package cgl.iotcloud.core.transport.jms; import cgl.iotcloud.core.msg.MessageContext; import cgl.iotcloud.core.transport.Manageable; import cgl.iotcloud.core.transport.TransportConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jms.*; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.concurrent.BlockingQueue; public class JMSListener implements Manageable { private static Logger LOG = LoggerFactory.getLogger(JMSListener.class); private Connection connection; private Session session; private Destination dest; private BlockingQueue<MessageContext> inQueue; private MessageConsumer consumer; private ConnectionFactory conFactory; private boolean topic; private String destination; public JMSListener(ConnectionFactory conFactory, String destination, boolean topic, BlockingQueue<MessageContext> inQueue) { if (conFactory == null || destination == null || inQueue == null) { throw new IllegalArgumentException("All the parameters are mandatory"); } this.conFactory = conFactory; this.topic = topic; this.inQueue = inQueue; this.destination = destination; } public void start(){ try { this.connection = conFactory.createConnection(); this.connection.start(); this.session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); if (topic) { dest = session.createTopic(destination); } else { dest = session.createQueue(destination); } consumer = session.createConsumer(dest); consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { try { if (message instanceof BytesMessage) { BytesMessage bytesMessage = (BytesMessage) message; String sensorId = message.getStringProperty(TransportConstants.SENSOR_ID); byte[] bytes = new byte[(int) bytesMessage.getBodyLength()]; bytesMessage.readBytes(bytes); Map<String, Object> properties = getMessageProperties(message); MessageContext messageContext = new MessageContext(sensorId, bytes, properties); inQueue.put(messageContext); } } catch (InterruptedException e) { LOG.error("Failed to put the message to queue", e); } catch (JMSException e) { LOG.warn("Message received without a sensor ID, discarding"); } } }); } catch (JMSException e) { String msg = "Failed to create a message consumer for destination: " + destination; LOG.error(msg); throw new RuntimeException(msg, e); } } @SuppressWarnings("unchecked") private static HashMap<String, Object> getMessageProperties(Message msg) throws JMSException { HashMap<String, Object> properties = new HashMap<String, Object>(); Enumeration srcProperties = msg.getPropertyNames(); while (srcProperties.hasMoreElements()) { String propertyName = (String) srcProperties.nextElement(); properties.put(propertyName, msg.getObjectProperty(propertyName)); } return properties; } public void stop() { try { consumer.close(); session.close(); connection.close(); } catch (JMSException e) { LOG.error("Error occurred while closing JMS connections"); } } }