- Made ActiveMQConnectionFactory and ActiveMQDestination referenceable.

- Ported to 4.x the jndi implementation from 3.x (JNDIStorableInterface, JNDIBaseStorable, JNDIReferenceFactory)
- Added a simple test case to test the object factory.


git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@369411 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrian T. Co 2006-01-16 09:58:02 +00:00
parent b329273cf4
commit b9a4deed5d
7 changed files with 367 additions and 78 deletions

View File

@ -43,6 +43,7 @@ import org.apache.activemq.util.IntrospectionSupport;
import org.apache.activemq.util.JMSExceptionSupport; import org.apache.activemq.util.JMSExceptionSupport;
import org.apache.activemq.util.URISupport; import org.apache.activemq.util.URISupport;
import org.apache.activemq.util.URISupport.CompositeData; import org.apache.activemq.util.URISupport.CompositeData;
import org.apache.activemq.jndi.JNDIBaseStorable;
import edu.emory.mathcs.backport.java.util.concurrent.Executor; import edu.emory.mathcs.backport.java.util.concurrent.Executor;
import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor; import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor;
@ -57,7 +58,7 @@ import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
* @version $Revision: 1.9 $ * @version $Revision: 1.9 $
* @see javax.jms.ConnectionFactory * @see javax.jms.ConnectionFactory
*/ */
public class ActiveMQConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable, Referenceable { public class ActiveMQConnectionFactory extends JNDIBaseStorable implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable {
public static final String DEFAULT_BROKER_URL = "tcp://localhost:61616"; public static final String DEFAULT_BROKER_URL = "tcp://localhost:61616";
public static final String DEFAULT_USER = null; public static final String DEFAULT_USER = null;
@ -359,12 +360,7 @@ public class ActiveMQConnectionFactory implements ConnectionFactory, QueueConnec
this.redeliveryPolicy = redeliveryPolicy; this.redeliveryPolicy = redeliveryPolicy;
} }
/** public void buildFromProperties(Properties properties) {
* set the properties for this instance as retrieved from JNDI
*
* @param properties
*/
public void setProperties(Properties properties) throws URISyntaxException {
if (properties == null) { if (properties == null) {
properties = new Properties(); properties = new Properties();
@ -381,10 +377,11 @@ public class ActiveMQConnectionFactory implements ConnectionFactory, QueueConnec
} }
} }
public Properties getProperties() { public void populateProperties(Properties props) {
Properties props = new Properties();
props.setProperty("asyncDispatch", Boolean.toString(isAsyncDispatch())); props.setProperty("asyncDispatch", Boolean.toString(isAsyncDispatch()));
props.setProperty(Context.PROVIDER_URL, getBrokerURL());
props.setProperty("brokerURL", getBrokerURL()); props.setProperty("brokerURL", getBrokerURL());
if (getClientID() != null)
props.setProperty("clientID", getClientID()); props.setProperty("clientID", getClientID());
props.setProperty("copyMessageOnSend", Boolean.toString(isCopyMessageOnSend())); props.setProperty("copyMessageOnSend", Boolean.toString(isCopyMessageOnSend()));
props.setProperty("disableTimeStampsByDefault", Boolean.toString(isDisableTimeStampsByDefault())); props.setProperty("disableTimeStampsByDefault", Boolean.toString(isDisableTimeStampsByDefault()));
@ -395,9 +392,7 @@ public class ActiveMQConnectionFactory implements ConnectionFactory, QueueConnec
props.setProperty("useAsyncSend", Boolean.toString(isUseAsyncSend())); props.setProperty("useAsyncSend", Boolean.toString(isUseAsyncSend()));
props.setProperty("useCompression", Boolean.toString(isUseCompression())); props.setProperty("useCompression", Boolean.toString(isUseCompression()));
props.setProperty("useRetroactiveConsumer", Boolean.toString(isUseRetroactiveConsumer())); props.setProperty("useRetroactiveConsumer", Boolean.toString(isUseRetroactiveConsumer()));
props.setProperty("username", getUserName()); props.setProperty("userName", getUserName());
return props;
} }
public boolean isOnSendPrepareMessageBody() { public boolean isOnSendPrepareMessageBody() {
@ -431,28 +426,4 @@ public class ActiveMQConnectionFactory implements ConnectionFactory, QueueConnec
public void setAsyncDispatch(boolean asyncDispatch) { public void setAsyncDispatch(boolean asyncDispatch) {
this.asyncDispatch = asyncDispatch; this.asyncDispatch = asyncDispatch;
} }
/**
* Retrieve a Reference for this instance to store in JNDI
*
* @return the built Reference
* @throws NamingException if error on building Reference
*/
public Reference getReference() throws NamingException {
Reference ref = new Reference(this.getClass().getName());
try {
Properties props = getProperties();
for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) {
String key = (String) iter.nextElement();
String value = props.getProperty(key);
javax.naming.StringRefAddr addr = new javax.naming.StringRefAddr(key, value);
ref.add(addr);
}
} catch (Exception e) {
throw new NamingException(e.getMessage());
}
return ref;
}
} }

View File

@ -26,7 +26,6 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.Properties; import java.util.Properties;
import java.util.Enumeration;
import javax.jms.Destination; import javax.jms.Destination;
import javax.jms.JMSException; import javax.jms.JMSException;
@ -34,17 +33,16 @@ import javax.jms.Queue;
import javax.jms.TemporaryQueue; import javax.jms.TemporaryQueue;
import javax.jms.TemporaryTopic; import javax.jms.TemporaryTopic;
import javax.jms.Topic; import javax.jms.Topic;
import javax.naming.Reference;
import javax.naming.NamingException;
import javax.naming.Referenceable;
import org.apache.activemq.util.URISupport; import org.apache.activemq.util.URISupport;
import org.apache.activemq.util.IntrospectionSupport;
import org.apache.activemq.jndi.JNDIBaseStorable;
/** /**
* @openwire:marshaller * @openwire:marshaller
* @version $Revision: 1.10 $ * @version $Revision: 1.10 $
*/ */
abstract public class ActiveMQDestination implements DataStructure, Destination, Externalizable, Comparable, Referenceable { abstract public class ActiveMQDestination extends JNDIBaseStorable implements DataStructure, Destination, Externalizable, Comparable {
private static final long serialVersionUID = -3885260014960795889L; private static final long serialVersionUID = -3885260014960795889L;
@ -335,43 +333,15 @@ abstract public class ActiveMQDestination implements DataStructure, Destination,
return false; return false;
} }
public Properties getProperties() { public void buildFromProperties(Properties properties) {
Properties props = new Properties(); if (properties == null) {
properties = new Properties();
}
props.setProperty("composite", Boolean.toString(isComposite())); IntrospectionSupport.setProperties(this, properties);
props.setProperty("destinationType", Byte.toString(getDestinationType())); }
props.setProperty("destinationTypeAsString", getDestinationTypeAsString());
props.setProperty("marshallAware", Boolean.toString(isMarshallAware())); public void populateProperties(Properties props) {
props.setProperty("physicalName", getPhysicalName()); props.setProperty("physicalName", getPhysicalName());
props.setProperty("qualifiedName", getQualifiedName());
props.setProperty("qualifiedPrefix", getQualifiedPrefix());
props.setProperty("queue", Boolean.toString(isQueue()));
props.setProperty("temporary", Boolean.toString(isTemporary()));
props.setProperty("topic", Boolean.toString(isTopic()));
return props;
}
/**
* Retrieve a Reference for this instance to store in JNDI
*
* @return the built Reference
* @throws javax.naming.NamingException if error on building Reference
*/
public Reference getReference() throws NamingException {
Reference ref = new Reference(this.getClass().getName());
try {
Properties props = getProperties();
for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) {
String key = (String) iter.nextElement();
String value = props.getProperty(key);
javax.naming.StringRefAddr addr = new javax.naming.StringRefAddr(key, value);
ref.add(addr);
}
} catch (Exception e) {
throw new NamingException(e.getMessage());
}
return ref;
} }
} }

View File

@ -0,0 +1,83 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.apache.activemq.jndi;
import javax.naming.NamingException;
import javax.naming.Reference;
import java.util.Properties;
/**
* Faciliates objects to be stored in JNDI as properties
*/
public abstract class JNDIBaseStorable implements JNDIStorableInterface {
private Properties properties = null;
/**
* Set the properties that will represent the instance in JNDI
*
* @param props
*/
protected abstract void buildFromProperties(Properties props);
/**
* Initialize the instance from properties stored in JNDI
*
* @param props
*/
protected abstract void populateProperties(Properties props);
/**
* set the properties for this instance as retrieved from JNDI
*
* @param props
*/
public synchronized void setProperties(Properties props) {
this.properties = props;
buildFromProperties(props);
}
/**
* Get the properties from this instance for storing in JNDI
*
* @return the properties
*/
public synchronized Properties getProperties() {
if (this.properties == null) {
this.properties = new Properties();
}
populateProperties(this.properties);
return this.properties;
}
/**
* Retrive a Reference for this instance to store in JNDI
*
* @return the built Reference
* @throws NamingException if error on building Reference
*/
public Reference getReference() throws NamingException {
return JNDIReferenceFactory.createReference(this.getClass().getName(), this);
}
}

View File

@ -0,0 +1,137 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.apache.activemq.jndi;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.naming.spi.ObjectFactory;
import javax.naming.Name;
import javax.naming.Context;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.NamingException;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Enumeration;
/**
* Converts objects implementing JNDIStorable into a property fields so they can
* be stored and regenerated from JNDI
*/
public class JNDIReferenceFactory implements ObjectFactory {
static Log log = LogFactory.getLog(JNDIReferenceFactory.class);
/**
* This will be called by a JNDIprovider when a Reference is retrieved from
* a JNDI store - and generates the orignal instance
*
* @param object the Reference object
* @param name the JNDI name
* @param nameCtx the context
* @param environment the environment settings used by JNDI
* @return the instance built from the Reference object
* @throws Exception if building the instance from Reference fails (usually class
* not found)
*/
public Object getObjectInstance(Object object, Name name, Context nameCtx, Hashtable environment) throws Exception {
Object result = null;
if (object instanceof Reference) {
Reference reference = (Reference) object;
if (log.isTraceEnabled()) {
log.trace("Getting instance of " + reference.getClassName());
}
Class theClass = loadClass(this, reference.getClassName());
if (JNDIStorableInterface.class.isAssignableFrom(theClass)) {
JNDIStorableInterface store = (JNDIStorableInterface) theClass.newInstance();
Properties properties = new Properties();
for (Enumeration iter = reference.getAll(); iter.hasMoreElements();) {
StringRefAddr addr = (StringRefAddr) iter.nextElement();
properties.put(addr.getType(), (addr.getContent() == null) ? "" : addr.getContent());
}
store.setProperties(properties);
result = store;
}
}
else {
log.error("Object " + object + " is not a reference - cannot load");
throw new RuntimeException("Object " + object + " is not a reference");
}
return result;
}
/**
* Create a Reference instance from a JNDIStorable object
*
* @param instanceClassName
* @param po
* @return @throws
* NamingException
*/
public static Reference createReference(String instanceClassName, JNDIStorableInterface po) throws NamingException {
if (log.isTraceEnabled()) {
log.trace("Creating reference: " + instanceClassName + "," + po);
}
Reference result = new Reference(instanceClassName, JNDIReferenceFactory.class.getName(), null);
try {
Properties props = po.getProperties();
for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) {
String key = (String) iter.nextElement();
String value = props.getProperty(key);
javax.naming.StringRefAddr addr = new javax.naming.StringRefAddr(key, value);
result.add(addr);
}
}
catch (Exception e) {
log.error(e.getMessage(), e);
throw new NamingException(e.getMessage());
}
return result;
}
/**
* Retrieve the class loader for a named class
*
* @param thisObj
* @param className
* @return @throws
* ClassNotFoundException
*/
public static Class loadClass(Object thisObj, String className) throws ClassNotFoundException {
// tryu local ClassLoader first.
ClassLoader loader = thisObj.getClass().getClassLoader();
Class theClass;
if (loader != null) {
theClass = loader.loadClass(className);
}
else {
// Will be null in jdk1.1.8
// use default classLoader
theClass = Class.forName(className);
}
return theClass;
}
}

View File

@ -0,0 +1,44 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.apache.activemq.jndi;
import javax.naming.Referenceable;
import java.util.Properties;
/**
* Faciliates objects to be stored in JNDI as properties
*/
public interface JNDIStorableInterface extends Referenceable {
/**
* set the properties for this instance as retrieved from JNDI
*
* @param properties
*/
public void setProperties(Properties properties);
/**
* Get the properties from this instance for storing in JNDI
*
* @return
*/
public Properties getProperties();
}

View File

@ -38,7 +38,7 @@ public class ActiveMQInitialContextFactoryTest extends JNDITestSupport {
InitialContext context = new InitialContext(); InitialContext context = new InitialContext();
//make sure contest is not null //make sure context is not null
assertTrue("Created context", context != null); assertTrue("Created context", context != null);
Object topicDestination = context.lookup("MyTopic"); Object topicDestination = context.lookup("MyTopic");

View File

@ -0,0 +1,84 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.apache.activemq.jndi;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.CombinationTestSupport;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQQueue;
import javax.naming.Reference;
public class ObjectFactoryTest extends CombinationTestSupport {
public void testConnectionFactory() throws Exception {
// Create sample connection factory
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
factory.setAsyncDispatch(false);
factory.setBrokerURL("vm://test");
factory.setClientID("test");
factory.setCopyMessageOnSend(false);
factory.setDisableTimeStampsByDefault(true);
factory.setObjectMessageSerializationDefered(true);
factory.setOnSendPrepareMessageBody(false);
factory.setOptimizedMessageDispatch(false);
factory.setPassword("pass");
factory.setUseAsyncSend(true);
factory.setUseCompression(true);
factory.setUseRetroactiveConsumer(true);
factory.setUserName("user");
// Create reference
Reference ref = JNDIReferenceFactory.createReference(factory.getClass().getName(), factory);
// Get object created based on reference
ActiveMQConnectionFactory temp;
JNDIReferenceFactory refFactory = new JNDIReferenceFactory();
temp = (ActiveMQConnectionFactory)refFactory.getObjectInstance(ref, null, null, null);
// Check settings
assertEquals(factory.isAsyncDispatch(), temp.isAsyncDispatch());
assertEquals(factory.getBrokerURL(), temp.getBrokerURL());
assertEquals(factory.getClientID(), temp.getClientID());
assertEquals(factory.isCopyMessageOnSend(), temp.isCopyMessageOnSend());
assertEquals(factory.isDisableTimeStampsByDefault(), temp.isDisableTimeStampsByDefault());
assertEquals(factory.isObjectMessageSerializationDefered(), temp.isObjectMessageSerializationDefered());
assertEquals(factory.isOnSendPrepareMessageBody(), temp.isOnSendPrepareMessageBody());
assertEquals(factory.isOptimizedMessageDispatch(), temp.isOptimizedMessageDispatch());
assertEquals(factory.getPassword(), temp.getPassword());
assertEquals(factory.isUseAsyncSend(), temp.isUseAsyncSend());
assertEquals(factory.isUseCompression(), temp.isUseCompression());
assertEquals(factory.isUseRetroactiveConsumer(), temp.isUseRetroactiveConsumer());
assertEquals(factory.getUserName(), temp.getUserName());
}
public void testDestination() throws Exception {
// Create sample destination
ActiveMQDestination dest = new ActiveMQQueue();
dest.setPhysicalName("TEST.FOO");
// Create reference
Reference ref = JNDIReferenceFactory.createReference(dest.getClass().getName(), dest);
// Get object created based on reference
ActiveMQDestination temp;
JNDIReferenceFactory refFactory = new JNDIReferenceFactory();
temp = (ActiveMQDestination)refFactory.getObjectInstance(ref, null, null, null);
// Check settings
assertEquals(dest.getPhysicalName(), temp.getPhysicalName());
}
}