/** * GRANITE DATA SERVICES * Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S. * * This file is part of the Granite Data Services Platform. * * Granite Data Services is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Granite Data Services is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA, or see <http://www.gnu.org/licenses/>. */ package org.granite.tide.data; import java.io.Serializable; import java.util.Map; import java.util.Map.Entry; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.ObjectMessage; import javax.jms.Session; import javax.jms.Topic; import javax.jms.TopicConnectionFactory; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.http.HttpSession; import org.granite.context.GraniteContext; import org.granite.gravity.adapters.JMSClient; import org.granite.logging.Logger; import org.granite.messaging.webapp.ServletGraniteContext; /** * Implementation for data update dispatchers using JMS to dispatch updates. * * @see DataDispatcher * @see DataContext * * @author William Drai */ public class JMSDataDispatcher extends AbstractDataDispatcher { private static final Logger log = Logger.getLogger(JMSDataDispatcher.class); private boolean transacted = false; private TopicConnectionFactory connectionFactory = null; private Topic topic; private JMSClient jmsClient = null; public JMSDataDispatcher(String topicName, boolean transacted, Class<? extends DataTopicParams> dataTopicParamsClass) { super(topicName, dataTopicParamsClass); this.transacted = transacted; GraniteContext graniteContext = GraniteContext.getCurrentInstance(); if (graniteContext instanceof ServletGraniteContext) { HttpSession session = ((ServletGraniteContext)graniteContext).getSession(false); if (session == null) { log.debug("Gravity not found or HTTP session not found, data dispatch disabled"); return; } sessionId = session.getId(); jmsClient = (JMSClient)((ServletGraniteContext)graniteContext).getSessionMap().get(JMSClient.JMSCLIENT_KEY_PREFIX + topicName); } else { // Server initiated dispatcher this.sessionId = SERVER_DISPATCHER_GDS_SESSION_ID; try { InitialContext ic = new InitialContext(); this.connectionFactory = (TopicConnectionFactory)ic.lookup("java:comp/env/tide/ConnectionFactory"); this.topic = (Topic)ic.lookup("java:comp/env/tide/topic/" + topicName); } catch (NamingException e) { log.warn(e, "Could not retrieve ConnectionFactory and Topic in JNDI for topic %s", topicName); return; } } enabled = true; } @Override protected void changeDataSelector(String dataSelector) { if (jmsClient != null) { try { jmsClient.subscribe(dataSelector, topicName, TIDE_DATA_SUBTOPIC); log.debug("JMS Topic %s data selector changed: %s", topicName, dataSelector); } catch (Exception e) { log.error(e, "Could not change JMS Topic %s data selector: %s", topicName); } } } @Override public void publishUpdate(Map<String, Object> params, Object body) { if (jmsClient != null) { try { jmsClient.send(params, body, 0L); } catch (Exception e) { log.error("Could not dispatch data update on topic %s using internal JMS client, message %s", topicName, body.toString()); } } else if (enabled) { try { Connection jmsConnection = connectionFactory.createConnection(); Session jmsSession = jmsConnection.createSession(transacted, Session.AUTO_ACKNOWLEDGE); MessageProducer jmsProducer = jmsSession.createProducer(topic); ObjectMessage jmsMessage = jmsSession.createObjectMessage((Serializable)body); for (Entry<String, Object> hh : params.entrySet()) jmsMessage.setObjectProperty(hh.getKey(), hh.getValue()); jmsProducer.send(jmsMessage); log.debug("Data message dispatched on JMS topic %s", topicName); } catch (JMSException e) { log.error("Could not dispatch data update on topic %s, message %s", topicName, body.toString()); } } } }