package cz.cuni.mff.d3s.been.hostruntime;
import static cz.cuni.mff.d3s.been.cluster.Names.ACTION_QUEUE_NAME;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.Message;
import com.hazelcast.core.MessageListener;
import cz.cuni.mff.d3s.been.cluster.Names;
import cz.cuni.mff.d3s.been.cluster.Service;
import cz.cuni.mff.d3s.been.cluster.ServiceException;
import cz.cuni.mff.d3s.been.cluster.context.ClusterContext;
import cz.cuni.mff.d3s.been.core.protocol.messages.BaseMessage;
import cz.cuni.mff.d3s.been.mq.IMessageSender;
import cz.cuni.mff.d3s.been.mq.MessageQueues;
import cz.cuni.mff.d3s.been.mq.MessagingException;
/**
* Listens for Host Runtime messages.
*
* @author Martin Sixta
*/
final class HostRuntimeMessageListener implements MessageListener<BaseMessage>, Service {
/** Logging */
private static final Logger log = LoggerFactory.getLogger(HostRuntimeMessageListener.class);
/** Cluster Context */
private final ClusterContext ctx;
/** Sender for task action messages */
private IMessageSender<BaseMessage> sender;
/** ID of this Host Runtime */
private final String nodeId;
/** The Hazelcast topic to listen for messages on */
final ITopic<BaseMessage> globalTopic;
/**
* Creates HostRuntimeMessageListener.
*
* @param ctx
* connection to the cluster
* @param nodeId
* this nodes ID
*/
public HostRuntimeMessageListener(final ClusterContext ctx, final String nodeId) {
this.ctx = ctx;
this.nodeId = nodeId;
globalTopic = ctx.getTopic(Names.BEEN_GLOBAL_TOPIC);
}
@Override
public void start() throws ServiceException {
try {
this.sender = MessageQueues.getInstance().createSender(ACTION_QUEUE_NAME);
} catch (MessagingException e) {
String msg = String.format("Cannot connet to %s", ACTION_QUEUE_NAME);
throw new ServiceException(msg, e);
}
globalTopic.addMessageListener(this);
}
@Override
public synchronized void stop() {
globalTopic.removeMessageListener(this);
sender.close();
}
/**
* Picks a message from Hazelcast and sends it to its Host Runtime for
* processing.
*
* @param message
* received message
*/
@Override
public synchronized void onMessage(Message<BaseMessage> message) {
final BaseMessage messageObject = message.getMessageObject();
String receiverId = messageObject.recieverId;
boolean isForThisHostRuntime = (receiverId == null || nodeId.equals(receiverId));
if (isForThisHostRuntime) {
try {
sender.send(messageObject);
} catch (MessagingException e) {
log.error("Cannot request message to task action queue", e);
}
}
}
}