All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rabbitmq.jms.admin.RMQObjectFactory Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/* Copyright (c) 2013 Pivotal Software, Inc. All rights reserved. */
package com.rabbitmq.jms.admin;

import java.util.Hashtable;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.Topic;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * JNDI Factory to create resources in containers such as Tomcat.
 * 

* An example Tomcat configuration for a {@link ConnectionFactory} would look like: *

*
 * <Resource name="jms/ConnectionFactory" type="javax.jms.ConnectionFactory"
 *           factory="com.rabbitmq.jms.admin.RMQObjectFactory"
 *           username="guest"
 *           password="guest"
 *           virtualHost="/"
 *           host="localhost"/>
 * 
*

Alternatively, a AMQP uri can be used: *

*
 * <Resource name="jms/ConnectionFactory" type="javax.jms.ConnectionFactory"
 *           factory="com.rabbitmq.jms.admin.RMQObjectFactory"
 *           uri="amqp://guest:[email protected]"
 * 
*

* the type attribute can be {@link javax.jms.ConnectionFactory}, {@link javax.jms.QueueConnectionFactory}, * {@link javax.jms.TopicConnectionFactory} or the actual classname of the implementation, * {@link com.rabbitmq.jms.admin.RMQConnectionFactory}. *

*

* A destination, {@link Queue} or {@link Topic}, can be created using the following configuration ({@link Queue} first): *

*
 * <Resource name="jms/Queue" type="javax.jms.Queue"
 *           factory="com.rabbitmq.jms.admin.RMQObjectFactory"
 *           destinationName="queueName"/>
 * 
*

* and a {@link Topic} would be created thus: *

*
 * <Resource name="jms/Topic" type="javax.jms.Topic"
 *           factory="com.rabbitmq.jms.admin.RMQObjectFactory"
 *           destinationName="topicName"/>
 * 
*

* An example Wildfly configuration for a {@link ConnectionFactory} would look like: *

*
 * <object-factory name="java:global/jms/ConnectionFactory" module="org.jboss.genericjms.provider" class="com.rabbitmq.jms.admin.RMQObjectFactory">
 *     <environment>
 *         <property name="className" value="javax.jms.ConnectionFactory"/>
 *         <property name="username" value="guest"/>
 *         <property name="password" value="guest"/>
 *         <property name="virtualHost" value="/"/>
 *         <property name="host" value="localhost"/>
 *     </environment>
 * </object-factory>
 * 
*

* Valid types are: *

*
 * javax.jms.ConnectionFactory
 * javax.jms.QueueConnectionFactory
 * javax.jms.TopicConnectionFactory
 * javax.jms.Topic
 * javax.jms.Queue
 * 
*

* Valid properties for a {@link ConnectionFactory} are: *

*
    *
  • uri
  • *
  • host
  • *
  • password
  • *
  • port
  • *
  • queueBrowserReadMax
  • *
  • onMessageTimeoutMs
  • *
  • ssl
  • *
  • terminationTimeout
  • *
  • username
  • *
  • virtualHost
  • *
  • className - only applies when properties are provided via environment HashTable
  • *
* and are applied in this order, if they are present. If a property is not present, or is not set by means of the * uri attribute, the default value is the same as that obtained by instantiating a * {@link RMQConnectionFactory} object with the default constructor. *

* Properties for a {@link Topic} or a {@link Queue} are: *

*
    *
  • destinationName
  • *
* TODO Implement socket options. */ public class RMQObjectFactory implements ObjectFactory { private static final String ENV_CLASS_NAME = "className"; private final Logger logger = LoggerFactory.getLogger(RMQObjectFactory.class); /** * {@inheritDoc} */ @Override public Object getObjectInstance(Object obj, Name name, Context ctx, Hashtable environment) throws Exception { if ((obj == null) ) { return null; } Reference ref = obj instanceof Reference ? (Reference) obj : null; if (ref == null && (environment == null || environment.isEmpty())) { throw new NamingException("Unable to instantiate object: obj is not a Reference instance and environment table is empty"); } String className = ref!= null ? ref.getClassName(): (String) environment.get(ENV_CLASS_NAME); if (className == null || className.trim().length() == 0) { throw new NamingException("Unable to instantiate object: type has not been specified"); } /* * Valid class names are: * javax.jms.ConnectionFactory * javax.jms.QueueConnectionFactory * javax.jms.TopicConnectionFactory * javax.jms.Topic * javax.jms.Queue * */ boolean topic = false; boolean connectionFactory = false; if ( javax.jms.QueueConnectionFactory.class.getName().equals(className) || javax.jms.TopicConnectionFactory.class.getName().equals(className) || javax.jms.ConnectionFactory.class.getName().equals(className) ) { connectionFactory = true; } else if (javax.jms.Topic.class.getName().equals(className)) { topic = true; } else if (javax.jms.Queue.class.getName().equals(className)) { } else { throw new NamingException(String.format("Unknown class [%s]", className)); } if (connectionFactory) { return createConnectionFactory(ref, environment, name); } else { return createDestination(ref, environment, name, topic); } } /** * Creates a RMQConnectionFactory from a Reference or environment Hashtable * @param ref the reference containing properties * @param environment the environment containing properties * @param name the name of the object * @return a {@link RMQConnectionFactory} object configured * @throws NamingException if a required property is missing or invalid */ public Object createConnectionFactory(Reference ref, Hashtable environment, Name name) throws NamingException { this.logger.trace("Creating connection factory ref '{}', name '{}'.", ref, name); RMQConnectionFactory f = new RMQConnectionFactory(); try { // set uri first, which may fail if it doesn't parse f.setUri(getStringProperty(ref, environment, "uri", true, f.getUri())); } catch (JMSException e) { this.logger.warn("Failed to set RMQConnectionFactory properties by URI--defaults taken initially.", e); } // explicit properties (these override the uri, if set) f.setHost (getStringProperty (ref, environment, "host", true, f.getHost() )); f.setPassword (getStringProperty (ref, environment, "password", true, f.getPassword() )); f.setPort (getIntProperty (ref, environment, "port", true, f.getPort() )); f.setQueueBrowserReadMax(getIntProperty (ref, environment, "queueBrowserReadMax", true, f.getQueueBrowserReadMax())); f.setOnMessageTimeoutMs (getIntProperty (ref, environment, "onMessageTimeoutMs", true, f.getOnMessageTimeoutMs() )); f.setSsl (getBooleanProperty(ref, environment, "ssl", true, f.isSsl() )); f.setTerminationTimeout (getLongProperty (ref, environment, "terminationTimeout", true, f.getTerminationTimeout() )); f.setUsername (getStringProperty (ref, environment, "username", true, f.getUsername() )); f.setVirtualHost (getStringProperty (ref, environment, "virtualHost", true, f.getVirtualHost() )); f.setCleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose(getBooleanProperty(ref, environment, "cleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose", true, f.isCleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose() )); return f; } /** * Create a {@link RMQDestination} from a Reference of environment Hashtable * @param ref the reference containing the properties * @param environment the environment containing the properties * @param name the name * @param topic true if this is a topic, false if it is a queue (ignored if this is amqp-mapped) * @return a {@link RMQDestination} object with the destinationName configured * @throws NamingException if the destinationName property is missing */ public Object createDestination(Reference ref, Hashtable environment, Name name, boolean topic) throws NamingException { this.logger.trace("Creating destination ref '{}', name '{}' (topic={}).", ref, name, topic); String dname = getStringProperty(ref, environment, "destinationName", false, null); boolean amqp = getBooleanProperty(ref, environment, "amqp", true, false); if (amqp) { String amqpExchangeName = getStringProperty(ref, environment, "amqpExchangeName", false, null); String amqpRoutingKey = getStringProperty(ref, environment,"amqpRoutingKey", false, null); String amqpQueueName = getStringProperty(ref, environment, "amqpQueueName", false, null); return new RMQDestination(dname, amqpExchangeName, amqpRoutingKey, amqpQueueName); } else { return new RMQDestination(dname, !topic, false); } } /** * Returns the value of a set property in a reference * @param ref the Reference containing the value * @param environment the environment Hashtable containing the value * @param propertyName the name of the property * @param mayBeNull true if the property may be missing or contain a null value, in this case defaultValue will be returned * @param defaultValue the defaultValue to return if the property is null and mayBeNull==true * @return the String value for the property * @throws NamingException if the property is missing and mayBeNull==false */ private String getStringProperty(Reference ref, Hashtable environment, String propertyName, boolean mayBeNull, String defaultValue) throws NamingException { String content = propertyContent(ref, environment, propertyName, mayBeNull); if (content == null) return defaultValue; return content; } /** * Reads a property from the reference and returns the boolean value it represents * @param ref the Reference containing the value * @param environment the environment Hashtable containing the value * @param propertyName the name of the property * @param mayBeNull true if the property may be missing or contain a null value, in this case defaultValue will be returned * @param defaultValue the defaultValue to return if the property is null and mayBeNull==true * @return the boolean value of the property * @throws NamingException if the property is missing and mayBeNull==false */ private boolean getBooleanProperty(Reference ref, Hashtable environment, String propertyName, boolean mayBeNull, boolean defaultValue) throws NamingException { String content = propertyContent(ref, environment, propertyName, mayBeNull); if (content == null) return defaultValue; return Boolean.valueOf(content); } /** * Reads a property from the reference and returns the int value it represents * @param ref the Reference containing the value * @param environment the environment Hashtable containing the value * @param propertyName the name of the property * @param mayBeNull true if the property may be missing, in which case defaultValue will be returned * @param defaultValue the default value to return if mayBeNull is set to true * @return the integer value representing the property value * @throws NamingException if the property is missing while mayBeNull is set to false, or a number format exception happened */ private int getIntProperty(Reference ref, Hashtable environment, String propertyName, boolean mayBeNull, int defaultValue) throws NamingException { String content = propertyContent(ref, environment, propertyName, mayBeNull); if (content == null) return defaultValue; try { return Integer.parseInt(content); } catch (Exception x) { NamingException nx = new NamingException(String.format("Property [%s] is present but is not an integer value [%s]", propertyName, content)); nx.setRootCause(x); throw nx; } } /** * Reads a property from the reference and returns the long integer value it represents * @param ref the Reference containing the value * @param environment the environment Hashtable containing the value * @param propertyName the name of the property * @param mayBeNull true if the property may be missing, in which case defaultValue will be returned * @param defaultValue the default value to return if mayBeNull is set to true * @return the long integer value representing the property value * @throws NamingException if the property is missing while mayBeNull is set to false, or a number format exception happened */ private long getLongProperty(Reference ref, Hashtable environment, String propertyName, boolean mayBeNull, long defaultValue) throws NamingException { String content = propertyContent(ref, environment, propertyName, mayBeNull); if (content == null) return defaultValue; try { return Long.parseLong(content); } catch (Exception x) { NamingException nx = new NamingException(String.format("Property [%s] is present but is not a long integer value [%s]", propertyName, content)); nx.setRootCause(x); throw nx; } } private static String propertyStringContent(RefAddr ra) { return (ra == null ? null : ra.getContent() == null ? null : ra.getContent().toString()); } private static String environmentPropertyStringContent(Object propValue) { return (propValue == null ? null : propValue.toString()); } private static String propertyContent(Reference ref, Hashtable environment, String propertyName, boolean mayBeNull) throws NamingException { if (!mayBeNull && (ref == null || ref.get(propertyName) == null) && (environment == null || environment.get(propertyName) == null)) { throw new NamingException(String.format("Property [%s] may not be null.", propertyName)); } String content = ref != null ? propertyStringContent(ref.get(propertyName)) : environmentPropertyStringContent(environment.get(propertyName)); if (content == null && !mayBeNull) { throw new NamingException(String.format("Property [%s] is present but is lacking a value.", propertyName)); } return content; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy