/* * JBoss, Home of Professional Open Source. * Copyright 2012, 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.ejb; import org.jboss.ejb.client.EJBClient; import org.jboss.ejb.client.StatelessEJBLocator; import org.jboss.logging.Logger; import org.jboss.naming.remote.MockContext; import org.jboss.naming.remote.TestUtils; import org.jboss.naming.remote.common.ejb.DummyEJBServer; import org.jboss.naming.remote.common.ejb.EchoBean; import org.jboss.naming.remote.common.ejb.EchoRemote; import org.jboss.naming.remote.server.RemoteNamingService; 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.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.xnio.OptionMap; import org.xnio.Xnio; import javax.naming.Context; import javax.naming.InitialContext; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Properties; import java.util.concurrent.Executors; /** * Tests that invocations on EJB proxies via remote naming lookup works as expected * * @author Jaikiran Pai */ public class EJBInvocationTestCase { private static final Logger logger = Logger.getLogger(EJBInvocationTestCase.class); private static RemoteNamingService server; private static DummyEJBServer dummyEJBServer; 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); // register the EJB server dummyEJBServer = new DummyEJBServer(endpoint); dummyEJBServer.start(); } @AfterClass public static void afterClass() throws Exception { dummyEJBServer.stop(); server.stop(); } @Before public void beforeTest() { dummyEJBServer.register("my-app", "my-module", "", EchoBean.class.getSimpleName(), new EchoBean()); } @After public void afterTest() { dummyEJBServer.unregister("my-app", "my-module", "", EchoBean.class.getSimpleName()); } /** * Tests that a remote naming context created by using <code>jboss.naming.ejb.context=true</code> can be used * to do EJB lookup and invocations. * * @throws Exception */ @Test public void testEJBInvocation() throws Exception { final StatelessEJBLocator<EchoRemote> statelessEJBLocator = new StatelessEJBLocator<EchoRemote>(EchoRemote.class, "my-app", "my-module", EchoBean.class.getSimpleName(), ""); final EchoRemote bean = EJBClient.createProxy(statelessEJBLocator); final String jndiName = "ejb-invocation-test"; localContext.bind(jndiName, bean); 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("jboss.naming.client.ejb.context", true); final Context context = new InitialContext(env); try { final Object returnedProxy = context.lookup(jndiName); Assert.assertTrue("Object returned by remote naming lookup: " + returnedProxy + " is not an EJB proxy", EJBClient.isEJBProxy(returnedProxy)); // make sure the proxy is of the business interface type Assert.assertTrue("EJB proxy returned by remote naming lookup is not of type: " + EchoRemote.class, returnedProxy instanceof EchoRemote); // invoke on the bean proxy final String message = "Gangnam Style!!!"; final String echo = ((EchoRemote) returnedProxy).echo(message); Assert.assertEquals("Unexpected echo message from the EJB proxy returned by remote naming lookup", message, echo); } finally { context.close(); localContext.unbind(jndiName); } } /** * Tests that a remote naming context created by using <code>jboss.naming.ejb.context=false</code> fails * when used for EJB invocations * * @throws Exception */ @Test public void testEJBInvocationWithoutEJBClientContext() throws Exception { final StatelessEJBLocator<EchoRemote> statelessEJBLocator = new StatelessEJBLocator<EchoRemote>(EchoRemote.class, "my-app", "my-module", EchoBean.class.getSimpleName(), ""); final EchoRemote bean = EJBClient.createProxy(statelessEJBLocator); final String jndiName = "ejb-invocation-test-without-ejb-client-context"; localContext.bind(jndiName, bean); 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("jboss.naming.client.ejb.context", false); final Context context = new InitialContext(env); try { final Object returnedProxy = context.lookup(jndiName); Assert.assertTrue("Object returned by remote naming lookup: " + returnedProxy + " is not an EJB proxy", EJBClient.isEJBProxy(returnedProxy)); // make sure the proxy is of the business interface type Assert.assertTrue("EJB proxy returned by remote naming lookup is not of type: " + EchoRemote.class, returnedProxy instanceof EchoRemote); // invoke on the bean proxy. MUST fail since the EJB client context isn't setup for this JNDI context final String message = "Gangnam Style!!!"; try { final String echo = ((EchoRemote) returnedProxy).echo(message); Assert.fail("Invocation on an EJB proxy without any EJB client context was expected to fail, but it didn't"); } catch (IllegalStateException ise) { // expected logger.debug("Got the expected exception while invoking on an EJB proxy without any backing EJB client context", ise); } } finally { context.close(); localContext.unbind(jndiName); } } }