package ddth.dasp.hetty.qnt.hazelcast; import java.util.List; import java.util.concurrent.TimeUnit; import ddth.dasp.common.DaspGlobal; import ddth.dasp.common.hazelcastex.IHazelcastClient; import ddth.dasp.common.hazelcastex.IHazelcastClientFactory; import ddth.dasp.common.hazelcastex.IMessageListener; import ddth.dasp.common.hazelcastex.PoolConfig; import ddth.dasp.hetty.front.AbstractHettyResponseService; import ddth.dasp.hetty.message.IMessageFactory; import ddth.dasp.hetty.message.IResponse; /* * TODO: what would happen if a message comes when onMessage() is busy? */ public class HazelcastResponseService extends AbstractHettyResponseService implements IMessageListener<Object> { private IHazelcastClientFactory hazelcastClientFactory; private List<String> hazelcastServers; private String hazelcastUsername, hazelcastPassword; private PoolConfig poolConfig; private IMessageFactory messageFactory; private String topicName; private boolean _listening = false, _destroyed = false; protected String getTopicName() { return topicName; } public HazelcastResponseService setTopicName(String topicName) { this.topicName = topicName; return this; } protected IHazelcastClientFactory getHazelcastClientFactory() { return hazelcastClientFactory; } public HazelcastResponseService setHazelcastClientFactory( IHazelcastClientFactory hazelcastClientFactory) { this.hazelcastClientFactory = hazelcastClientFactory; return this; } protected List<String> getHazelcastServers() { return hazelcastServers; } public HazelcastResponseService setHazelcastServers(List<String> hazelcastServers) { this.hazelcastServers = hazelcastServers; return this; } protected String getHazelcastUsername() { return hazelcastUsername; } public HazelcastResponseService setHazelcastUsername(String hazelcastUsername) { this.hazelcastUsername = hazelcastUsername; return this; } protected String getHazelcastPassword() { return hazelcastPassword; } public HazelcastResponseService setHazelcastPassword(String hazelcastPassword) { this.hazelcastPassword = hazelcastPassword; return this; } protected PoolConfig getPoolConfig() { return poolConfig; } public HazelcastResponseService setPoolConfig(PoolConfig poolConfig) { this.poolConfig = poolConfig; return this; } protected IMessageFactory getMessageFactory() { return messageFactory; } public void setMessageFactory(IMessageFactory messageFactory) { this.messageFactory = messageFactory; } private class MessageListenerKeeper implements Runnable { private IMessageListener<Object> messageListener; public MessageListenerKeeper(IMessageListener<Object> messageListener) { this.messageListener = messageListener; } private void ping() { try { if (!_hazelcastClient.ping()) { unsubscribe(); } } catch (Exception e) { _listening = false; returnHazelcastClient(); } } @Override public void run() { if (!_destroyed) { try { if (_listening) { ping(); } else { IHazelcastClient hazelcastClient = getHazelcastClient(); if (hazelcastClient != null) { _listening = true; hazelcastClient.subscribe(topicName, messageListener); } } } finally { DaspGlobal.getScheduler().schedule(this, 5000, TimeUnit.MILLISECONDS); } } } } public void init() { Runnable command = new MessageListenerKeeper(this); DaspGlobal.getScheduler().schedule(command, 2000, TimeUnit.MILLISECONDS); } public void destroy() { _destroyed = true; try { unsubscribe(); } finally { returnHazelcastClient(); } } private IHazelcastClient _hazelcastClient; synchronized private IHazelcastClient getHazelcastClient() { if (_hazelcastClient == null) { _hazelcastClient = hazelcastClientFactory.getHazelcastClient(hazelcastServers, hazelcastUsername, hazelcastPassword, poolConfig); } return _hazelcastClient; } synchronized private void returnHazelcastClient() { try { hazelcastClientFactory.returnHazelcastClient(_hazelcastClient); } finally { _hazelcastClient = null; } } /** * {@inheritDoc} */ @Override public void unsubscribe() { try { if (_hazelcastClient != null) { _hazelcastClient.unsubscribe(topicName, this); } } finally { _listening = false; } } /** * {@inheritDoc} */ @Override public void onMessage(Object message) { IResponse response = null; if (message instanceof byte[]) { response = messageFactory.deserializeResponse((byte[]) message); } else if (message instanceof IResponse) { response = (IResponse) message; } writeResponse(response); } }