001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.jbi.nmr.flow.jms;
018
019 import javax.jbi.JBIException;
020 import javax.jms.ConnectionFactory;
021 import javax.jms.JMSException;
022 import javax.jms.Message;
023 import javax.jms.MessageListener;
024 import javax.jms.Session;
025 import javax.jms.Topic;
026
027 import org.apache.activemq.advisory.AdvisorySupport;
028 import org.apache.activemq.command.ActiveMQDestination;
029 import org.apache.activemq.command.ActiveMQMessage;
030 import org.apache.activemq.command.ConsumerId;
031 import org.apache.activemq.command.ConsumerInfo;
032 import org.apache.activemq.command.RemoveInfo;
033 import org.apache.activemq.pool.PooledConnectionFactory;
034
035 /**
036 * Use for message routing among a network of containers. All
037 * routing/registration happens automatically.
038 *
039 * @version $Revision: 596245 $
040 * @org.apache.xbean.XBean element="jmsFlow"
041 */
042 public class JMSFlow extends AbstractJMSFlow {
043
044 private PooledConnectionFactory factory;
045
046 protected ConnectionFactory createConnectionFactoryFromUrl(String jmsURL) {
047 factory = (jmsURL != null) ? new PooledConnectionFactory(jmsURL) : new PooledConnectionFactory();
048 return factory;
049 }
050
051 /**
052 * Listener on the ActiveMQ advisory topic so we get messages when a cluster
053 * node is added or removed
054 */
055 protected void onConsumerMonitorMessage(Message advisoryMessage) {
056 if (!started.get()) {
057 return;
058 }
059 Object obj = ((ActiveMQMessage) advisoryMessage).getDataStructure();
060 if (obj instanceof ConsumerInfo) {
061 ConsumerInfo info = (ConsumerInfo) obj;
062 addClusterNode(info.getConsumerId().getConnectionId());
063 } else if (obj instanceof RemoveInfo) {
064 ConsumerId consumerId = (ConsumerId) ((RemoveInfo) obj).getObjectId();
065 removeClusterNode(consumerId.getConnectionId());
066 }
067 }
068
069 public void startConsumerMonitor() throws JMSException {
070 Session broadcastSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
071 Topic broadcastTopic = broadcastSession.createTopic(getBroadcastDestinationName());
072 Topic advisoryTopic = AdvisorySupport.getConsumerAdvisoryTopic((ActiveMQDestination) broadcastTopic);
073 monitorMessageConsumer = broadcastSession.createConsumer(advisoryTopic);
074 monitorMessageConsumer.setMessageListener(new MessageListener() {
075 public void onMessage(Message message) {
076 onConsumerMonitorMessage(message);
077 }
078 });
079 }
080
081 @Override
082 public void shutDown() throws JBIException {
083 super.shutDown();
084 if (factory != null) {
085 try {
086 factory.stop();
087 } catch (Exception e) {
088 log.warn("Unable to stop JMS connection pool: " + e.getMessage(), e);
089 }
090 }
091 }
092 }