jmsconnectionfactory.java

来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 546 行 · 第 1/2 页

JAVA
546
字号
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.axis2.transport.jms;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axis2.addressing.EndpointReference;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

/**
 * Encapsulate a JMS Connection factory definition within an Axis2.xml
 * <p/>
 * More than one JMS connection factory could be defined within an Axis2 XML
 * specifying the JMSListener as the transportReceiver.
 * <p/>
 * These connection factories are created at the initialization of the
 * transportReceiver, and any service interested in using any of these could
 * specify the name of the factory and the destination through Parameters named
 * JMSConstants.CONFAC_PARAM and JMSConstants.DEST_PARAM as shown below.
 * <p/>
 * <parameter name="transport.jms.ConnectionFactory" locked="true">myQueueConnectionFactory</parameter>
 * <parameter name="transport.jms.Destination" locked="true">TestQueue</parameter>
 * <p/>
 * If a connection factory is defined by a parameter named
 * JMSConstants.DEFAULT_CONFAC_NAME in the Axis2 XML, services which does not
 * explicitly specify a connection factory will be defaulted to it - if it is
 * defined in the Axis2 configuration.
 * <p/>
 * e.g.
 * <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
 * <parameter name="myTopicConnectionFactory" locked="false">
 * <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
 * <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
 * <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
 * <parameter name="transport.jms.Destination" locked="false">myTopicOne, myTopicTwo</parameter>
 * </parameter>
 * <parameter name="myQueueConnectionFactory" locked="false">
 * <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
 * <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
 * <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
 * <parameter name="transport.jms.Destination" locked="false">myQueueOne, myQueueTwo</parameter>
 * </parameter>
 * <parameter name="default" locked="false">
 * <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
 * <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
 * <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">ConnectionFactory</parameter>
 * <parameter name="transport.jms.Destination" locked="false">myDestinationOne, myDestinationTwo</parameter>
 * </parameter>
 * </transportReceiver>
 */
public class JMSConnectionFactory {

    private static final Log log = LogFactory.getLog(JMSConnectionFactory.class);

    /**
     * The name used for the connection factory definition within Axis2
     */
    private String name = null;
    /**
     * The JNDI name of the actual connection factory
     */
    private String jndiName = null;
    /**
     * The JNDI name of the actual connection factory username
     */
    private String jndiUser = null;
    /**
     * The JNDI name of the actual connection factory password
     */
    private String jndiPass = null;
    /**
     * Map of destination JNDI names to service names
     */
    private Map serviceJNDINameMapping = null;
    /**
     * Map of destinations to service names
     */
    private Map serviceDestinationMapping = null;
    /**
     * The JMS Sessions listening for messages
     */
    private Map jmsSessions = null;
    /**
     * Properties of the connection factory
     */
    private Hashtable properties = null;
    /**
     * The JNDI Context used
     */
    private Context context = null;
    /**
     * The actual ConnectionFactory instance held within
     */
    private ConnectionFactory conFactory = null;
    /**
     * The JMS Connection is opened.
     */
    private Connection connection = null;
    /**
     * The JMS Message receiver for this connection factory
     */
    private JMSMessageReceiver msgRcvr = null;
    /**
     * The actual password for the connection factory after retrieval from JNDI.
     * If this is not supplied, the OS username will be used by default
     */
    private String user = null;
    /**
     * The actual password for the connection factory after retrieval from JNDI.
     * If this is not supplied, the OS credentials will be used by default
     */
    private String pass = null;
    
    /**
     * Create a JMSConnectionFactory for the given Axis2 name and JNDI name
     *
     * @param name     the local Axis2 name of the connection factory
     * @param jndiName the JNDI name of the actual connection factory used
     */
    JMSConnectionFactory(String name, String jndiName) {
        this.name = name;
        this.jndiName = jndiName;
        serviceJNDINameMapping = new HashMap();
        serviceDestinationMapping = new HashMap();
        properties = new Hashtable();
        jmsSessions = new HashMap();
    }

    /**
     * Create a JMSConnectionFactory for the given Axis2 name
     *
     * @param name the local Axis2 name of the connection factory
     */
    JMSConnectionFactory(String name) {
        this(name, null);
    }

    /**
     * Connect to the actual JMS connection factory specified by the JNDI name
     *
     * @throws NamingException if the connection factory cannot be found
     */
    public void connect() throws NamingException {
        if (context == null) {
            createInitialContext();
        }
        conFactory = (ConnectionFactory) context.lookup(jndiName);

        if (jndiUser != null)
        	user = (String ) context.lookup(jndiUser);
        
        if (jndiPass != null)
        	pass = (String ) context.lookup(jndiPass);
        
        log.debug("Connected to the actual connection factory : " + jndiName);
    }

    /**
     * Creates the initial context using the set properties
     *
     * @throws NamingException
     */
    private void createInitialContext() throws NamingException {
        context = new InitialContext(properties);
    }

    /**
     * Set the JNDI connection factory name
     *
     * @param jndiName
     */
    public void setJndiName(String jndiName) {
        this.jndiName = jndiName;
    }

    /**
     * Get the JNDI name of the actual factory username
     *
     * @return the jndi name of the actual connection factory username
     */
	public void setJndiUser(String jndiUser) {
		this.jndiUser = jndiUser;
	}   
    
    /**
     * Get the JNDI name of the actual factory password
     *
     * @return the jndi name of the actual connection factory password
     */
	public void setJndiPass(String jndiPass) {
		this.jndiPass = jndiPass;
	}

    /**
     * Add a listen destination on this connection factory on behalf of the given service
     *
     * @param destinationJndi destination JNDI name
     * @param serviceName     the service to which it belongs
     */
    public void addDestination(String destinationJndi, String serviceName) {

        serviceJNDINameMapping.put(destinationJndi, serviceName);
        String destinationName = getDestinationName(destinationJndi);

        if (destinationName == null) {
            log.warn("JMS Destination with JNDI name : " + destinationJndi + " does not exist");

            Connection con = null;
            try {
            	if ((jndiUser == null) || (jndiPass == null)){
            		// Use the OS username and credentials
                    con = conFactory.createConnection();            		
            	} else{
            		// use an explicit username and password
                    con = conFactory.createConnection(user, pass);            		            		
            	}
                Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
                Queue queue = session.createQueue(destinationJndi);
                destinationName = queue.getQueueName();
                log.warn("JMS Destination with JNDI name : " + destinationJndi + " created");

            } catch (JMSException e) {
                log.error("Unable to create a Destination with JNDI name : " + destinationJndi, e);
                // mark service as faulty
                JMSUtils.markServiceAsFaulty(
                    (String) serviceJNDINameMapping.get(destinationJndi),
                    "Error looking up JMS destination : " + destinationJndi,
                    msgRcvr.getAxisConf().getAxisConfiguration());

            } finally {
                if (con != null) {
                    try {
                        con.close();
                    } catch (JMSException ignore) {}
                }
            }
        }
        
        serviceDestinationMapping.put(destinationName, serviceName);
        log.info("Mapping JNDI name : " + destinationJndi + " and JMS Destination name : " +
            destinationName + " against service : " + serviceName);
    }

    /**
     * Remove listen destination on this connection factory
     *
     * @param destinationJndi the JMS destination to be removed
     * @throws if an error occurs trying to stop listening for messages before removal

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?