From 09682d7ce7e9dca1c664ac13a882dc51be9e1ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Andr=C3=A9=20Pearce?= Date: Sat, 4 Nov 2017 02:26:39 +0000 Subject: [PATCH] JNDI Tomcat Resource Properties Apply fix so that when using JNDI via tomcat resource it works. Replace original extract of JNDIStorable taken from Qpid, and use ActiveMQ5's as fits better to address this issue. (which primary use case is users migrating from 5.x) Refactored ActiveMQConnectionFactory to externalise and turn into reference by StringRefAddr's instead of custom RefAddr which isnt standard. Refactored ActiveMQDestinations similar Refactored ActiveMQDestination to remove redundent and duplicated name field and ensured getters still behave the same --- .../artemis/utils/uri/BeanSupport.java | 32 +++++ .../jms/client/ActiveMQConnectionFactory.java | 85 ++++++------ .../jms/client/ActiveMQDestination.java | 125 +++++++++--------- .../artemis/jms/client/ActiveMQQueue.java | 29 ++-- .../jms/client/ActiveMQTemporaryQueue.java | 10 +- .../jms/client/ActiveMQTemporaryTopic.java | 7 +- .../artemis/jms/client/ActiveMQTopic.java | 26 ++-- .../DestinationObjectFactory.java | 44 ------ .../artemis/jndi/JNDIReferenceFactory.java | 33 ++--- .../activemq/artemis/jndi/JNDIStorable.java | 77 +++++------ .../artemis/jndi/JNDIStorableInterface.java | 41 ++++++ .../amqp/converter/jms/ServerDestination.java | 9 +- .../amqp/converter/jms/ServerJMSMessage.java | 5 +- .../artemis/jms/tests/ReferenceableTest.java | 9 +- .../DestinationObjectFactoryTest.java | 5 +- 15 files changed, 283 insertions(+), 254 deletions(-) delete mode 100644 artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/referenceable/DestinationObjectFactory.java create mode 100644 artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorableInterface.java diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/BeanSupport.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/BeanSupport.java index 70b36aba4cf..62caea0c287 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/BeanSupport.java +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/BeanSupport.java @@ -19,12 +19,14 @@ import java.beans.PropertyDescriptor; import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import org.apache.commons.beanutils.BeanUtilsBean; @@ -69,6 +71,36 @@ public static

P setData(P obj, Map data) throws Exception { return obj; } + public static

P setProperties(P bean, Properties properties) + throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + synchronized (beanUtils) { + PropertyDescriptor[] descriptors = beanUtils.getPropertyUtils().getPropertyDescriptors(bean); + for (PropertyDescriptor descriptor : descriptors) { + if (descriptor.getReadMethod() != null && isWriteable(descriptor, null)) { + String value = properties.getProperty(descriptor.getName()); + if (value != null) { + beanUtils.setProperty(bean, descriptor.getName(), value); + } + } + } + } + return bean; + } + + public static

Properties getProperties(P bean, Properties properties) + throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + synchronized (beanUtils) { + PropertyDescriptor[] descriptors = beanUtils.getPropertyUtils().getPropertyDescriptors(bean); + for (PropertyDescriptor descriptor : descriptors) { + if (descriptor.getReadMethod() != null && isWriteable(descriptor, null)) { + String value = beanUtils.getProperty(bean, descriptor.getName()); + properties.put(descriptor.getName(), value); + } + } + } + return properties; + } + public static void setData(URI uri, HashMap properties, Set allowableProperties, diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java index bd5fccf375f..7bf4a7047c5 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQConnectionFactory.java @@ -30,17 +30,13 @@ import javax.jms.XAJMSContext; import javax.jms.XAQueueConnection; import javax.jms.XATopicConnection; -import javax.naming.NamingException; -import javax.naming.Reference; -import javax.naming.Referenceable; -import java.io.Externalizable; +import javax.naming.Context; import java.io.IOException; -import java.io.InvalidObjectException; -import java.io.ObjectInput; -import java.io.ObjectOutput; +import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Properties; import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration; import org.apache.activemq.artemis.api.core.TransportConfiguration; @@ -51,18 +47,17 @@ import org.apache.activemq.artemis.api.jms.ActiveMQJMSConstants; import org.apache.activemq.artemis.api.jms.JMSFactoryType; import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl; -import org.apache.activemq.artemis.jms.referenceable.ConnectionFactoryObjectFactory; -import org.apache.activemq.artemis.jms.referenceable.SerializableObjectRefAddr; +import org.apache.activemq.artemis.jndi.JNDIStorable; import org.apache.activemq.artemis.spi.core.remoting.ClientProtocolManagerFactory; import org.apache.activemq.artemis.uri.ConnectionFactoryParser; -import org.apache.activemq.artemis.uri.ServerLocatorParser; import org.apache.activemq.artemis.utils.ClassloadingUtil; +import org.apache.activemq.artemis.utils.uri.BeanSupport; /** *

ActiveMQ Artemis implementation of a JMS ConnectionFactory.

*

This connection factory will use defaults defined by {@link DefaultConnectionProperties}. */ -public class ActiveMQConnectionFactory implements ConnectionFactoryOptions, Externalizable, Referenceable, ConnectionFactory, XAConnectionFactory, AutoCloseable { +public class ActiveMQConnectionFactory extends JNDIStorable implements ConnectionFactoryOptions, ConnectionFactory, XAConnectionFactory, AutoCloseable { private ServerLocator serverLocator; @@ -88,20 +83,6 @@ public class ActiveMQConnectionFactory implements ConnectionFactoryOptions, Exte private boolean finalizeChecks; - @Override - public void writeExternal(ObjectOutput out) throws IOException { - URI uri = toURI(); - - try { - out.writeUTF(uri.toASCIIString()); - } catch (Exception e) { - if (e instanceof IOException) { - throw (IOException) e; - } - throw new IOException(e); - } - } - public URI toURI() throws IOException { ConnectionFactoryParser parser = new ConnectionFactoryParser(); String scheme; @@ -183,20 +164,6 @@ public void setDeserializationWhiteList(String whiteList) { this.deserializationWhiteList = whiteList; } - @Override - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - String url = in.readUTF(); - ConnectionFactoryParser parser = new ConnectionFactoryParser(); - ServerLocatorParser locatorParser = new ServerLocatorParser(); - try { - URI uri = new URI(url); - serverLocator = locatorParser.newObject(uri, null); - parser.populateObject(uri, this); - } catch (Exception e) { - throw new InvalidObjectException(e.getMessage()); - } - } - /** * This will use a default URI from {@link DefaultConnectionProperties} */ @@ -204,10 +171,14 @@ public ActiveMQConnectionFactory() { this(DefaultConnectionProperties.DEFAULT_BROKER_URL); } - public ActiveMQConnectionFactory(String url) { + public ActiveMQConnectionFactory(String brokerURL) { + setBrokerURL(brokerURL); + } + + private void setBrokerURL(String brokerURL) { ConnectionFactoryParser cfParser = new ConnectionFactoryParser(); try { - URI uri = cfParser.expandURI(url); + URI uri = cfParser.expandURI(brokerURL); serverLocator = ServerLocatorImpl.newLocator(uri); cfParser.populateObject(uri, this); } catch (Exception e) { @@ -378,8 +349,36 @@ public XATopicConnection createXATopicConnection(final String username, final St } @Override - public Reference getReference() throws NamingException { - return new Reference(this.getClass().getCanonicalName(), new SerializableObjectRefAddr("ActiveMQ-CF", this), ConnectionFactoryObjectFactory.class.getCanonicalName(), null); + protected void buildFromProperties(Properties props) { + String url = props.getProperty(Context.PROVIDER_URL); + if (url == null || url.isEmpty()) { + url = props.getProperty("brokerURL"); + } + if (url != null && url.length() > 0) { + setBrokerURL(url); + } + if (url == null || url.isEmpty()) { + throw new IllegalArgumentException(Context.PROVIDER_URL + " or " + "brokerURL is required"); + } + try { + BeanSupport.setProperties(this, props); + } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + @Override + protected void populateProperties(Properties props) { + try { + URI uri = toURI(); + if (uri != null) { + props.put(Context.PROVIDER_URL, uri.toASCIIString()); + props.put("brokerURL", uri.toASCIIString()); + } + BeanSupport.getProperties(this, props); + } catch (IOException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { + throw new RuntimeException(e); + } } public boolean isHA() { diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java index 0bf4dd6258e..9caa0a97541 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java @@ -19,21 +19,17 @@ import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.JMSRuntimeException; -import javax.naming.NamingException; -import javax.naming.Reference; -import javax.naming.Referenceable; -import java.io.Serializable; +import java.util.Properties; import java.util.UUID; import org.apache.activemq.artemis.api.core.Pair; import org.apache.activemq.artemis.api.core.SimpleString; -import org.apache.activemq.artemis.jms.referenceable.DestinationObjectFactory; -import org.apache.activemq.artemis.jms.referenceable.SerializableObjectRefAddr; +import org.apache.activemq.artemis.jndi.JNDIStorable; /** * ActiveMQ Artemis implementation of a JMS Destination. */ -public class ActiveMQDestination implements Destination, Serializable, Referenceable { +public class ActiveMQDestination extends JNDIStorable implements Destination { // Constants ----------------------------------------------------- // Static -------------------------------------------------------- @@ -78,27 +74,27 @@ public static ActiveMQDestination createDestination(String name, TYPE defaultTyp case TEMP_TOPIC: return new ActiveMQTopic(name, true); case DESTINATION: - return new ActiveMQDestination(name, name, TYPE.DESTINATION, null); + return new ActiveMQDestination(name, TYPE.DESTINATION, null); default: throw new IllegalArgumentException("Invalid default destination type: " + defaultType); } } - public static Destination fromPrefixedName(final String address) { - if (address.startsWith(ActiveMQDestination.QUEUE_QUALIFIED_PREFIX)) { - String name = address.substring(ActiveMQDestination.QUEUE_QUALIFIED_PREFIX.length()); - return createQueue(name); - } else if (address.startsWith(ActiveMQDestination.TOPIC_QUALIFIED_PREFIX)) { - String name = address.substring(ActiveMQDestination.TOPIC_QUALIFIED_PREFIX.length()); - return createTopic(name); - } else if (address.startsWith(ActiveMQDestination.TEMP_QUEUE_QUALIFED_PREFIX)) { - String name = address.substring(ActiveMQDestination.TEMP_QUEUE_QUALIFED_PREFIX.length()); - return new ActiveMQTemporaryQueue(name, name, null); - } else if (address.startsWith(ActiveMQDestination.TEMP_TOPIC_QUALIFED_PREFIX)) { - String name = address.substring(ActiveMQDestination.TEMP_TOPIC_QUALIFED_PREFIX.length()); - return new ActiveMQTemporaryTopic(name, name, null); + public static Destination fromPrefixedName(final String name) { + if (name.startsWith(ActiveMQDestination.QUEUE_QUALIFIED_PREFIX)) { + String address = name.substring(ActiveMQDestination.QUEUE_QUALIFIED_PREFIX.length()); + return createQueue(address); + } else if (name.startsWith(ActiveMQDestination.TOPIC_QUALIFIED_PREFIX)) { + String address = name.substring(ActiveMQDestination.TOPIC_QUALIFIED_PREFIX.length()); + return createTopic(address); + } else if (name.startsWith(ActiveMQDestination.TEMP_QUEUE_QUALIFED_PREFIX)) { + String address = name.substring(ActiveMQDestination.TEMP_QUEUE_QUALIFED_PREFIX.length()); + return new ActiveMQTemporaryQueue(address, null); + } else if (name.startsWith(ActiveMQDestination.TEMP_TOPIC_QUALIFED_PREFIX)) { + String address = name.substring(ActiveMQDestination.TEMP_TOPIC_QUALIFED_PREFIX.length()); + return new ActiveMQTemporaryTopic(address, null); } else { - return new ActiveMQDestination(address, address, TYPE.DESTINATION, null); + return new ActiveMQDestination(name, TYPE.DESTINATION, null); } } @@ -191,58 +187,48 @@ public static SimpleString createTopicAddressFromName(final String name) { return new SimpleString(TOPIC_QUALIFIED_PREFIX + name); } - public static ActiveMQQueue createQueue(final String name) { - return new ActiveMQQueue(name); + public static ActiveMQQueue createQueue(final String address) { + return new ActiveMQQueue(address); } - public static ActiveMQTopic createTopic(final String name) { - return new ActiveMQTopic(name); + public static ActiveMQTopic createTopic(final String address) { + return new ActiveMQTopic(address); } - public static ActiveMQTemporaryQueue createTemporaryQueue(final String name, final ActiveMQSession session) { - return new ActiveMQTemporaryQueue(name, name, session); + public static ActiveMQTemporaryQueue createTemporaryQueue(final String address, final ActiveMQSession session) { + return new ActiveMQTemporaryQueue(address, session); } - public static ActiveMQTemporaryQueue createTemporaryQueue(final String name) { - return createTemporaryQueue(name, null); + public static ActiveMQTemporaryQueue createTemporaryQueue(final String address) { + return createTemporaryQueue(address, null); } public static ActiveMQTemporaryQueue createTemporaryQueue(final ActiveMQSession session) { - String name = UUID.randomUUID().toString(); + String address = UUID.randomUUID().toString(); - return createTemporaryQueue(name, session); + return createTemporaryQueue(address, session); } public static ActiveMQTemporaryTopic createTemporaryTopic(final ActiveMQSession session) { - String name = UUID.randomUUID().toString(); + String address = UUID.randomUUID().toString(); - return createTemporaryTopic(name, session); + return createTemporaryTopic(address, session); } - public static ActiveMQTemporaryTopic createTemporaryTopic(String name, final ActiveMQSession session) { - return new ActiveMQTemporaryTopic(name, name, session); + public static ActiveMQTemporaryTopic createTemporaryTopic(String address, final ActiveMQSession session) { + return new ActiveMQTemporaryTopic(address, session); } - public static ActiveMQTemporaryTopic createTemporaryTopic(String name) { - return createTemporaryTopic(name, null); + public static ActiveMQTemporaryTopic createTemporaryTopic(String address) { + return createTemporaryTopic(address, null); } // Attributes ---------------------------------------------------- - /** - * The JMS name - */ - protected final String name; - - /** - * The core address - */ - private final String address; - /** * SimpleString version of address */ - private final SimpleString simpleAddress; + private SimpleString address; private final TYPE type; @@ -251,25 +237,34 @@ public static ActiveMQTemporaryTopic createTemporaryTopic(String name) { // Constructors -------------------------------------------------- protected ActiveMQDestination(final String address, - final String name, final TYPE type, final ActiveMQSession session) { - this.address = address; + this.address = SimpleString.toSimpleString(address); - this.name = name; + this.type = type; + + this.session = session; + } - simpleAddress = new SimpleString(address); + protected ActiveMQDestination(final SimpleString address, + final TYPE type, + final ActiveMQSession session) { + this.address = address; this.type = type; this.session = session; } - // Referenceable implementation --------------------------------------- + public void setAddress(String address) { + setSimpleAddress(SimpleString.toSimpleString(address)); + } - @Override - public Reference getReference() throws NamingException { - return new Reference(this.getClass().getCanonicalName(), new SerializableObjectRefAddr("ActiveMQ-DEST", this), DestinationObjectFactory.class.getCanonicalName(), null); + public void setSimpleAddress(SimpleString address) { + if (address == null) { + throw new IllegalArgumentException("address cannot be null"); + } + this.address = address; } public void delete() throws JMSException { @@ -293,15 +288,15 @@ public boolean isQueue() { // Public -------------------------------------------------------- public String getAddress() { - return address; + return address.toString(); } public SimpleString getSimpleAddress() { - return simpleAddress; + return address; } public String getName() { - return name; + return address.toString(); } public boolean isTemporary() { @@ -332,6 +327,16 @@ public int hashCode() { return address.hashCode(); } + @Override + protected void buildFromProperties(Properties props) { + setAddress(props.getProperty("address")); + } + + @Override + protected void populateProperties(Properties props) { + props.put("address", getAddress()); + } + // Package protected --------------------------------------------- // Protected ----------------------------------------------------- diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueue.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueue.java index 2f9a47b0016..2deefa974b0 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueue.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQQueue.java @@ -18,8 +18,6 @@ import javax.jms.Queue; -import org.apache.activemq.artemis.api.core.SimpleString; - /** * ActiveMQ Artemis implementation of a JMS Queue. *
@@ -32,35 +30,30 @@ public class ActiveMQQueue extends ActiveMQDestination implements Queue { // Static -------------------------------------------------------- - public static SimpleString createAddressFromName(final String name) { - return new SimpleString(name); - } - // Attributes ---------------------------------------------------- // Constructors -------------------------------------------------- + public ActiveMQQueue() { + this(null); + } - public ActiveMQQueue(final String name) { - super(name, name, TYPE.QUEUE, null); + public ActiveMQQueue(final String address) { + super(address, TYPE.QUEUE, null); } - public ActiveMQQueue(final String name, boolean temporary) { - super(name, name, temporary ? TYPE.TEMP_QUEUE : TYPE.QUEUE, null); + public ActiveMQQueue(final String address, boolean temporary) { + super(address, temporary ? TYPE.TEMP_QUEUE : TYPE.QUEUE, null); } /** * @param address - * @param name * @param temporary * @param session */ - public ActiveMQQueue(String address, String name, boolean temporary, ActiveMQSession session) { - super(address, name, temporary ? TYPE.TEMP_QUEUE : TYPE.QUEUE, session); + public ActiveMQQueue(String address, boolean temporary, ActiveMQSession session) { + super(address, temporary ? TYPE.TEMP_QUEUE : TYPE.QUEUE, session); } - public ActiveMQQueue(final String address, final String name) { - super(address, name, TYPE.QUEUE, null); - } // Queue implementation ------------------------------------------ @@ -68,12 +61,12 @@ public ActiveMQQueue(final String address, final String name) { @Override public String getQueueName() { - return name; + return getAddress(); } @Override public String toString() { - return "ActiveMQQueue[" + name + "]"; + return "ActiveMQQueue[" + getAddress() + "]"; } @Override diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryQueue.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryQueue.java index 88a822ade7f..b79c36adf8a 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryQueue.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryQueue.java @@ -37,19 +37,21 @@ public class ActiveMQTemporaryQueue extends ActiveMQQueue implements TemporaryQu // TemporaryQueue implementation ------------------------------------------ // Public -------------------------------------------------------- + public ActiveMQTemporaryQueue() { + this(null, null); + } /** * @param address - * @param name * @param session */ - public ActiveMQTemporaryQueue(String address, String name, ActiveMQSession session) { - super(address, name, true, session); + public ActiveMQTemporaryQueue(String address, ActiveMQSession session) { + super(address, true, session); } @Override public String toString() { - return "ActiveMQTemporaryQueue[" + name + "]"; + return "ActiveMQTemporaryQueue[" + getAddress() + "]"; } @Override diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryTopic.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryTopic.java index 98b5ba6c368..457663d1a7d 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryTopic.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTemporaryTopic.java @@ -29,9 +29,12 @@ public class ActiveMQTemporaryTopic extends ActiveMQTopic implements TemporaryTo // Static -------------------------------------------------------- // Constructors -------------------------------------------------- + public ActiveMQTemporaryTopic() { + this(null, null); + } - protected ActiveMQTemporaryTopic(final String address, final String name, final ActiveMQSession session) { - super(address, name, true, session); + public ActiveMQTemporaryTopic(final String address, final ActiveMQSession session) { + super(address, true, session); } // Public -------------------------------------------------------- diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTopic.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTopic.java index 94bdd255529..e22e67b65b3 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTopic.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQTopic.java @@ -18,8 +18,6 @@ import javax.jms.Topic; -import org.apache.activemq.artemis.api.core.SimpleString; - /** * ActiveMQ Artemis implementation of a JMS Topic. *
@@ -31,44 +29,42 @@ public class ActiveMQTopic extends ActiveMQDestination implements Topic { private static final long serialVersionUID = 7873614001276404156L; // Static -------------------------------------------------------- - public static SimpleString createAddressFromName(final String name) { - return new SimpleString(name); - } - // Attributes ---------------------------------------------------- // Constructors -------------------------------------------------- + public ActiveMQTopic() { + this(null); + } - public ActiveMQTopic(final String name) { - this(name, false); + public ActiveMQTopic(final String address) { + this(address, false); } - public ActiveMQTopic(final String name, boolean temporary) { - super(name, name, TYPE.TOPIC, null); + public ActiveMQTopic(final String address, boolean temporary) { + super(address, TYPE.TOPIC, null); } /** * @param address - * @param name * @param temporary * @param session */ - protected ActiveMQTopic(String address, String name, boolean temporary, ActiveMQSession session) { - super(address, name, temporary ? TYPE.TEMP_TOPIC : TYPE.TOPIC, session); + protected ActiveMQTopic(String address, boolean temporary, ActiveMQSession session) { + super(address, temporary ? TYPE.TEMP_TOPIC : TYPE.TOPIC, session); } // Topic implementation ------------------------------------------ @Override public String getTopicName() { - return name; + return getName(); } // Public -------------------------------------------------------- @Override public String toString() { - return "ActiveMQTopic[" + name + "]"; + return "ActiveMQTopic[" + getName() + "]"; } @Override diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/referenceable/DestinationObjectFactory.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/referenceable/DestinationObjectFactory.java deleted file mode 100644 index 896e81561ff..00000000000 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/referenceable/DestinationObjectFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.activemq.artemis.jms.referenceable; - -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.Reference; -import javax.naming.spi.ObjectFactory; -import java.util.Hashtable; - -/** - * A DestinationObjectFactory. - * - * Given a Reference - reconstructs an ActiveMQDestination - */ -public class DestinationObjectFactory implements ObjectFactory { - - @Override - public Object getObjectInstance(final Object ref, - final Name name, - final Context ctx, - final Hashtable props) throws Exception { - Reference r = (Reference) ref; - - byte[] bytes = (byte[]) r.get("ActiveMQ-DEST").getContent(); - - // Deserialize - return SerializableObjectRefAddr.deserialize(bytes); - } -} diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIReferenceFactory.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIReferenceFactory.java index c22676013bb..f530c3213fb 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIReferenceFactory.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIReferenceFactory.java @@ -19,14 +19,13 @@ import javax.naming.Context; import javax.naming.Name; import javax.naming.NamingException; -import javax.naming.RefAddr; import javax.naming.Reference; import javax.naming.StringRefAddr; import javax.naming.spi.ObjectFactory; import java.util.Enumeration; -import java.util.HashMap; import java.util.Hashtable; -import java.util.Map; +import java.util.Properties; + /** * Converts objects implementing JNDIStorable into a property fields so they can be @@ -61,14 +60,9 @@ public Object getObjectInstance(Object object, Name name, Context nameCtx, Hasht if (object instanceof Reference) { Reference reference = (Reference) object; Class theClass = loadClass(this, reference.getClassName()); - if (JNDIStorable.class.isAssignableFrom(theClass)) { - JNDIStorable store = (JNDIStorable) theClass.newInstance(); - Map properties = new HashMap<>(); - for (Enumeration iter = reference.getAll(); iter.hasMoreElements();) { - StringRefAddr addr = (StringRefAddr) iter.nextElement(); - properties.put(addr.getType(), (addr.getContent() == null) ? "" : addr.getContent().toString()); - } - store.setProperties(properties); + if (JNDIStorableInterface.class.isAssignableFrom(theClass)) { + JNDIStorableInterface store = (JNDIStorableInterface) theClass.newInstance(); + store.setProperties(getProperties(reference)); result = store; } } else { @@ -77,6 +71,15 @@ public Object getObjectInstance(Object object, Name name, Context nameCtx, Hasht return result; } + public static Properties getProperties(Reference reference) { + 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()); + } + return properties; + } + /** * Create a Reference instance from a JNDIStorable object * @@ -92,10 +95,10 @@ public Object getObjectInstance(Object object, Name name, Context nameCtx, Hasht public static Reference createReference(String instanceClassName, JNDIStorable po) throws NamingException { Reference result = new Reference(instanceClassName, JNDIReferenceFactory.class.getName(), null); try { - Map props = po.getProperties(); - for (Map.Entry entry : props.entrySet()) { - StringRefAddr addr = new StringRefAddr(entry.getKey(), entry.getValue()); - result.add(addr); + Properties props = po.getProperties(); + for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) { + String key = (String)iter.nextElement(); + result.add(new StringRefAddr(key, props.getProperty(key))); } } catch (Exception e) { throw new NamingException(e.getMessage()); diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorable.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorable.java index 2c26b0a7386..bdc3bd00736 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorable.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorable.java @@ -1,4 +1,4 @@ -/* +/** * 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. @@ -6,7 +6,7 @@ * (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 + * 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, @@ -16,51 +16,47 @@ */ package org.apache.activemq.artemis.jndi; -import javax.naming.NamingException; -import javax.naming.Reference; -import javax.naming.Referenceable; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.Properties; + +import javax.naming.NamingException; +import javax.naming.Reference; /** * Facilitates objects to be stored in JNDI as properties - * - * @since 1.0 */ -public abstract class JNDIStorable implements Referenceable, Externalizable { +public abstract class JNDIStorable implements JNDIStorableInterface, Externalizable { + + private Properties properties; + /** - * Set the properties that will represent the instance in JNDI + * set the properties for this instance as retrieved from JNDI * * @param props - * The properties to use when building the new isntance. - * - * @return a new, unmodifiable, map containing any unused properties, or empty if none were. */ - protected abstract Map buildFromProperties(Map props); + protected abstract void buildFromProperties(Properties props); + /** - * Initialize the instance from properties stored in JNDI + * Set the properties that will represent the instance in JNDI * * @param props - * The properties to use when initializing the new instance. */ - protected abstract void populateProperties(Map props); + protected abstract void populateProperties(Properties props); /** * set the properties for this instance as retrieved from JNDI * * @param props - * The properties to apply to this instance. - * - * @return a new, unmodifiable, map containing any unused properties, or empty if none were. */ - public synchronized Map setProperties(Map props) { - return buildFromProperties(props); + @Override + public synchronized void setProperties(Properties props) { + this.properties = props; + buildFromProperties(props); } /** @@ -68,18 +64,20 @@ public synchronized Map setProperties(Map props) * * @return the properties */ - public synchronized Map getProperties() { - Map properties = new LinkedHashMap<>(); - populateProperties(properties); - return properties; + @Override + public synchronized Properties getProperties() { + if (this.properties == null) { + this.properties = new Properties(); + } + populateProperties(this.properties); + return this.properties; } /** * Retrieve a Reference for this instance to store in JNDI * * @return the built Reference - * @throws NamingException - * if error on building Reference + * @throws NamingException if error on building Reference */ @Override public Reference getReference() throws NamingException { @@ -87,30 +85,27 @@ public Reference getReference() throws NamingException { } /** - * @see Externalizable#readExternal(ObjectInput) + * @param in + * @throws IOException + * @throws ClassNotFoundException + * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ - @SuppressWarnings("unchecked") @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - Map props = (Map) in.readObject(); + Properties props = (Properties)in.readObject(); if (props != null) { setProperties(props); } } /** - * @see Externalizable#writeExternal(ObjectOutput) + * @param out + * @throws IOException + * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) */ @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(getProperties()); } - protected String getProperty(Map map, String key, String defaultValue) { - String value = map.get(key); - if (value != null) { - return value; - } - return defaultValue; - } -} +} \ No newline at end of file diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorableInterface.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorableInterface.java new file mode 100644 index 00000000000..a49fda0ec5c --- /dev/null +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jndi/JNDIStorableInterface.java @@ -0,0 +1,41 @@ +/** + * 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.activemq.artemis.jndi; + +import javax.naming.Referenceable; +import java.util.Properties; + +/** + * Facilitates 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 + */ + void setProperties(Properties properties); + + /** + * Get the properties from this instance for storing in JNDI + * + * @return the properties that should be stored in JNDI + */ + Properties getProperties(); + +} \ No newline at end of file diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java index cee9ee5ed52..5a2f55bb67f 100644 --- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java @@ -19,6 +19,7 @@ import javax.jms.JMSException; import javax.jms.Queue; +import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.jms.client.ActiveMQDestination; /** @@ -27,8 +28,12 @@ */ public class ServerDestination extends ActiveMQDestination implements Queue { - public ServerDestination(String name) { - super(name, name, TYPE.DESTINATION, null); + public ServerDestination(String address) { + super(address, TYPE.DESTINATION, null); + } + + public ServerDestination(SimpleString address) { + super(address, TYPE.DESTINATION, null); } @Override diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java index 2a52f7af761..221c529f619 100644 --- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java @@ -139,7 +139,7 @@ public final void setJMSCorrelationID(String correlationID) throws JMSException public final Destination getJMSReplyTo() throws JMSException { SimpleString reply = MessageUtil.getJMSReplyTo(message); if (reply != null) { - return new ServerDestination(reply.toString()); + return new ServerDestination(reply); } else { return null; } @@ -148,7 +148,6 @@ public final Destination getJMSReplyTo() throws JMSException { @Override public final void setJMSReplyTo(Destination replyTo) throws JMSException { MessageUtil.setJMSReplyTo(message, replyTo == null ? null : ((ActiveMQDestination) replyTo).getSimpleAddress()); - } @Override @@ -158,7 +157,7 @@ public final Destination getJMSDestination() throws JMSException { if (sdest == null) { return null; } else { - return new ServerDestination(sdest.toString()); + return new ServerDestination(sdest); } } diff --git a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ReferenceableTest.java b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ReferenceableTest.java index 2cebf045d90..1795193bf0b 100644 --- a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ReferenceableTest.java +++ b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/ReferenceableTest.java @@ -25,6 +25,7 @@ import javax.jms.TextMessage; import javax.naming.Reference; import javax.naming.Referenceable; +import javax.naming.spi.ObjectFactory; import java.io.Serializable; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; @@ -32,8 +33,6 @@ import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQQueue; import org.apache.activemq.artemis.jms.client.ActiveMQTopic; -import org.apache.activemq.artemis.jms.referenceable.ConnectionFactoryObjectFactory; -import org.apache.activemq.artemis.jms.referenceable.DestinationObjectFactory; import org.apache.activemq.artemis.jms.tests.util.ProxyAssertSupport; import org.junit.Test; @@ -81,7 +80,7 @@ public void testReferenceCF() throws Exception { Class factoryClass = Class.forName(factoryName); - ConnectionFactoryObjectFactory factory = (ConnectionFactoryObjectFactory) factoryClass.newInstance(); + ObjectFactory factory = (ObjectFactory) factoryClass.newInstance(); Object instance = factory.getObjectInstance(cfRef, null, null, null); @@ -100,7 +99,7 @@ public void testReferenceQueue() throws Exception { Class factoryClass = Class.forName(factoryName); - DestinationObjectFactory factory = (DestinationObjectFactory) factoryClass.newInstance(); + ObjectFactory factory = (ObjectFactory) factoryClass.newInstance(); Object instance = factory.getObjectInstance(queueRef, null, null, null); @@ -121,7 +120,7 @@ public void testReferenceTopic() throws Exception { Class factoryClass = Class.forName(factoryName); - DestinationObjectFactory factory = (DestinationObjectFactory) factoryClass.newInstance(); + ObjectFactory factory = (ObjectFactory) factoryClass.newInstance(); Object instance = factory.getObjectInstance(topicRef, null, null, null); diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/jms/referenceable/DestinationObjectFactoryTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/jms/referenceable/DestinationObjectFactoryTest.java index 7bbbf31c75d..e0cb5b27627 100644 --- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/jms/referenceable/DestinationObjectFactoryTest.java +++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/jms/referenceable/DestinationObjectFactoryTest.java @@ -17,10 +17,11 @@ package org.apache.activemq.artemis.tests.unit.jms.referenceable; import javax.naming.Reference; +import javax.naming.spi.ObjectFactory; import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient; import org.apache.activemq.artemis.jms.client.ActiveMQDestination; -import org.apache.activemq.artemis.jms.referenceable.DestinationObjectFactory; +import org.apache.activemq.artemis.jndi.JNDIReferenceFactory; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.activemq.artemis.utils.RandomUtil; import org.junit.Assert; @@ -42,7 +43,7 @@ public void testReference() throws Exception { ActiveMQDestination queue = (ActiveMQDestination) ActiveMQJMSClient.createQueue(RandomUtil.randomString()); Reference reference = queue.getReference(); - DestinationObjectFactory factory = new DestinationObjectFactory(); + ObjectFactory factory = new JNDIReferenceFactory(); Object object = factory.getObjectInstance(reference, null, null, null); Assert.assertNotNull(object); Assert.assertTrue(object instanceof ActiveMQDestination);