package com.netifera.platform.internal.dispatcher; import com.netifera.platform.api.channels.IChannelMessageSerializer; import com.netifera.platform.api.dispatcher.IMessageDispatcher; import com.netifera.platform.api.dispatcher.IMessenger; import com.netifera.platform.api.dispatcher.IProbeMessage; import com.netifera.platform.api.dispatcher.MessageErrorException; import com.netifera.platform.api.dispatcher.MessengerException; import com.netifera.platform.api.dispatcher.ProbeMessage; import com.netifera.platform.api.dispatcher.UnhandledMessageException; import com.netifera.platform.api.log.ILogger; import com.netifera.platform.api.probe.IProbe; import com.netifera.platform.dispatcher.StatusMessage; /* * <code>IMessenger</code> implementation. * */ public class Messenger implements IMessenger { private final IChannelMessageSerializer serializer; private final MessageReader reader; private final MessageSender sender; private volatile boolean closed; private ILogger logger; private IProbe probe; public Messenger(IChannelMessageSerializer serializer, IMessageDispatcher dispatcher, ILogger logger) { this.serializer = serializer; reader = new MessageReader(serializer, this, logger); if(dispatcher != null) { reader.setDispatcher(dispatcher); } sender = new MessageSender(serializer, this, logger); closed = false; this.logger = logger; } public synchronized void close() { if(closed) return; closed = true; reader.interrupt(); sender.interrupt(); serializer.close(); if(probe != null) { probe.setDisconnected(); } } public boolean isOpen() { return !closed; } public void start() { reader.start(); sender.start(); } public IProbe getProbe() { return probe; } public void setProbe(IProbe probe) { this.probe = probe; } public IProbeMessage exchangeMessage(IProbeMessage message) throws MessengerException { if(closed) { throw new MessengerClosedException(); } sender.queueMessage((ProbeMessage)message); return reader.readResponse(message.getSequenceNumber()); } public void sendMessage(IProbeMessage message) throws MessengerException { logger.debug("Sending probe message: " + message.getClass()); IProbeMessage response = exchangeMessage(message); if(response instanceof StatusMessage) { StatusMessage status = (StatusMessage) response; if(status.isError()) { if(status.isUnhandledMessageError()) { throw new UnhandledMessageException(); } else { throw new MessageErrorException(status.getErrorMessage()); } } } else { logger.debug("StatusMessage not received"); throw new MessengerException("Did not receive expected StatusMessage response"); } } public String toString() { return "Messenger for [" + probe + "]"; } public void emitMessage(IProbeMessage message) throws MessengerException { if(closed) { throw new MessengerClosedException(); } sender.queueMessage((ProbeMessage)message); } public void respondOk(IProbeMessage message) throws MessengerException { emitMessage(StatusMessage.createOk(message.getSequenceNumber())); } public void respondError(IProbeMessage message, String errorMessage) throws MessengerException { emitMessage(StatusMessage.createError(message.getSequenceNumber(), errorMessage)); } }