/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.naming.remote; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.URI; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import javax.naming.Binding; import javax.naming.CompositeName; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.LinkRef; import javax.naming.Name; import javax.naming.NameClassPair; import javax.naming.NameNotFoundException; import javax.naming.NamingEnumeration; import javax.naming.Reference; import javax.naming.StringRefAddr; import javax.naming.spi.ObjectFactory; import org.jboss.ejb.client.ContextSelector; import org.jboss.ejb.client.EJBClientContext; import org.jboss.naming.remote.client.InitialContextFactory; import org.jboss.naming.remote.client.RemoteContext; import org.jboss.naming.remote.protocol.IoFutureHelper; import org.jboss.naming.remote.server.RemoteNamingService; import org.jboss.remoting3.Connection; import org.jboss.remoting3.Endpoint; import org.jboss.remoting3.Remoting; import org.jboss.remoting3.remote.RemoteConnectionProviderFactory; import org.jboss.remoting3.spi.NetworkServerProvider; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.xnio.IoFuture; import org.xnio.OptionMap; import org.xnio.Options; import org.xnio.Xnio; import javax.naming.Binding; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.LinkRef; import javax.naming.NameClassPair; import javax.naming.NameNotFoundException; import javax.naming.NamingEnumeration; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.URI; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.xnio.Options.SSL_ENABLED; /** * @author John Bailey */ public class ClientConnectionTest { private static RemoteNamingService server; private static Context remoteContext; private static final Context localContext = new MockContext(); @BeforeClass public static void beforeClass() throws Exception { final Xnio xnio = Xnio.getInstance(); final Endpoint endpoint = Remoting.createEndpoint("RemoteNaming", xnio, OptionMap.EMPTY); endpoint.addConnectionProvider("remote", new RemoteConnectionProviderFactory(), OptionMap.EMPTY); final NetworkServerProvider nsp = endpoint.getConnectionProviderInterface("remote", NetworkServerProvider.class); final SocketAddress bindAddress = new InetSocketAddress("localhost", 7999); final OptionMap serverOptions = TestUtils.createOptionMap(); nsp.createServer(bindAddress, serverOptions, new TestUtils.DefaultAuthenticationHandler(), null); server = new RemoteNamingService(localContext, Executors.newFixedThreadPool(10)); server.start(endpoint); Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName()); env.put(Context.PROVIDER_URL, "remote://localhost:7999"); env.put("jboss.naming.client.ejb.context", "false"); remoteContext = new InitialContext(env); } @AfterClass public static void afterClass() throws Exception { remoteContext.close(); server.stop(); } @Test public void testLookup() throws Exception { localContext.bind("test", "TestValue"); assertEquals("TestValue", remoteContext.lookup("test")); localContext.unbind("test"); } @Test public void testLookupNotFound() throws Exception { try { remoteContext.lookup("test"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException expected) { } } @Test public void testLookupContext() throws Exception { localContext.createSubcontext("test"); try { final Object result = remoteContext.lookup("test"); assertNotNull(result); assertTrue(result instanceof RemoteContext); } finally { localContext.destroySubcontext("test"); } } @Test public void testLookupInSubContext() throws Exception { localContext.createSubcontext("test").bind("nested", "TestValue"); try { final Object result = remoteContext.lookup("test"); assertNotNull(result); assertTrue(result instanceof RemoteContext); assertEquals("TestValue", Context.class.cast(result).lookup("nested")); } finally { localContext.destroySubcontext("test"); } } @Test public void testLookupNested() throws Exception { localContext.createSubcontext("test").bind("nested", "TestValue"); try { assertEquals("TestValue", remoteContext.lookup("test/nested")); } finally { localContext.destroySubcontext("test"); } } @Test public void testLookupReference() throws Exception { final Name name = new CompositeName("test"); final Reference reference = new Reference(String.class.getName(), new StringRefAddr("blah", "test"), TestObjectFactory.class.getName(), null); try { localContext.bind(name, reference); final Object result = remoteContext.lookup(name); assertEquals("test", result); } finally { localContext.unbind(name); } } public static class TestObjectFactory implements ObjectFactory { @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception { return ((Reference) obj).get(0).getContent(); } } @Test public void testLookupLinkRef() throws Exception { try { localContext.bind("test", "testValue"); localContext.bind("link", new LinkRef("./test")); assertEquals("testValue", remoteContext.lookup("link")); } finally { localContext.unbind("test"); localContext.unbind("link"); } } @Test public void testBind() throws Exception { remoteContext.bind("test", "TestValue"); assertEquals("TestValue", localContext.lookup("test")); localContext.unbind("test"); } @Test public void testBindNested() throws Exception { localContext.createSubcontext("test"); remoteContext.bind("test/nested", "TestValue"); assertEquals("TestValue", localContext.lookup("test/nested")); localContext.destroySubcontext("test"); } @Test public void testBindInvalidContext() throws Exception { try { remoteContext.bind("test/nested", "TestValue"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException expected) { } } @Test public void testRebind() throws Exception { localContext.bind("test", "InitialValue"); remoteContext.rebind("test", "TestValue"); assertEquals("TestValue", localContext.lookup("test")); localContext.unbind("test"); } @Test public void testRebindNested() throws Exception { localContext.createSubcontext("test"); localContext.bind("test/nested", "Initial"); remoteContext.rebind("test/nested", "TestValue"); assertEquals("TestValue", localContext.lookup("test/nested")); localContext.destroySubcontext("test"); } @Test public void testRebindInvalidContext() throws Exception { try { remoteContext.rebind("test/nested", "TestValue"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException expected) { } } @Test public void testList() throws Exception { localContext.bind("test1", "TestValue1"); localContext.bind("test2", new Object()); localContext.bind("test3", "TestValue3"); localContext.bind("test4", "TestValue4"); localContext.createSubcontext("test5"); final NamingEnumeration<NameClassPair> entries = remoteContext.list("test"); final Map<String, String> expected = new HashMap<String, String>(); expected.put("test1", String.class.getName()); expected.put("test2", Object.class.getName()); expected.put("test3", String.class.getName()); expected.put("test4", String.class.getName()); expected.put("test5", Context.class.getName()); while (entries.hasMore()) { final NameClassPair pair = entries.next(); assertTrue("Unexpected pair: " + pair.getName(), expected.containsKey(pair.getName())); assertEquals(expected.get(pair.getName()), pair.getClassName()); expected.remove(pair.getName()); } assertTrue(expected.isEmpty()); localContext.unbind("test1"); localContext.unbind("test2"); localContext.unbind("test3"); localContext.unbind("test4"); localContext.unbind("test5"); } @Test public void testListBindings() throws Exception { localContext.bind("test1", "TestValue1"); final Object value2 = new Integer(1); localContext.bind("test2", value2); localContext.bind("test3", "TestValue3"); localContext.bind("test4", "TestValue4"); final Context context = localContext.createSubcontext("test5"); final NamingEnumeration<Binding> entries = remoteContext.listBindings(""); final Map<String, Object> expected = new HashMap<String, Object>(); expected.put("test1", "TestValue1"); expected.put("test2", value2); expected.put("test3", "TestValue3"); expected.put("test4", "TestValue4"); expected.put("test5", context); while (entries.hasMore()) { final Binding binding = entries.next(); assertTrue("Unexpected pair: " + binding.getName(), expected.containsKey(binding.getName())); if (!binding.getClassName().equals(Context.class.getName())) { assertEquals(expected.get(binding.getName()), binding.getObject()); } expected.remove(binding.getName()); } assertTrue(expected.isEmpty()); localContext.unbind("test1"); localContext.unbind("test2"); localContext.unbind("test3"); localContext.unbind("test4"); localContext.unbind("test5"); } @Test public void testLookupFromListBindings() throws Exception { localContext.createSubcontext("test").bind("nested", "TestValue"); final NamingEnumeration<Binding> entries = remoteContext.listBindings(""); assertTrue(entries.hasMore()); final Binding binding = entries.next(); assertEquals("test", binding.getName()); assertEquals(Context.class.getName(), binding.getClassName()); assertEquals("TestValue", Context.class.cast(binding.getObject()).lookup("nested")); assertFalse(entries.hasMore()); localContext.unbind("test"); } @Test public void testUnbind() throws Exception { localContext.bind("test", "TestValue1"); remoteContext.unbind("test"); try { localContext.lookup("test"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException e) { } } @Test public void testUnbindNotFound() throws Exception { try { remoteContext.unbind("test"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException e) { } } @Test public void testRename() throws Exception { localContext.bind("test", "TestValue1"); remoteContext.rename("test", "test2"); try { localContext.lookup("test"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException e) { } assertEquals("TestValue1", localContext.lookup("test2")); localContext.unbind("test2"); } @Test public void testRenameNotFound() throws Exception { try { remoteContext.rename("test", "test2"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException e) { } } @Test public void testCreateSubcontext() throws Exception { remoteContext.createSubcontext("test"); assertTrue(localContext.lookup("test") instanceof Context); localContext.unbind("test"); } @Test public void testDestroySubcontext() throws Exception { localContext.createSubcontext("test"); remoteContext.destroySubcontext("test"); try { remoteContext.lookup("test"); fail("Should have thrown NameNotFound"); } catch (NameNotFoundException e) { } } @Test public void testLookupLink() throws Exception { localContext.bind("test", "testValue"); localContext.bind("link", new LinkRef("./test")); assertTrue(remoteContext.lookupLink("link") instanceof LinkRef); localContext.unbind("test"); localContext.unbind("link"); } @Test public void testWithExistingEndpoint() throws Exception { final Xnio xnio = Xnio.getInstance(); final Endpoint endpoint = Remoting.createEndpoint("RemoteNaming", xnio, OptionMap.EMPTY); endpoint.addConnectionProvider("remote", new RemoteConnectionProviderFactory(), OptionMap.create(SSL_ENABLED, false)); final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName()); env.put(Context.PROVIDER_URL, "remote://localhost:7999"); env.put(InitialContextFactory.ENDPOINT, endpoint); final Context context = new InitialContext(env); localContext.bind("test", "TestValue"); assertEquals("TestValue", context.lookup("test")); localContext.unbind("test"); endpoint.close(); } @Test public void testWithExistingConnection() throws Exception { final Xnio xnio = Xnio.getInstance(); final Endpoint endpoint = Remoting.createEndpoint("RemoteNaming", xnio, OptionMap.EMPTY); endpoint.addConnectionProvider("remote", new RemoteConnectionProviderFactory(), OptionMap.create(SSL_ENABLED, false)); final IoFuture<Connection> futureConnection = endpoint.connect(new URI("remote://localhost:7999"), OptionMap.create(Options.SASL_POLICY_NOANONYMOUS, false), new TestUtils.AnonymousCallbackHandler()); final Connection connection = IoFutureHelper.get(futureConnection, 1000, TimeUnit.MILLISECONDS); final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName()); env.put(InitialContextFactory.CONNECTION, connection); final Context context = new InitialContext(env); localContext.bind("test", "TestValue"); assertEquals("TestValue", context.lookup("test")); localContext.unbind("test"); endpoint.close(); } }