Package org.jboss.ejb3.core.test.common

Source Code of org.jboss.ejb3.core.test.common.AbstractEJB3TestCase

/*
* 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.ejb3.core.test.common;

import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.jboss.aop.AspectManager;
import org.jboss.aop.AspectXmlLoader;
import org.jboss.aop.Domain;
import org.jboss.aop.DomainDefinition;
import org.jboss.beans.metadata.plugins.AbstractBeanMetaData;
import org.jboss.beans.metadata.plugins.AbstractDemandMetaData;
import org.jboss.beans.metadata.spi.DemandMetaData;
import org.jboss.beans.metadata.spi.SupplyMetaData;
import org.jboss.deployers.spi.DeploymentException;
import org.jboss.deployers.structure.spi.ClassLoaderFactory;
import org.jboss.deployers.structure.spi.helpers.AbstractDeploymentContext;
import org.jboss.deployers.structure.spi.helpers.AbstractDeploymentUnit;
import org.jboss.ejb3.DependencyPolicy;
import org.jboss.ejb3.DeploymentUnit;
import org.jboss.ejb3.Ejb3Deployment;
import org.jboss.ejb3.Ejb3Registry;
import org.jboss.ejb3.InitialContextFactory;
import org.jboss.ejb3.MCDependencyPolicy;
import org.jboss.ejb3.MCKernelAbstraction.AlreadyInstantiated;
import org.jboss.ejb3.cache.CacheFactoryRegistry;
import org.jboss.ejb3.cache.persistence.PersistenceManagerFactoryRegistry;
import org.jboss.ejb3.common.deployers.spi.AttachmentNames;
import org.jboss.ejb3.common.registrar.plugin.mc.Ejb3McRegistrar;
import org.jboss.ejb3.common.registrar.spi.Ejb3RegistrarLocator;
import org.jboss.ejb3.common.registrar.spi.NotBoundException;
import org.jboss.ejb3.core.resolvers.ScopedEJBReferenceResolver;
import org.jboss.ejb3.service.ServiceContainer;
import org.jboss.ejb3.session.SessionContainer;
import org.jboss.ejb3.stateful.StatefulContainer;
import org.jboss.ejb3.stateless.StatelessContainer;
import org.jboss.ejb3.test.cachepassivation.MockDeploymentUnit;
import org.jboss.ejb3.test.common.MetaDataHelper;
import org.jboss.ejb3.test.mc.bootstrap.EmbeddedTestMcBootstrap;
import org.jboss.logging.Logger;
import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeanMetaData;
import org.jboss.metadata.ejb.jboss.JBossMetaData;
import org.jboss.metadata.ejb.jboss.JBossServiceBeanMetaData;
import org.jboss.metadata.ejb.jboss.JBossSessionBeanMetaData;
import org.junit.AfterClass;
import org.junit.BeforeClass;

import static org.junit.Assert.assertEquals;

/**
* Create an environment with some basic facilities on which EJB 3 containers
* depend.
*
* @author <a href="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a>
* @version $Revision: $
*/
public abstract class AbstractEJB3TestCase
{
   private static EmbeddedTestMcBootstrap bootstrap;

   private static final Logger log = Logger.getLogger(AbstractEJB3TestCase.class);

   private static final String DOMAIN_NAME_SLSB = "Stateless Bean";

   private static final String DOMAIN_NAME_SFSB = "Stateful Bean";

   private static final String OBJECT_STORE_NAME_PM_FACTORY_REGISTRY = "EJB3PersistenceManagerFactoryRegistry";

   private static final String OBJECT_STORE_NAME_CACHE_FACTORY_REGISTRY = "EJB3CacheFactoryRegistry";

   private static InitialContext initialContext;

   private static Set<SessionContainer> allDeployedContainers = new HashSet<SessionContainer>();

   /**
    * Types of Containers Supported
    */
   enum ContainerType {
      SFSB, SLSB, SERVICE
   }

   @AfterClass
   public static void afterClass() throws Exception
   {
      Set<SessionContainer> deployedContainers = new HashSet<SessionContainer>();
      deployedContainers.addAll(allDeployedContainers);
      for (SessionContainer container : deployedContainers)
         undeployEjb(container);
      allDeployedContainers.clear();

      if (initialContext != null)
         initialContext.close();
      initialContext = null;

      URL url = Thread.currentThread().getContextClassLoader().getResource("ejb3-interceptors-aop.xml");
      if (url != null)
         AspectXmlLoader.undeployXML(url);

      if (bootstrap != null)
         bootstrap.shutdown();
      bootstrap = null;

      // Unbind Registrar
      Ejb3RegistrarLocator.unbindRegistrar();

   }

   protected static void assertCause(Throwable expected, Throwable actual)
   {
      Throwable cause = actual.getCause();
      if(cause != null)
         assertCause(expected, cause);
      else
         assertThrowable(expected, actual);
   }

   protected static void assertThrowable(Throwable expected, Throwable actual)
   {
      assertEquals(expected.toString(), actual.toString());
   }

   @BeforeClass
   public static void beforeClass() throws Exception
   {
      System.setProperty("xb.builder.useUnorderedSequence", "true");
     
      // FIXME: weirdness in InitialContextFactory (see EJBTHREE-1097)
      InitialContextFactory.close(null, null);

      bootstrap = EmbeddedTestMcBootstrap.createEmbeddedMcBootstrap();

      // Bind Registrar
      if (!Ejb3RegistrarLocator.isRegistrarBound())
      {
         Ejb3RegistrarLocator.bindRegistrar(new Ejb3McRegistrar(bootstrap.getKernel()));
      }

      deploy("namingserver-beans.xml");
      deploy("transactionmanager-beans.xml");
      deploy("mocktimerservice-beans.xml");
      deploy("servicecontainer-beans.xml");
      deploy("statefulcontainer-beans.xml");
      deploy("statelesscontainer-beans.xml");
      deploy("connector-beans.xml");
      deploy("container-beans.xml");

      // TODO: AspectDeployment
      URL url = Thread.currentThread().getContextClassLoader().getResource("ejb3-interceptors-aop.xml");
      if (url == null)
         throw new IllegalStateException("Can't find ejb3-interceptors-aop.xml on class loader "
               + Thread.currentThread().getContextClassLoader());
      AspectXmlLoader.deployXML(url);

      initialContext = new InitialContext();
   }

   protected static SessionContainer container(final String containerName)
   {
      for (SessionContainer container : allDeployedContainers)
      {
         if (container.getName().equals(containerName))
            return container;
      }
      throw new IllegalArgumentException("Can't find container " + containerName);
   }

   protected static void deploy(String resourceName)
   {
      URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
      if (url == null)
         throw new IllegalArgumentException("Can't find a resource named '" + resourceName + "'");
      assert bootstrap != null : "Can't deploy a resource, bootstrap is null";
      bootstrap.deploy(url);
   }

   protected static EmbeddedTestMcBootstrap getBootstrap()
   {
      return bootstrap;
   }

   protected static Domain getDomain(String domainName)
   {
      DomainDefinition domainDef = AspectManager.instance().getContainer(domainName);
      if (domainDef == null)
         throw new IllegalArgumentException("No such domain '" + domainName + "'");
      return (Domain) domainDef.getManager();
   }

   protected static InitialContext getInitialContext()
   {
      return initialContext;
   }

   /**
    * Creates and deploys a Session EJB represented by the specified implementation classes
    *
    * @param beanImplementationClasses
    * @return
    * @throws DeploymentException
    */
   public static Collection<SessionContainer> deploySessionEjbs(Class<?>... beanImplementationClasses) throws DeploymentException
   {
      // Initialize
      Collection<SessionContainer> containers = new HashSet<SessionContainer>();

      // Obtain TCL
      ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
      {
         public ClassLoader run()
         {
            return Thread.currentThread().getContextClassLoader();
         }
      });

      AbstractDeploymentUnit deploymentUnit = new AbstractDeploymentUnit(new AbstractDeploymentContext("test", ""));
      deploymentUnit.createClassLoader(new ClassLoaderFactory() {
         public ClassLoader createClassLoader(org.jboss.deployers.structure.spi.DeploymentUnit unit) throws Exception
         {
            return Thread.currentThread().getContextClassLoader();
         }

         public void removeClassLoader(org.jboss.deployers.structure.spi.DeploymentUnit unit) throws Exception
         {
         }
      });
      DeploymentUnit unit = new MockDeploymentUnit(deploymentUnit);
      Ejb3Deployment deployment = new MockEjb3Deployment(unit, deploymentUnit);

      deployment.setEJBReferenceResolver(new ScopedEJBReferenceResolver());
     
      /*
       * Create Metadata
       */

      // Create metadata
      JBossMetaData jbossMetaData = MetaDataHelper.getMetaDataFromBeanImplClasses(beanImplementationClasses);

      unit.addAttachment(AttachmentNames.PROCESSED_METADATA, jbossMetaData);
     
      // Iterate through each EJB
      for (JBossEnterpriseBeanMetaData beanMetaData : jbossMetaData.getEnterpriseBeans())
      {

         // Ensure a Session Bean
         assert beanMetaData.isSession() || beanMetaData.isService() : "The specified EJB must be a Session Bean or a Service Bean";

         // Cast
         JBossSessionBeanMetaData smd = (JBossSessionBeanMetaData) beanMetaData;

         /*
          * Determine type
          */

         // Initialize as SLSB
         ContainerType sessionType = ContainerType.SLSB;

         // Set as SFSB if stateful
         if (smd.isStateful())
         {
            sessionType = ContainerType.SFSB;
         }
         else if (beanMetaData.isService())
            sessionType = ContainerType.SERVICE;

         // Ensure jndi.properties is accessible
         log.info("Found: " + cl.getResource("jndi.properties"));

         // Obtain properties required of container construction
         String beanClassname = smd.getEjbClass();
         Domain domain = getDomain(sessionType.equals(ContainerType.SLSB)
               ? AbstractEJB3TestCase.DOMAIN_NAME_SLSB
               : AbstractEJB3TestCase.DOMAIN_NAME_SFSB);
         Hashtable<?, ?> ctxProperties = null;
        
         // Is SFSB, manually set a PM Factory Registry and Cache Factory
         //TODO C'mon, here?  Much better elsewhere.
         if (sessionType.equals(ContainerType.SFSB))
         {
            // Lookup Factory Registries in MC
            PersistenceManagerFactoryRegistry registry = Ejb3RegistrarLocator.locateRegistrar().lookup(
                  AbstractEJB3TestCase.OBJECT_STORE_NAME_PM_FACTORY_REGISTRY, PersistenceManagerFactoryRegistry.class);
            CacheFactoryRegistry cacheFactoryRegistry = Ejb3RegistrarLocator.locateRegistrar().lookup(
                  AbstractEJB3TestCase.OBJECT_STORE_NAME_CACHE_FACTORY_REGISTRY, CacheFactoryRegistry.class);

            // Set on the deployment
            deployment.setPersistenceManagerFactoryRegistry(registry);
            deployment.setCacheFactoryRegistry(cacheFactoryRegistry);
         }

         // Create a Session Container
         SessionContainer container = instanciateContainer(sessionType, cl, beanClassname, smd.getEjbName(), domain,
               ctxProperties, deployment, smd);

         // Deploy and register
         registerContainer(container);
         containers.add(container);

      }

      // make sure the containers are available through lookup
      for(SessionContainer container : containers)
      {
         try
         {
            bootstrap.lookup(container.getObjectName().getCanonicalName(), Object.class);
         }
         catch (RuntimeException e)
         {
            throw e;
         }
         catch (Error e)
         {
            throw e;
         }
         catch (Throwable t)
         {
            throw new RuntimeException(t);
         }
      }
      // Return
      return containers;
   }

   /**
    * Creates and deploys a Session EJB represented by the specified implementation class
    *
    * @param beanImplementationClass
    * @return
    * @throws DeploymentException
    */
   public static SessionContainer deploySessionEjb(Class<?> beanImplementationClass) throws DeploymentException
   {
      Collection<SessionContainer> containers = deploySessionEjbs(new Class<?>[]
      {beanImplementationClass});
      assert containers.size() == 1 : "Was only expected one " + SessionContainer.class.getSimpleName()
            + " from bean impl class: " + beanImplementationClass;
      return containers.iterator().next();
   }

   private static void install(String name, Object service, DependencyPolicy dependencies) throws Exception
   {
      AbstractBeanMetaData bean = new AbstractBeanMetaData(name, service.getClass().getName());
      bean.setConstructor(new AlreadyInstantiated(service));
      MCDependencyPolicy policy = (MCDependencyPolicy) dependencies;
      bean.setDepends(policy.getDependencies());
      bean.setDemands(policy.getDemands());
      bean.setSupplies(policy.getSupplies());
      log.info("installing bean: " + name);
      log.info("  with dependencies:");
      for (Object obj : policy.getDependencies())
      {
         Object msgObject = obj;
         if (obj instanceof AbstractDemandMetaData)
         {
            msgObject = ((AbstractDemandMetaData)obj).getDemand();
         }
         log.info("\t" + msgObject);
      }
      log.info("  and demands:");
      for(DemandMetaData dmd : policy.getDemands())
      {
         log.info("\t" + dmd.getDemand());
      }
      log.info("  and supplies:");
      for(SupplyMetaData smd : policy.getSupplies())
      {
         log.info("\t" + smd.getSupply());
      }
      try
      {
         bootstrap.getKernel().getController().install(bean);
      }
      catch(Throwable t)
      {
         if(t instanceof Error)
            throw (Error) t;
         if(t instanceof RuntimeException)
            throw (RuntimeException) t;
         throw (Exception) t;
      }
   }
   /**
    * Instanciates the appropriate SessionContainer based on the specified arguments and returns it
    * 
    * @param type
    * @param loader
    * @param beanClassName
    * @param ejbName
    * @param domain
    * @param ctxProperties
    * @param deployment
    * @param md
    * @return
    */
   private static SessionContainer instanciateContainer(ContainerType type, ClassLoader loader, String beanClassName,
         String ejbName, Domain domain, Hashtable<?, ?> ctxProperties, Ejb3Deployment deployment,
         JBossSessionBeanMetaData md)
   {
      // Initialize
      SessionContainer container = null;

      /*
       * Instanciate the Container, depending upon the type specified
       */
      switch (type)
      {
         case SERVICE :
            try
            {
               domain = getDomain("Service Bean");
               container = new ServiceContainer(null, loader, beanClassName, ejbName, domain, ctxProperties,
                     deployment, (JBossServiceBeanMetaData) md);
            }
            catch (ClassNotFoundException cnfe)
            {
               throw new RuntimeException("Could not create SLSB Container for " + beanClassName, cnfe);
            }
            break;
         case SFSB :
            try
            {
               container = new StatefulContainer(loader, beanClassName, ejbName, domain, ctxProperties, deployment, md);
            }
            catch (ClassNotFoundException cnfe)
            {
               throw new RuntimeException("Could not create SLSB Container for " + beanClassName, cnfe);
            }
            break;
         case SLSB :
            try
            {
               container = new StatelessContainer(loader, beanClassName, ejbName, domain, ctxProperties, deployment, md);
            }
            catch (ClassNotFoundException cnfe)
            {
               throw new RuntimeException("Could not create SLSB Container for " + beanClassName, cnfe);
            }
            break;
         default :
            throw new UnsupportedOperationException("Only SFSB and SLSB currently supported");
      }

      // Return
      return container;
   }

   protected static <T> T lookup(String name, Class<T> type) throws NamingException
   {
      return type.cast(getInitialContext().lookup(name));
   }

   /**
    * Deploys, registers the specified Session Container
    *
    * @param beanImplementationClass
    * @return
    * @throws DeploymentException
    */
   private static SessionContainer registerContainer(SessionContainer container) throws DeploymentException
   {
      //FIXME
      // Typically these steps are done by Ejb3Deployment
      container.instantiated(); //TODO: Wickeness
      container.processMetadata();
      Ejb3Registry.register(container);

      // Add as one of the deployed containers here
      allDeployedContainers.add(container);

      // Register the Container in ObjectStore (MC) - will also invoke lifecycle
      String containerName = container.getObjectName().getCanonicalName();
      try
      {
         install(containerName, container, container.getDependencyPolicy());
      }
      catch(Exception e)
      {
         throw new DeploymentException(e);
      }
      // Return
      return container;
   }

   /**
    * Undeploys the specified Container
    *
    * @param container
    */
   public static void undeployEjb(SessionContainer container)
   {
      // Igonre a null container (maybe deployment did not succeed)
      if (container == null)
         return;
      if (!allDeployedContainers.contains(container))
      {
         return;
      }

      unregisterContainer(container);

   }

   private static void unregisterContainer(SessionContainer container)
   {
      // Unbind and call appropriate lifecycle events
      try
      {
         Ejb3RegistrarLocator.locateRegistrar().unbind(container.getObjectName().getCanonicalName());
      }
      catch (NotBoundException nbe)
      {
         // Ignore
      }
      Ejb3Registry.unregister(container);
      allDeployedContainers.remove(container);
   }
}
TOP

Related Classes of org.jboss.ejb3.core.test.common.AbstractEJB3TestCase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.