Package org.activemq.advisories

Source Code of org.activemq.advisories.ProducerDemandAdvisor

/**
*
* Copyright 2005 Hiram Chirino
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
package org.activemq.advisories;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.activemq.message.ActiveMQDestination;
import org.activemq.message.ConsumerInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;

/**
* A ProducerDemandAdvisor is used to know when a destination is in demand.
*
* Sometimes generating messages to send to a destination is very expensive
* and the application would like to avoid producing messages if there are no
* active consumers for the destination.  There is a "demand" for messages
* when a consumer does come active.
*
* This object uses Advisory messages to know when consumer go active and
* inactive.
*/
public class ProducerDemandAdvisor {
   
    private static final Log log = LogFactory.getLog(ProducerDemandAdvisor.class);

    private final ActiveMQDestination destination;
    private Connection connection;
    private Session session;
    private SynchronizedBoolean started = new SynchronizedBoolean(false);
    private int consumerCount;
    private ProducerDemandListener demandListener;
   
    public ProducerDemandAdvisor( Connection connection, final Destination destination ) throws JMSException {
        this.connection = connection;
        this.destination = ActiveMQDestination.transformDestination(destination);
    }
    
    /**
     * @param destination
     */
    private void fireDemandEvent() {
        demandListener.onEvent( new ProducerDemandEvent(destination, isInDemand()));
    }

    public boolean isInDemand() {
        return consumerCount>0;
    }
   
    public ProducerDemandListener getDemandListener() {
        return demandListener;
    }

    synchronized public void setDemandListener(ProducerDemandListener demandListener) {
        this.demandListener = demandListener;
        fireDemandEvent();
    }

    public void start() throws JMSException {
        if (started.commit(false, true)) {
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageConsumer consumer = session.createConsumer(destination.getTopicForConsumerAdvisory());
            consumer.setMessageListener(new MessageListener(){
                public void onMessage(Message msg) {
                    process(msg);
                }
            });
        }
    }

    public void stop() throws JMSException {
        if (started.commit(true, false)) {
            if (session != null) {
                session.close();
            }
        }
    }
   
    protected void process(Message msg) {
        if (msg instanceof ObjectMessage) {
            try {
                ConsumerInfo info = (ConsumerInfo) ((ObjectMessage) msg).getObject();
                ConsumerAdvisoryEvent event = new ConsumerAdvisoryEvent(info);
               
               
                boolean inDemand = isInDemand();

                if ( info.isStarted() ) {
                    consumerCount++;
                } else {
                    consumerCount--;
                }
               
                // Notify listener if there was a change in demand.
                if (inDemand ^ isInDemand() && demandListener != null) {
                    fireDemandEvent();
                }
            } catch (JMSException e) {
                log.error("Failed to process message: " + msg);
            }
        }
    }

}
TOP

Related Classes of org.activemq.advisories.ProducerDemandAdvisor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.