diff --git a/src/main/java/com/rabbitmq/jms/admin/RMQConnectionFactory.java b/src/main/java/com/rabbitmq/jms/admin/RMQConnectionFactory.java index 2cac5cc1..2beecbc0 100644 --- a/src/main/java/com/rabbitmq/jms/admin/RMQConnectionFactory.java +++ b/src/main/java/com/rabbitmq/jms/admin/RMQConnectionFactory.java @@ -556,10 +556,22 @@ private static String uriVirtualHostEscape(String vHost) { */ @Override public Reference getReference() throws NamingException { - Reference ref = new Reference(RMQConnectionFactory.class.getName()); + Reference ref = new Reference(RMQConnectionFactory.class.getName(), RMQObjectFactory.class.getName(), null); addStringRefProperty(ref, "uri", this.getUri()); + addStringRefProperty(ref, "host", this.getHost()); + addStringRefProperty(ref, "password", this.getPassword()); + addIntegerRefProperty(ref, "port", this.getPort()); addIntegerRefProperty(ref, "queueBrowserReadMax", this.getQueueBrowserReadMax()); addIntegerRefProperty(ref, "onMessageTimeoutMs", this.getOnMessageTimeoutMs()); + addIntegerRefProperty(ref, "channelsQos", this.getChannelsQos()); + addBooleanProperty(ref, "ssl", this.ssl); + addLongRefProperty(ref, "terminationTimeout", this.getTerminationTimeout()); + addStringRefProperty(ref, "username", this.getUsername()); + addStringRefProperty(ref, "virtualHost", this.getVirtualHost()); + addBooleanProperty(ref, "cleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose", + this.isCleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose()); + addBooleanProperty(ref, "declareReplyToDestination", + this.declareReplyToDestination); return ref; } @@ -591,6 +603,35 @@ private static void addIntegerRefProperty(Reference ref, ref.add(ra); } + /** + * Adds an long valued property to a Reference (as a RefAddr). + * @param ref - the reference to contain the value + * @param propertyName - the name of the property + * @param value - the value to store with the property + */ + private static void addLongRefProperty(Reference ref, + String propertyName, + Long value) { + if (value == null || propertyName == null) return; + RefAddr ra = new StringRefAddr(propertyName, String.valueOf(value)); + ref.add(ra); + } + + /** + * Adds a boolean valued property to a Reference (as a StringRefAddr) if the value is true + * (default false on read assumed). + * @param ref - the reference to contain the value + * @param propertyName - the name of the property + * @param value - the value to store with the property + */ + private static final void addBooleanProperty(Reference ref, + String propertyName, + boolean value) { + if (propertyName==null) return; + RefAddr ra = new StringRefAddr(propertyName, String.valueOf(value)); + ref.add(ra); + } + /** * {@inheritDoc} */ diff --git a/src/main/java/com/rabbitmq/jms/admin/RMQDestination.java b/src/main/java/com/rabbitmq/jms/admin/RMQDestination.java index ea19f34b..e274eef6 100644 --- a/src/main/java/com/rabbitmq/jms/admin/RMQDestination.java +++ b/src/main/java/com/rabbitmq/jms/admin/RMQDestination.java @@ -260,7 +260,7 @@ public String getQueueName() throws JMSException { @Override public Reference getReference() throws NamingException { - Reference ref = new Reference(this.getClass().getCanonicalName()); + Reference ref = new Reference(this.getClass().getCanonicalName(), RMQObjectFactory.class.getName(), null); addStringProperty(ref, "destinationName", this.destinationName); addBooleanProperty(ref, "amqp", this.amqp); addBooleanProperty(ref, "isQueue", this.isQueue); diff --git a/src/main/java/com/rabbitmq/jms/admin/RMQObjectFactory.java b/src/main/java/com/rabbitmq/jms/admin/RMQObjectFactory.java index 4c9219fa..e44eec03 100644 --- a/src/main/java/com/rabbitmq/jms/admin/RMQObjectFactory.java +++ b/src/main/java/com/rabbitmq/jms/admin/RMQObjectFactory.java @@ -143,8 +143,10 @@ public Object getObjectInstance(Object obj, Name name, Context ctx, Hashtable environment, Name 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); + String amqpExchangeName = getStringProperty(ref, environment, "amqpExchangeName", true, null); + String amqpRoutingKey = getStringProperty(ref, environment,"amqpRoutingKey", true, null); + String amqpQueueName = getStringProperty(ref, environment, "amqpQueueName", true, null); return new RMQDestination(dname, amqpExchangeName, amqpRoutingKey, amqpQueueName); } else { return new RMQDestination(dname, !topic, false); diff --git a/src/test/java/com/rabbitmq/jms/admin/RMQConnectionFactoryTest.java b/src/test/java/com/rabbitmq/jms/admin/RMQConnectionFactoryTest.java index e0fdcaa5..ba9c9e7a 100644 --- a/src/test/java/com/rabbitmq/jms/admin/RMQConnectionFactoryTest.java +++ b/src/test/java/com/rabbitmq/jms/admin/RMQConnectionFactoryTest.java @@ -15,6 +15,7 @@ import javax.naming.StringRefAddr; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; +import java.lang.reflect.Field; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; @@ -34,8 +35,18 @@ public class RMQConnectionFactoryTest { static { RMQConnectionFactory defaultFact = new RMQConnectionFactory(); defaultProps.setProperty("uri", defaultFact.getUri()); + defaultProps.setProperty("host", defaultFact.getHost()); + defaultProps.setProperty("password", defaultFact.getPassword()); + defaultProps.setProperty("port", "5672"); defaultProps.setProperty("queueBrowserReadMax", "0"); defaultProps.setProperty("onMessageTimeoutMs", "2000"); + defaultProps.setProperty("channelsQos", "-1"); + defaultProps.setProperty("ssl", "false"); + defaultProps.setProperty("terminationTimeout", "15000"); + defaultProps.setProperty("username", "guest"); + defaultProps.setProperty("virtualHost", "/"); + defaultProps.setProperty("cleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose", "false"); + defaultProps.setProperty("declareReplyToDestination", "true"); } private static Properties getProps(Reference ref) { @@ -87,7 +98,7 @@ private static void removeRefProperty(Reference ref, public void testDefaultConnectionFactoryReference() throws Exception { RMQConnectionFactory connFactory = new RMQConnectionFactory(); Reference ref = connFactory.getReference(); - + assertThat(getProps(ref)).hasSameSizeAs(defaultProps); assertEquals(defaultProps, getProps(ref), "Not the default properties"); } @@ -121,10 +132,14 @@ public void testConnectionFactoryRegeneration() throws Exception { connFactory.setPassword("my-password"); connFactory.setPort(42); connFactory.setQueueBrowserReadMax(52); + connFactory.setOnMessageTimeoutMs(66); + connFactory.setChannelsQos(250); connFactory.useSslProtocol(); connFactory.setTerminationTimeout(1234567890123456789L); connFactory.setUsername("fred"); connFactory.setVirtualHost("bill"); + connFactory.setCleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose(true); + connFactory.setDeclareReplyToDestination(false); Reference ref = connFactory.getReference(); @@ -136,12 +151,19 @@ public void testConnectionFactoryRegeneration() throws Exception { assertEquals("my-password", newFactory.getPassword(), "Not the correct password"); assertEquals(42, newFactory.getPort(), "Not the correct port"); assertEquals(52, newFactory.getQueueBrowserReadMax(), "Not the correct queueBrowserReadMax"); + assertEquals(66, newFactory.getOnMessageTimeoutMs()); + assertEquals(250, newFactory.getChannelsQos()); assertEquals(true, newFactory.isSsl(), "Not the correct ssl"); - assertEquals(15000L, newFactory.getTerminationTimeout(), "Not the correct terminationTimeout"); + assertEquals(1234567890123456789L, newFactory.getTerminationTimeout(), "Not the correct terminationTimeout"); assertEquals("fred", newFactory.getUsername(), "Not the correct username"); assertEquals("bill", newFactory.getVirtualHost(), "Not the correct virtualHost"); + assertTrue(newFactory.isCleanUpServerNamedQueuesForNonDurableTopicsOnSessionClose()); + + Field declareReplyToDestinationField = RMQConnectionFactory.class.getDeclaredField("declareReplyToDestination"); + declareReplyToDestinationField.setAccessible(true); + assertFalse((Boolean) declareReplyToDestinationField.get(newFactory)); } @Test diff --git a/src/test/java/com/rabbitmq/jms/admin/RMQDestinationTest.java b/src/test/java/com/rabbitmq/jms/admin/RMQDestinationTest.java new file mode 100644 index 00000000..0f2764af --- /dev/null +++ b/src/test/java/com/rabbitmq/jms/admin/RMQDestinationTest.java @@ -0,0 +1,79 @@ +/* Copyright (c) 2020 VMware, Inc. or its affiliates. All rights reserved. */ +package com.rabbitmq.jms.admin; + +import org.junit.jupiter.api.Test; + +import javax.naming.Reference; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RMQDestinationTest { + + RMQObjectFactory rmqObjectFactory = new RMQObjectFactory(); + + @Test + void queueRegeneration() throws Exception { + RMQDestination queue = new RMQDestination("queue", true, false); + Reference reference = queue.getReference(); + RMQDestination newQueue = (RMQDestination) rmqObjectFactory.getObjectInstance(reference, null, null, null); + assertThat(newQueue.isQueue()).isTrue(); + assertThat(newQueue.getDestinationName()).isEqualTo("queue"); + assertThat(newQueue.isAmqp()).isFalse(); + } + + @Test + void topicRegeneration() throws Exception { + RMQDestination topic = new RMQDestination("topic", false, false); + Reference reference = topic.getReference(); + RMQDestination newTopic = (RMQDestination) rmqObjectFactory.getObjectInstance(reference, null, null, null); + assertThat(newTopic.isQueue()).isFalse(); + assertThat(newTopic.getDestinationName()).isEqualTo("topic"); + assertThat(newTopic.isAmqp()).isFalse(); + } + + @Test + void amqpDestinationRegeneration() throws Exception { + RMQDestination destination = new RMQDestination( + "destination", "exchange", "routing-key", "queue" + ); + Reference reference = destination.getReference(); + RMQDestination newReference = (RMQDestination) rmqObjectFactory.getObjectInstance(reference, null, null, null); + assertThat(newReference.isQueue()).isTrue(); + assertThat(newReference.getDestinationName()).isEqualTo("destination"); + assertThat(newReference.isAmqp()).isTrue(); + assertThat(newReference.getAmqpExchangeName()).isEqualTo("exchange"); + assertThat(newReference.getAmqpRoutingKey()).isEqualTo("routing-key"); + assertThat(newReference.getAmqpQueueName()).isEqualTo("queue"); + } + + @Test + void amqpDestinationExchangeRoutingKeyOnlyRegeneration() throws Exception { + RMQDestination destination = new RMQDestination( + "destination", "exchange", "routing-key", null + ); + Reference reference = destination.getReference(); + RMQDestination newReference = (RMQDestination) rmqObjectFactory.getObjectInstance(reference, null, null, null); + assertThat(newReference.isQueue()).isTrue(); + assertThat(newReference.getDestinationName()).isEqualTo("destination"); + assertThat(newReference.isAmqp()).isTrue(); + assertThat(newReference.getAmqpExchangeName()).isEqualTo("exchange"); + assertThat(newReference.getAmqpRoutingKey()).isEqualTo("routing-key"); + assertThat(newReference.getAmqpQueueName()).isNull(); + } + + @Test + void amqpDestinationQueueOnlyRegeneration() throws Exception { + RMQDestination destination = new RMQDestination( + "destination", null, null, "queue" + ); + Reference reference = destination.getReference(); + RMQDestination newReference = (RMQDestination) rmqObjectFactory.getObjectInstance(reference, null, null, null); + assertThat(newReference.isQueue()).isTrue(); + assertThat(newReference.getDestinationName()).isEqualTo("destination"); + assertThat(newReference.isAmqp()).isTrue(); + assertThat(newReference.getAmqpExchangeName()).isNull(); + assertThat(newReference.getAmqpRoutingKey()).isNull(); + assertThat(newReference.getAmqpQueueName()).isEqualTo("queue"); + } + +} diff --git a/src/test/java/com/rabbitmq/jms/admin/RMQObjectFactoryTest.java b/src/test/java/com/rabbitmq/jms/admin/RMQObjectFactoryTest.java index 565332ff..ae5287a8 100644 --- a/src/test/java/com/rabbitmq/jms/admin/RMQObjectFactoryTest.java +++ b/src/test/java/com/rabbitmq/jms/admin/RMQObjectFactoryTest.java @@ -1,3 +1,4 @@ +/* Copyright (c) 2018-2020 VMware, Inc. or its affiliates. All rights reserved. */ package com.rabbitmq.jms.admin; import org.junit.jupiter.api.Test; @@ -21,7 +22,7 @@ public class RMQObjectFactoryTest { private RMQObjectFactory rmqObjectFactory = new RMQObjectFactory(); @Test - public void getObjectInstanceShouldCreateARMQConnectionFactoryViaReference() throws Exception { + public void getObjectInstanceShouldCreateAMQPConnectionFactoryViaReference() throws Exception { Reference ref = new Reference(ConnectionFactory.class.getName()); @@ -42,7 +43,7 @@ public void getObjectInstanceShouldCreateARMQConnectionFactoryViaReference() thr @Test - public void getObjectInstanceShouldCreateARMQConnectionFactoryViaEnvironment() throws Exception { + public void getObjectInstanceShouldCreateAMQPConnectionFactoryViaEnvironment() throws Exception { Hashtable environment = new Hashtable() {{ put("className", "javax.jms.ConnectionFactory"); @@ -69,7 +70,7 @@ public void getObjectInstanceShouldCreateARMQConnectionFactoryViaEnvironment() t } @Test - public void getObjectInstanceShouldCreateARMQDestinationQUEUEViaEnvironment() throws Exception { + public void getObjectInstanceShouldCreateAMQPDestinationQUEUEViaEnvironment() throws Exception { Hashtable environment = new Hashtable() {{ put("className", "javax.jms.Queue"); @@ -90,7 +91,7 @@ public void getObjectInstanceShouldCreateARMQDestinationQUEUEViaEnvironment() th @Test - public void getObjectInstanceShouldCreateARMQDestinationTOPICViaEnvironment() throws Exception { + public void getObjectInstanceShouldCreateAMQPDestinationTOPICViaEnvironment() throws Exception { Hashtable environment = new Hashtable() {{ put("className", "javax.jms.Topic"); @@ -115,7 +116,6 @@ public void getObjectInstanceShouldThrowNamingExceptionWhenMissingRequiredProper Hashtable environment = new Hashtable() {{ put("className", "javax.jms.Queue"); - put("destinationName", "TEST_QUEUE"); put("amqp", "true"); }}; @@ -123,7 +123,7 @@ public void getObjectInstanceShouldThrowNamingExceptionWhenMissingRequiredProper rmqObjectFactory.getObjectInstance("anything but a javax.naming.Reference", new CompositeName("java:global/jms/TestConnectionFactory"), null, environment); fail("Should have thrown a NamingException"); } catch (NamingException ne) { - assertEquals("Property [amqpExchangeName] may not be null.", ne.getMessage()); + assertEquals("Property [destinationName] may not be null.", ne.getMessage()); } }