/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, 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.test.cts.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Collection; import java.util.Iterator; import java.util.Properties; import javax.ejb.EJBMetaData; import javax.ejb.Handle; import javax.ejb.HomeHandle; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import javax.transaction.UserTransaction; import junit.framework.Test; import junit.framework.TestSuite; import org.jboss.test.JBossTestCase; import org.jboss.test.JBossTestSetup; import org.jboss.test.cts.interfaces.CtsBmp; import org.jboss.test.cts.interfaces.CtsBmpHome; import org.jboss.test.cts.interfaces.UserTransactionTester; import org.jboss.test.cts.jms.ContainerMBox; import org.jboss.test.cts.keys.AccountPK; import org.jboss.test.util.jms.JMSDestinationsUtil; /** * Class BmpTest * * @author Author: kimptoc * @version $Revision: 105321 $ */ public class BmpUnitTestCase extends JBossTestCase { private ContainerMBox mbx = null; public static final String BEAN_NAME = "GuysName"; public static final String BEAN_OTHER_NAME = "OtherGuysName"; public static final String BEAN_PK_007 = "007"; /** * Constructor BmpTest * * @param name * */ public BmpUnitTestCase(String name) { super(name); } /** * Return the bean home interface. */ private CtsBmpHome getHome() throws Exception { return (CtsBmpHome)getInitialContext().lookup("ejbcts/BMPBean"); } /** * Create a bean instance. */ private CtsBmp doEjbCreate(AccountPK pk, String name) throws Exception { return getHome().create(pk, name); } /** * Method testEjbCreate * EJB 1.1 [8.3.1] p. 89 * An entity bean's home interface can define zero or more create(...) * methods. * * @throws Exception * */ public void testEjbCreate() throws Exception { getLog().debug( "**************************************************************"); getLog().debug(" testEjbCreate()"); CtsBmp bean = null; try { getLog().debug("create bean, name=" + BEAN_NAME); bean = doEjbCreate(new AccountPK(BEAN_PK_007), BEAN_NAME); } catch (Exception ex) { getLog().error("Error in bmptest", ex); fail("testEjbCreate has failed!"); } assertEquals(BEAN_NAME, bean.getPersonsName()); getLog().debug( "**************************************************************"); } /** * Method testEjbFinder * EJB 1.1 [8.3.2] p. 90 * An entity bean's home interface defines one or more finder methods, * one for each way to find and entity object or collection of entity objects * within the home. * * Test stategy: Create a bean. Use the bean that has been previously * created, and call the finder method. Make sure that * a result set is returned and that the bean returned * has the same name associated with it as the bean that * was previously created. * * @throws Exception * */ public void testEjbFinder() throws Exception { getLog().debug( "**************************************************************"); getLog().debug(" testEjbFinder()"); CtsBmp bean = null; try { CtsBmpHome home = getHome(); // First create a bean instance to find getLog().debug("Create bean, name=" + BEAN_NAME); doEjbCreate(new AccountPK(BEAN_PK_007), BEAN_NAME); getLog().debug("Find bean, name=" + BEAN_NAME); Collection clct = home.findByPersonsName(BEAN_NAME); getLog().debug("Verify result set not empty"); assertTrue(!clct.isEmpty()); getLog().debug("OK"); getLog().debug("Bean result set:"); for(Iterator itr=clct.iterator(); itr.hasNext();) { bean = (CtsBmp)itr.next(); getLog().debug("Name from Bean=" + bean.getPersonsName()); getLog().debug("Verify bean name equals: " + BEAN_NAME); assertTrue(bean.getPersonsName().trim().equals(BEAN_NAME)); getLog().debug("OK"); } } catch (Exception ex) { getLog().error("Error in bmptest", ex); fail("testEjbFinder has failed!"); } getLog().debug( "**************************************************************"); } /** * Method testEjbRemove * EJB 1.1 [8.3.3] p. 90 * * Test Strategy: * 1) Create a bean to remove. * 2) Attempt a simple remove using the remote interface. * 3) Create a bean to remove. * 4) Attempt a simple remove using the home interface and primary key. * 5) Create a bean to remove. * 6) Try to remove the instance using its handle. * 7) Try to access the instance. This should result in a * java.rmi.NoSuchObjectException * * @throws Exception */ public void testEjbRemove() throws Exception { getLog().debug( "**************************************************************"); getLog().debug(" testEjbRemove()"); CtsBmp bean = null; try { CtsBmpHome home = getHome(); AccountPK pk = new AccountPK(BEAN_PK_007); getLog().debug("Create a bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Delete with bean.remove()..."); bean.remove(); getLog().debug("OK"); getLog().debug("Recreate the bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Remove the bean using primary key..."); home.remove(pk); getLog().debug("OK"); getLog().debug("Reconstitute the bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Get Handle object..."); Handle hn = bean.getHandle( ); getLog().debug("OK"); getLog().debug("Remove the bean using the handle..."); home.remove(hn); getLog().debug("OK"); getLog().debug("Bean remove, try to use.. " + "Should get 'java.rmi.NoSuchObjectException'..." ); try { bean.getPersonsName(); } catch(java.rmi.NoSuchObjectException nsoex) { getLog().debug("OK"); } catch(Exception ex) { fail("Got Exception: expecting NoSuchObjectException" + ex.toString() ); } } catch (Exception ex) { getLog().error("Error in bmptest", ex); fail("testEjbRemove has failed!"); } getLog().debug( "**************************************************************"); } /** * Method testEjbLifeCycle * EJB 1.1 [8.4] p. 92 * * A client can get a reference to an existing entity objects * remote interface in any of the following ways: * - Receive the reference as a parameter in a method call. * - Find the entity object using a finder method defined in the EB home i/f. * - Obtain the reference from the entity objects' handle. * * @throws Exception * */ public void testEjbLifeCycle() { getLog().debug( "**************************************************************"); getLog().debug(" testEjbLifeCycle()"); CtsBmp bean = null; try { CtsBmpHome home = getHome(); AccountPK pk = new AccountPK(BEAN_PK_007); getLog().debug("Create a bean..."); doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Use a finder method to retrieve the bean..."); bean = home.findByPrimaryKey( pk ); getLog().debug("OK"); getLog().debug("Assert it is the same bean as passed to a method..." ); // Send to a method as a reference, make sure it is usable by the method assertTrue( this.gotRefOkay(bean, BEAN_NAME) ); getLog().debug("OK"); // Execute a business method getLog().debug("Calling setter as a business method..."); bean.setPersonsName(BEAN_OTHER_NAME); getLog().debug("OK"); // Get the home interface getLog().debug("Get the HOME interface..."); home = (CtsBmpHome)bean.getEJBHome(); getLog().debug("OK"); // Get the primary key getLog().debug("Get the bean's Primary Key..."); pk = (AccountPK)bean.getPrimaryKey(); getLog().debug("OK"); getLog().debug("Get the bean's handle..."); Handle hn = bean.getHandle(); getLog().debug("OK"); // Remove getLog().debug("Remove the bean..."); bean.remove(); getLog().debug("OK"); } catch (Exception ex) { getLog().error("Error in bmptest", ex); fail("testEjbCreate has failed!"); } getLog().debug( "**************************************************************"); } /** * Method testPrimaryKeyObjectIdentity * EJB 1.1 [8.5] p. 92-93 * * Every entity object has a unique identity within its home. If * two entity objects have the same home and the same primary key * they are considered identitcal. * * getPrimaryKey() always returns the same value when called one the * same entity object. * * A client can test whether two entity object references refer to the * same entity object by using the isIdentical(EBJObject) method. * Alternatively, if a client obtains two entity object references from * the same home, it can determin if they refer to the same entity by comparing * their primary keys using the 'equals' method. * * @throws Exception * */ public void testPrimaryKeyObjectIdentity() { getLog().debug( "**************************************************************"); getLog().debug(" testPrimaryKeyObjectIdentity()"); CtsBmp bean = null; CtsBmp anotherBean = null; CtsBmp differentBean = null; try { CtsBmpHome home = getHome(); AccountPK pk = new AccountPK(BEAN_PK_007); getLog().debug("Create a bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Now query based on the 'PersonsName': " + BEAN_NAME + "..."); Collection clct = home.findByPersonsName(BEAN_NAME); getLog().debug("OK"); getLog().debug("Verify result set not empty..."); assertTrue(!clct.isEmpty()); getLog().debug("OK"); getLog().debug("Bean result set:"); for (Iterator itr=clct.iterator(); itr.hasNext();) { anotherBean = (CtsBmp)itr.next(); getLog().debug("Use 'isIdentical()' to compare beans"); assertTrue(anotherBean.isIdentical(bean)); getLog().debug( "beans match..OK" ); } getLog().debug("Make a bean that doesn't match.."); AccountPK anotherPK = new AccountPK("123"); differentBean = doEjbCreate(anotherPK, "SomeOtherGuy"); getLog().debug("OK"); getLog().debug("Use 'isIdentical()' to verify different beans..."); assertTrue(!differentBean.isIdentical(bean)); getLog().debug("OK...beans are different!"); getLog().debug("Test the Primary Keys..."); AccountPK beansPK = (AccountPK)bean.getPrimaryKey(); AccountPK anotherBeansPK = (AccountPK)anotherBean.getPrimaryKey(); assertTrue(beansPK.equals(anotherBeansPK)); getLog().debug("OK...they're the same"); getLog().debug("Compare different keys..."); assertTrue(!beansPK.equals(anotherPK)); getLog().debug("OK...they're different"); getLog().debug( "**************************************************************"); } catch(Exception ex) { getLog().error("Error in bmptest", ex); fail("Caught an unknown exception: " + ex.toString() ); } } /** * Method testEjbRemoteIF * EJB 1.1 [8.6] p. 93-94 * * The javax.ejb.EJBObject I/F defines the methods that allow the client * to perform the following: * - Obtain the home interface for the entity object * - Remove the entity object * - Obtain the entity object's handle * - Obtain the entity object's primary key * * @throws Exception * */ public void testEjbRemoteIF() { getLog().debug( "**************************************************************"); getLog().debug(" testEjbRemoteIF ()"); CtsBmp bean = null; try { CtsBmpHome home = getHome(); AccountPK pk = new AccountPK(BEAN_PK_007); getLog().debug("Create a bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Obtain the HOME interface..."); home = (CtsBmpHome)bean.getEJBHome(); assertTrue(home != null); getLog().debug("OK"); getLog().debug("Obtain the HANDLE..."); Handle han = bean.getHandle(); assertTrue(han != null); getLog().debug("OK"); getLog().debug("Obtain the primary key..."); pk = (AccountPK)bean.getPrimaryKey(); assertTrue(pk != null); getLog().debug("OK"); getLog().debug("Remove the entity bean"); bean.remove(); getLog().debug("OK"); } catch(Exception ex) { getLog().error("Error in bmptest", ex); fail("Caught an unknown exception" + ex.toString()); } getLog().debug( "**************************************************************"); } /** * Method testEntityHandle * EJB 1.1 [8.7] p. 93-94 * * - Client can get handle to remote interface * - Use javax.rmi.PortableRemoteObject.narrow(...) to convert the * result of the getEJBObject(). * - An entity handle is typically implemented to be usable over a * long period of time it must be usable at least across a server * restart. * * @throws Exception * */ public void testEntityHandle() { getLog().debug( "**************************************************************"); getLog().debug(" testEntityHandle()"); CtsBmp bean = null; try { CtsBmpHome home = getHome(); AccountPK pk = new AccountPK(BEAN_PK_007); getLog().debug("Create a bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Get a Handle reference and serialize it..."); Handle beanHandle = bean.getHandle(); ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream sOut = new ObjectOutputStream(out); sOut.writeObject(beanHandle); sOut.flush(); byte[] bytes = out.toByteArray(); getLog().debug("OK"); getLog().debug("Unserialize bean handle..."); ByteArrayInputStream in = new ByteArrayInputStream(bytes); ObjectInputStream sIn = new ObjectInputStream(in); beanHandle = (Handle)sIn.readObject(); getLog().debug("OK"); getLog().debug("Use PortableRemoteObject to narrow result..."); bean = (CtsBmp)PortableRemoteObject.narrow(beanHandle.getEJBObject(), CtsBmp.class); getLog().debug("OK"); getLog().debug("Check that new reference works..."); assertTrue(bean.getPersonsName().trim().equals(BEAN_NAME)); getLog().debug("OK"); } catch(Exception ex) { getLog().error("Error in bmptest", ex); fail("Caught an unknown exeption: " + ex.toString()); } getLog().debug( "**************************************************************"); } /** Test of handle that is unmarshalled in a environment where * new InitialContext() will not work. This must use the * @throws Exception */ public void testSessionHandleNoDefaultJNDI() throws Exception { getLog().debug("+++ testSessionHandleNoDefaultJNDI()"); /* We have to establish the JNDI env by creating a InitialContext with the org.jboss.naming.NamingContextFactory. Normally this would be done during the home lookup and session creation. */ Properties homeProps = new Properties(); homeProps.setProperty("java.naming.factory.initial", "org.jboss.naming.NamingContextFactory"); InitialContext ic = new InitialContext(homeProps); CtsBmpHome home = (CtsBmpHome) ic.lookup("ejbcts/BMPBean"); AccountPK pk = new AccountPK(BEAN_PK_007); CtsBmp bean = doEjbCreate(pk, BEAN_NAME); Handle beanHandle = bean.getHandle(); ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(beanHandle); oos.flush(); byte[] bytes = out.toByteArray(); Properties sysProps = System.getProperties(); Properties newProps = new Properties(sysProps); newProps.setProperty("java.naming.factory.initial", "badFactory"); newProps.setProperty("java.naming.provider.url", "jnp://badhost:12345"); System.setProperties(newProps); try { getLog().debug("Unserialize bean handle..."); ByteArrayInputStream in = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(in); beanHandle = (Handle) ois.readObject(); bean = (CtsBmp) beanHandle.getEJBObject(); String name = bean.getPersonsName(); getLog().debug("getPersonsName: "+name); } finally { System.setProperties(sysProps); } } /** * Method testProbeContainerCallbacks */ public void testProbeContainerCallbacks() { getLog().debug( "**************************************************************"); getLog().debug(" testProbeContainerCallbacks()"); CtsBmp bean = null; try { CtsBmpHome home = getHome(); AccountPK pk = new AccountPK(BEAN_PK_007); mbx.clearMessages(); getLog().debug("Create a bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Check for set entity context, create " + "and post create messages..."); Thread.sleep(2500); // OSH: We cannot be sure that the context will be set: // If the container elects a pooled instance to use for the // new object, setEntityContext() may have been called before // we cleared the message box. //assertTrue(mbx.messageReceived(ContainerMBox.SET_ENTITY_CONTEXT_MSG)); assertTrue("Expected to receive notification of EJB_CREATE_MSG",mbx.messageReceived(ContainerMBox.EJB_CREATE_MSG)); assertTrue("Expected to receive notification of EJB_POST_CREATE_MSG",mbx.messageReceived(ContainerMBox.EJB_POST_CREATE_MSG)); getLog().debug("OK"); // Execute a business method getLog().debug("Calling setter as a business method..."); bean.setPersonsName(BEAN_OTHER_NAME); getLog().debug("OK"); // Remove getLog().debug("Remove the bean..."); bean.remove(); Thread.sleep(3000); assertTrue("Expected to receive notification of EJB_STORE_MSG",mbx.messageReceived(ContainerMBox.EJB_STORE_MSG)); assertTrue("Expected to receive notification of EJB_REMOVE_MSG",mbx.messageReceived(ContainerMBox.EJB_REMOVE_MSG)); getLog().debug("OK"); } catch (Exception ex) { getLog().error("Error in bmptest", ex); fail("testEjbCreate has failed!"); } getLog().debug( "**************************************************************"); } /** * Method testContainerObjects * EJB 1.1 [9.3] p. 127-129 * Container must implement: * - Entity EJBHome class * - Entity EJBObject class * - Handle class * - HomeHandle class * - Meta-data class */ public void testContainerObjects() { getLog().debug( "**************************************************************"); getLog().debug(" testContainerObjects()"); CtsBmp bean = null; try { CtsBmpHome home = getHome(); AccountPK pk = new AccountPK(BEAN_PK_007); mbx.clearMessages(); getLog().debug("Create a bean..."); bean = doEjbCreate(pk, BEAN_NAME); getLog().debug("OK"); getLog().debug("Get HomeHandle..." ); HomeHandle homeHan = home.getHomeHandle(); assertTrue(homeHan != null); getLog().debug("OK"); getLog().debug("Get another home from the HomeHandle..."); CtsBmpHome anotherHome = (CtsBmpHome)homeHan.getEJBHome(); assertTrue(anotherHome != null); getLog().debug("OK"); getLog().debug("Get the Meta-data object..."); EJBMetaData md = anotherHome.getEJBMetaData(); assertTrue(md != null); getLog().debug("OK"); getLog().debug("Probe the Meta-data object:"); String homeInterface = md.getHomeInterfaceClass().getName(); String primaryKey = md.getPrimaryKeyClass().getName(); String remoteInterface = md.getRemoteInterfaceClass().getName(); getLog().debug(" Home Interface : " + homeInterface); getLog().debug(" PrimaryKey : " + primaryKey); getLog().debug(" Remote Interface: " + remoteInterface); assertTrue(homeInterface.equals("org.jboss.test.cts.interfaces.CtsBmpHome")); assertTrue(primaryKey.equals("org.jboss.test.cts.keys.AccountPK")); assertTrue(remoteInterface.equals("org.jboss.test.cts.interfaces.CtsBmp")); getLog().debug("Meta-data OK"); getLog().debug("Check isSession()==false ..."); assertTrue(!md.isSession()); getLog().debug("OK"); getLog().debug("Check isStatelessSession()==false ..."); assertTrue(!md.isStatelessSession()); getLog().debug("OK"); getLog().debug("Test EJBHome.remove(PrimaryKey)"); anotherHome.remove(pk); getLog().debug("OK"); } catch (Exception ex) { getLog().error("Error in bmptest", ex); fail("testEjbCreate has failed!"); } getLog().debug( "**************************************************************"); } /** * Do the UserTransaction tests. */ public void testUserTransaction() throws Exception { getLog().debug( "**************************************************************"); getLog().debug(" testUserTransaction()"); CtsBmpHome home = getHome(); UserTransaction ut; getLog().debug("Obtain UserTransaction..."); Object o = new InitialContext().lookup("UserTransaction"); ut = (UserTransaction)PortableRemoteObject.narrow(o, UserTransaction.class); assertTrue(ut != null); getLog().debug("OK"); getLog().debug("Do UserTransaction tests..."); UserTransactionTester utt = new UserTransactionTester(home, ut); assertTrue(ut != null); assertTrue(utt.runAllTests()); getLog().debug("Ok"); getLog().debug( "**************************************************************"); } // Used to test passing a Entity bean as a parameter. // OSH: ??? This just calls a method on the bean ??? private boolean gotRefOkay(CtsBmp bean, String expectedName) { boolean retVal = false; try { getLog().debug(expectedName + "==" + bean.getPersonsName()+"?"); retVal = (bean.getPersonsName().equals(expectedName)); } catch(Exception ex) { getLog().debug("Unknown Exception : " + ex.toString() ); } return retVal; } //do the mbox setup/teardown for each test separately protected void setUp() throws Exception { super.setUp(); getLog().debug("Build Container MBX for BMP"); mbx = new ContainerMBox(); getLog().debug("Initialize to empty BMP table."); CtsBmpHome home = getHome(); Collection clct = home.findAll(); if (clct.size() != 0) { getLog().debug("Removing " + clct.size() + " old beans."); for (Iterator itr=clct.iterator(); itr.hasNext();) { CtsBmp bean = (CtsBmp)itr.next(); bean.remove(); } getLog().debug("Removal done."); } } protected void tearDown() throws Exception { try { mbx.close(); } catch (Exception ignoredBecauseProblemsWillBeHighlightedAsTestFailures) {} } //deploy the cts.jar once for the suite. public static Test suite() throws Exception { return new JBossTestSetup(new TestSuite(BmpUnitTestCase.class)) { public void setUp() throws Exception { super.setUp(); JMSDestinationsUtil.setupBasicDestinations(); deploy("cts.jar"); } public void tearDown() throws Exception { undeploy("cts.jar"); JMSDestinationsUtil.destroyDestinations(); } }; } }