/* * 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.qpid.jms.jndi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Hashtable; import java.util.Properties; import javax.jms.ConnectionFactory; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameNotFoundException; import javax.naming.NamingException; import javax.naming.OperationNotSupportedException; import org.apache.qpid.jms.JmsConnectionFactory; import org.apache.qpid.jms.JmsQueue; import org.apache.qpid.jms.JmsTopic; import org.apache.qpid.jms.test.QpidJmsTestCase; import org.junit.Test; public class JmsInitialContextFactoryTest extends QpidJmsTestCase { private JmsInitialContextFactory factory; private Context context; private Context createInitialContext(final Hashtable<Object, Object> environment) throws NamingException { factory = new JmsInitialContextFactory(); context = factory.getInitialContext(environment); assertNotNull("No context created", context); return context; } @Test public void testDefaultConnectionFactoriesPresentWithEmptyEnvironment() throws Exception { Hashtable<Object, Object> env = new Hashtable<Object, Object>(); Context ctx = createInitialContext(env); for (String factoryName : JmsInitialContextFactory.DEFAULT_CONNECTION_FACTORY_NAMES) { Object o = ctx.lookup(factoryName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsConnectionFactory.class, o.getClass()); assertEquals("Unexpected URI for returned factory", JmsConnectionFactory.getDefaultRemoteAddress(), ((JmsConnectionFactory) o).getRemoteURI()); } } @Test public void testDefaultConnectionFactoriesSeeDefaultURIUpdate() throws Exception { String updatedDefaultURI = "amqp://example.com:1234"; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.CONNECTION_FACTORY_DEFAULT_KEY_PREFIX + JmsConnectionFactory.REMOTE_URI_PROP, updatedDefaultURI); Context ctx = createInitialContext(env); for (String factoryName : JmsInitialContextFactory.DEFAULT_CONNECTION_FACTORY_NAMES) { Object o = ctx.lookup(factoryName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsConnectionFactory.class, o.getClass()); assertEquals("Unexpected URI for returned factory", updatedDefaultURI, ((JmsConnectionFactory) o).getRemoteURI()); } } @Test public void testDefaultConnectionFactorySeesFactorySpecificProperty() throws Exception { String factoryName = JmsInitialContextFactory.DEFAULT_CONNECTION_FACTORY_NAMES[0]; // lower case prefix doDefaultConnectionFactorySeesFactorySpecificPropertyTestImpl("property.connectionfactory.", factoryName); // camelCase prefix doDefaultConnectionFactorySeesFactorySpecificPropertyTestImpl("property.connectionFactory.", factoryName); } private void doDefaultConnectionFactorySeesFactorySpecificPropertyTestImpl(String propertyPrefix, String factoryName) throws Exception { String updatedClientID = _testName.getMethodName(); Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(propertyPrefix + factoryName + "." + "clientID", updatedClientID); Context ctx = createInitialContext(env); Object o = ctx.lookup(factoryName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsConnectionFactory.class, o.getClass()); assertEquals("Unexpected ClientID for returned factory", updatedClientID, ((JmsConnectionFactory) o).getClientID()); } @Test public void testDefaultConnectionFactoriesNotPresentWhenOneIsExplicitlyDefined() throws Exception { Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.CONNECTION_FACTORY_KEY_PREFIX + "myNewFactory", "amqp://example.com:1234"); Context ctx = createInitialContext(env); for (String factoryName : JmsInitialContextFactory.DEFAULT_CONNECTION_FACTORY_NAMES) { try { ctx.lookup(factoryName); fail("should have thrown exception due to name not being found"); } catch (NameNotFoundException nnfe) { // //expected } } } @Test public void testDefaultConnectionFactoriesSeeDefaultPropertyUpdate() throws Exception { String factoryName = JmsInitialContextFactory.DEFAULT_CONNECTION_FACTORY_NAMES[0]; // lower case prefix doDefaultConnectionFactorySeesDefaultPropertyUpdatePropertyTestImpl("default.connectionfactory.", factoryName); // camelCase prefix doDefaultConnectionFactorySeesDefaultPropertyUpdatePropertyTestImpl("default.connectionFactory.", factoryName); } private void doDefaultConnectionFactorySeesDefaultPropertyUpdatePropertyTestImpl(String propertyPrefix, String factoryName) throws Exception { String updatedClientID = _testName.getMethodName(); Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(propertyPrefix + "clientID", updatedClientID); Context ctx = createInitialContext(env); Object o = ctx.lookup(factoryName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsConnectionFactory.class, o.getClass()); assertEquals("Unexpected ClientID for returned factory", updatedClientID, ((JmsConnectionFactory) o).getClientID()); } @Test public void testConnectionFactoryBinding() throws Exception { String factoryName = "myNewFactory"; // lower case prefix doConnectionFactoryBindingTestImpl("connectionfactory." + factoryName, factoryName); // camelCase prefix doConnectionFactoryBindingTestImpl("connectionFactory." + factoryName, factoryName); } private void doConnectionFactoryBindingTestImpl(String environmentProperty, String factoryName) throws NamingException { String uri = "amqp://example.com:1234"; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(environmentProperty, uri); Context ctx = createInitialContext(env); Object o = ctx.lookup(factoryName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsConnectionFactory.class, o.getClass()); assertEquals("Unexpected URI for returned factory", uri, ((JmsConnectionFactory) o).getRemoteURI()); } @Test public void testConnectionFactoryBindingWithInvalidFactorySpecificProperty() throws Exception { String factoryName = "myNewFactory"; String uri = "amqp://example.com:1234"; String propertyPrefix = JmsInitialContextFactory.CONNECTION_FACTORY_PROPERTY_KEY_PREFIX; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.CONNECTION_FACTORY_KEY_PREFIX + factoryName, uri); env.put(propertyPrefix + factoryName + "." + "invalidProperty", "value"); try { createInitialContext(env); fail("Should have thrown exception"); } catch (NamingException ne) { // Expected assertTrue("Should have had a cause", ne.getCause() != null); } } @Test public void testConnectionFactoryBindingWithInvalidDefaultProperty() throws Exception { String factoryName = "myNewFactory"; String uri = "amqp://example.com:1234"; String defaultPrefix = JmsInitialContextFactory.CONNECTION_FACTORY_DEFAULT_KEY_PREFIX; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.CONNECTION_FACTORY_KEY_PREFIX + factoryName, uri); env.put(defaultPrefix + "invalidDefaultProperty", "value"); try { createInitialContext(env); fail("Should have thrown exception"); } catch (NamingException ne) { // Expected assertTrue("Should have had a cause", ne.getCause() != null); } } @Test public void testConnectionFactoryBindingUsesDefaultURIWhenEmpty() throws Exception { doConnectionFactoryBindingUsesDefaultURITestImpl(""); } @Test public void testConnectionFactoryBindingUsesDefaultURIWhenNull() throws Exception { doConnectionFactoryBindingUsesDefaultURITestImpl(""); } private void doConnectionFactoryBindingUsesDefaultURITestImpl(String uriPropertyValue) throws NamingException { String factoryName = "myNewFactory"; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.CONNECTION_FACTORY_KEY_PREFIX + factoryName, uriPropertyValue); Context ctx = createInitialContext(env); Object o = ctx.lookup(factoryName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsConnectionFactory.class, o.getClass()); assertEquals("Unexpected URI for returned factory", JmsConnectionFactory.getDefaultRemoteAddress(), ((JmsConnectionFactory) o).getRemoteURI()); } @Test public void testQueueBinding() throws Exception { String lookupName = "myLookupName"; String actualName = "myQueueName"; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.QUEUE_KEY_PREFIX + lookupName, actualName); Context ctx = createInitialContext(env); Object o = ctx.lookup(lookupName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsQueue.class, o.getClass()); assertEquals("Unexpected name for returned object", actualName, ((JmsQueue) o).getQueueName()); } @Test public void testDynamicQueueLookup() throws Exception { String actualName = "myQueueName"; String lookupName = "dynamicQueues/" + actualName; Context ctx = createInitialContext(new Hashtable<Object, Object>()); Object o = ctx.lookup(lookupName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsQueue.class, o.getClass()); assertEquals("Unexpected name for returned object", actualName, ((JmsQueue) o).getQueueName()); } @Test public void testTopicBinding() throws Exception { String lookupName = "myLookupName"; String actualName = "myTopicName"; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.TOPIC_KEY_PREFIX + lookupName, actualName); Context ctx = createInitialContext(env); Object o = ctx.lookup(lookupName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsTopic.class, o.getClass()); assertEquals("Unexpected name for returned object", actualName, ((JmsTopic) o).getTopicName()); } @Test public void testDynamicTopicLookup() throws Exception { String actualName = "myTopicName"; String lookupName = "dynamicTopics/" + actualName; Context ctx = createInitialContext(new Hashtable<Object, Object>()); Object o = ctx.lookup(lookupName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsTopic.class, o.getClass()); assertEquals("Unexpected name for returned object", actualName, ((JmsTopic) o).getTopicName()); } @Test public void testQueueBindingWithSlashInLookupName() throws Exception { String lookupName = "myLookup/Name"; String actualName = "myQueueName"; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.QUEUE_KEY_PREFIX + lookupName, actualName); Context ctx = createInitialContext(env); Object o = ctx.lookup(lookupName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsQueue.class, o.getClass()); assertEquals("Unexpected name for returned object", actualName, ((JmsQueue) o).getQueueName()); } @Test public void testTopicBindingWithMulupleSlashesInLookupName() throws Exception { String lookupName = "my/Lookup/Name"; String actualName = "myTopicName"; Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(JmsInitialContextFactory.TOPIC_KEY_PREFIX + lookupName, actualName); Context ctx = createInitialContext(env); Object o = ctx.lookup(lookupName); assertNotNull("No object returned", o); assertEquals("Unexpected class type for returned object", JmsTopic.class, o.getClass()); assertEquals("Unexpected name for returned object", actualName, ((JmsTopic) o).getTopicName()); } @Test(expected = OperationNotSupportedException.class) public void testContextPreventsUnbind() throws Exception { Hashtable<Object, Object> env = new Hashtable<Object, Object>(); Context ctx = createInitialContext(env); ctx.unbind("lookupName"); } @Test(expected = OperationNotSupportedException.class) public void testContextPreventsRebind() throws Exception { Hashtable<Object, Object> env = new Hashtable<Object, Object>(); Context ctx = createInitialContext(env); ctx.rebind("lookupName", new Object()); } @Test(expected = OperationNotSupportedException.class) public void testContextPreventsRename() throws Exception { Hashtable<Object, Object> env = new Hashtable<Object, Object>(); Context ctx = createInitialContext(env); ctx.rename("lookupName", ""); } @Test public void testContextFromProviderUrlNotFoundThrowsNamingException() throws Exception { Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(Context.PROVIDER_URL, "/does/not/exist/1234"); try { createInitialContext(env); fail("Should have thrown exception"); } catch (NamingException ne) { // Expected assertTrue("Should have had a cause", ne.getCause() != null); } } @Test public void testContextFromProviderUrlInEnvironmentMap() throws Exception { doContextFromProviderUrlInEnvironmentMapTestImpl(false); } @Test public void testContextFromProviderUrlInEnvironmentMapWithBareFilePath() throws Exception { doContextFromProviderUrlInEnvironmentMapTestImpl(true); } private void doContextFromProviderUrlInEnvironmentMapTestImpl(boolean useBareFilePath) throws IOException, FileNotFoundException, NamingException { String myFactory = "myFactory"; String myURI = "amqp://example.com:2765"; Properties properties = new Properties(); properties.put("connectionfactory." + myFactory, myURI); File f = File.createTempFile(getTestName(), ".properties"); try { FileOutputStream fos = new FileOutputStream(f); try { properties.store(fos, null); } finally { fos.close(); } Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, JmsInitialContextFactory.class.getName()); if (useBareFilePath) { env.put(Context.PROVIDER_URL, f.getAbsolutePath()); } else if(QpidJmsTestCase.IS_WINDOWS) { env.put(Context.PROVIDER_URL, "file:///" + f.getAbsolutePath()); } else { env.put(Context.PROVIDER_URL, "file://" + f.getAbsolutePath()); } InitialContext context = new InitialContext(env); ConnectionFactory factory = (ConnectionFactory) context.lookup(myFactory); assertEquals("Unexpected type of object", JmsConnectionFactory.class, factory.getClass()); assertEquals("Unexpected URI value", myURI, ((JmsConnectionFactory) factory).getRemoteURI()); context.close(); } finally { f.delete(); } } @Test public void testContextFromProviderUrlInSystemProperty() throws Exception { String myFactory = "myFactory"; String myURI = "amqp://example.com:2765"; Properties properties = new Properties(); properties.put("connectionfactory." + myFactory, myURI); File f = File.createTempFile(getTestName(), ".properties"); try { FileOutputStream fos = new FileOutputStream(f); try { properties.store(fos, null); } finally { fos.close(); } setTestSystemProperty(Context.INITIAL_CONTEXT_FACTORY, JmsInitialContextFactory.class.getName()); setTestSystemProperty(Context.PROVIDER_URL, "file://" + f.getAbsolutePath()); if(QpidJmsTestCase.IS_WINDOWS) { setTestSystemProperty(Context.PROVIDER_URL, "file:///" + f.getAbsolutePath()); } else { setTestSystemProperty(Context.PROVIDER_URL, "file://" + f.getAbsolutePath()); } InitialContext context = new InitialContext(); ConnectionFactory factory = (ConnectionFactory) context.lookup(myFactory); assertEquals("Unexpected type of object", JmsConnectionFactory.class, factory.getClass()); assertEquals("Unexpected URI value", myURI, ((JmsConnectionFactory) factory).getRemoteURI()); context.close(); } finally { f.delete(); } } }