Package org.codehaus.activemq.ra

Source Code of org.codehaus.activemq.ra.ActiveMQAsfEndpointWorker$ServerSessionPoolImpl

/**
*
* Copyright 2004 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.codehaus.activemq.ra;

import java.util.ArrayList;
import java.util.LinkedList;

import javax.jms.ConnectionConsumer;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.ServerSession;
import javax.jms.ServerSessionPool;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.XASession;
import javax.resource.ResourceException;
import javax.resource.spi.UnavailableException;
import javax.resource.spi.endpoint.MessageEndpoint;
import javax.resource.spi.work.WorkException;
import javax.transaction.xa.XAResource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.activemq.message.ActiveMQQueue;
import org.codehaus.activemq.message.ActiveMQTopic;

/**
* @version $Revision: 1.8 $ $Date: 2004/11/20 05:49:51 $
*/
public class ActiveMQAsfEndpointWorker extends ActiveMQBaseEndpointWorker {

    private static final Log log = LogFactory.getLog(ActiveMQAsfEndpointWorker.class);
    private static final int MAX_MSGS_PER_SESSION = 1;
    private static final int MAX_SESSION = 10;

    private static final ThreadLocal threadLocal = new ThreadLocal();

    private ConnectionConsumer consumer;
    private ServerSessionPoolImpl serverSessionPool;


    /**
     * @param adapter
     * @param key
     * @throws ResourceException
     */
    public ActiveMQAsfEndpointWorker(ActiveMQResourceAdapter adapter, ActiveMQEndpointActivationKey key) throws ResourceException {
        super(adapter, key);
    }


    public void start() throws WorkException, ResourceException {
        log.debug("Starting");
        boolean ok = false;
        try {
            serverSessionPool = new ServerSessionPoolImpl();
            ActiveMQActivationSpec activationSpec = endpointActivationKey.getActivationSpec();

            Destination dest = null;

            if ("javax.jms.Queue".equals(activationSpec.getDestinationType())) {
                dest = new ActiveMQQueue(activationSpec.getDestination());
            }
            else if ("javax.jms.Topic".equals(activationSpec.getDestinationType())) {
                dest = new ActiveMQTopic(activationSpec.getDestination());
            }
            else {
                throw new ResourceException("Unknown destination type: " + activationSpec.getDestinationType());
            }

            if (activationSpec.isDurableSubscription()) {
                consumer = getPhysicalConnection().createDurableConnectionConsumer((Topic) dest, activationSpec.getSubscriptionId(), emptyToNull(activationSpec.getMessageSelector()), serverSessionPool, MAX_MSGS_PER_SESSION);
            }
            else {
                consumer = getPhysicalConnection().createConnectionConsumer(dest, emptyToNull(activationSpec.getMessageSelector()), serverSessionPool, MAX_MSGS_PER_SESSION);
            }

            ok = true;
            log.debug("Started");

        }
        catch (JMSException e) {
            throw new ResourceException("Could not start the endpoint.", e);
        }
        finally {
            // We don't want to leak sessions on errors.  Keep them around only if
            // there were no errors.
            if (!ok) {
                safeClose(consumer);
            }
        }
    }

    /**
     *
     */
    public void stop() throws InterruptedException {
        safeClose(consumer);
        serverSessionPool.close();
    }

    protected void registerThreadSession(Session session) {
        threadLocal.set(session);
    }

    protected void unregisterThreadSession(Session session) {
        threadLocal.set(null);
    }


    class ServerSessionPoolImpl implements ServerSessionPool {

        ServerSessionImpl ss;
        ArrayList idleSessions = new ArrayList();
        LinkedList activeSessions = new LinkedList();
        int sessionIds = 0;
        int nextUsedSession;
        boolean closing = false;

        public ServerSessionPoolImpl() {
        }

        public ServerSessionImpl createServerSessionImpl() throws JMSException {         
            Session session = createSession();
            XAResource xaResource=null;
            if (session instanceof XASession) {
        xaResource = ((XASession) session).getXAResource();
            }
            MessageEndpoint endpoint;
      try {
        endpoint = endpointFactory.createEndpoint( xaResource );
      } catch (UnavailableException e) {
        // The container could be limiting us on the number of endpoints that are being created.
        session.close();
        return null;
      }     
      return new ServerSessionImpl(this, session, workManager, endpoint);
        }

        /**
         */
        synchronized public ServerSession getServerSession() throws JMSException {
            log.debug("ServerSession requested.");
            if (closing) {
                throw new JMSException("Session Pool Shutting Down.");
            }

            if (idleSessions.size() > 0) {
                ServerSessionImpl ss = (ServerSessionImpl) idleSessions.remove(idleSessions.size() - 1);
                activeSessions.addLast(ss);
                log.debug("Using idle session: " + ss);
                return ss;
            }
            else {
                // Are we at the upper limit?
                if (activeSessions.size() >= MAX_SESSION ) {
                    // then reuse the allready created sessions..
                    // This is going to queue up messages into a session for processing.
                    return getExistingServerSession();
                }
                ServerSessionImpl ss = createServerSessionImpl();
                // We may not be able to create a session due to the conatiner restricting us.
                if( ss==null ) {
                    return getExistingServerSession();
                }
                activeSessions.addLast(ss);
                log.debug("Created a new session: " + ss);
                return ss;
            }
        }

        /**
     * @return
     */
    private ServerSession getExistingServerSession() {
      ServerSessionImpl ss = (ServerSessionImpl) activeSessions.removeFirst();
      activeSessions.addLast(ss);
      log.debug("Reusing an active session: " + ss);
      return ss;
    }

    synchronized public void returnToPool(ServerSessionImpl ss) {
            log.debug("Session returned to pool: " + ss);
            idleSessions.add(ss);
        }

        public void close() {
            synchronized (this) {
                closing = true;
            }
        }
    }

    private String emptyToNull(String value) {
        if ("".equals(value)) {
            return null;
        }
        return value;
    }

}
TOP

Related Classes of org.codehaus.activemq.ra.ActiveMQAsfEndpointWorker$ServerSessionPoolImpl

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.