Package org.jboss.test.messaging.tools.container

Source Code of org.jboss.test.messaging.tools.container.ServiceContainer

/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt 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.messaging.tools.container;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import javax.management.Attribute;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.spi.NamingManager;
import javax.sql.DataSource;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

import org.hsqldb.Server;
import org.hsqldb.persist.HsqlProperties;
import org.jboss.jms.jndi.JMSProviderAdapter;
import org.jboss.jms.jndi.JNDIProviderAdapter;
import org.jboss.jms.server.ServerPeer;
import org.jboss.jms.server.remoting.JMSServerInvocationHandler;
import org.jboss.logging.Logger;
import org.jboss.messaging.util.JNDIUtil;
import org.jboss.messaging.util.XMLUtil;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.ServerInvocationHandler;
import org.jboss.remoting.transport.PortUtil;
import org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory;
import org.jboss.resource.adapter.jdbc.remote.WrapperDataSourceService;
import org.jboss.resource.adapter.jms.JmsManagedConnectionFactory;
import org.jboss.resource.connectionmanager.CachedConnectionManager;
import org.jboss.resource.connectionmanager.CachedConnectionManagerMBean;
import org.jboss.resource.connectionmanager.ConnectionFactoryBindingService;
import org.jboss.resource.connectionmanager.JBossManagedConnectionPool;
import org.jboss.resource.connectionmanager.TxConnectionManager;
import org.jboss.system.Registry;
import org.jboss.system.ServiceController;
import org.jboss.system.ServiceCreator;
import org.jboss.test.messaging.tools.ServerManagement;
import org.jboss.test.messaging.tools.jboss.MBeanConfigurationElement;
import org.jboss.test.messaging.tools.jboss.ServiceDeploymentDescriptor;
import org.jboss.tm.TransactionManagerService;
import org.jboss.tm.usertx.client.ServerVMClientUserTransaction;
import org.jboss.util.id.GUID;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.arjuna.ats.arjuna.recovery.RecoveryManager;

/**
* An MBeanServer and a configurable set of services (TransactionManager,
* Remoting, etc) available for testing.
*
* @author <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
* @version <tt>$Revision: 3757 $</tt>
*
* $Id: ServiceContainer.java 3757 2008-02-21 16:34:49Z timfox $
*/
public class ServiceContainer
{
   // Constants
   // ------------------------------------------------------------------------------------
  
   private static final Logger log = Logger.getLogger(ServiceContainer.class);
  
   private static final String CONFIGURATION_FILE_NAME = "container.xml";
  
   public static final String DO_NOT_USE_MESSAGING_MARSHALLERS = "DO_NOT_USE_MESSAGING_MARSHALLERS";
  
   // Static
   // ---------------------------------------------------------------------------------------
  
   public static ObjectName SERVICE_CONTROLLER_OBJECT_NAME;
   public static ObjectName CLASS_LOADER_OBJECT_NAME;
   public static ObjectName TRANSACTION_MANAGER_OBJECT_NAME;
   public static ObjectName CACHED_CONNECTION_MANAGER_OBJECT_NAME;
  
   public static ObjectName DEFAULTDS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME;
   public static ObjectName DEFAULTDS_MANAGED_CONNECTION_POOL_OBJECT_NAME;
   public static ObjectName DEFAULTDS_CONNECTION_MANAGER_OBJECT_NAME;
   public static ObjectName DEFAULTDS_WRAPPER_DATA_SOURCE_SERVICE_OBJECT_NAME;
  
   public static ObjectName JMS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME;
   public static ObjectName JMS_MANAGED_CONNECTION_POOL_OBJECT_NAME;
   public static ObjectName JMS_CONNECTION_MANAGER_OBJECT_NAME;
   public static ObjectName JMS_CONNECTION_FACTORY_BINDING_SERVICE_OBJECT_NAME;
  
   public static ObjectName REMOTING_OBJECT_NAME;
  
   // Used only on testcases where Socket and HTTP are deployed at the same time
   public static ObjectName HTTP_REMOTING_OBJECT_NAME;
  
   public static ObjectName SERVER_PEER_OBJECT_NAME;
  
   public static String DATA_SOURCE_JNDI_NAME = "java:/DefaultDS";
   public static String TRANSACTION_MANAGER_JNDI_NAME = "java:/TransactionManager";
   public static String USER_TRANSACTION_JNDI_NAME = "UserTransaction";
   public static String JCA_JMS_CONNECTION_FACTORY_JNDI_NAME = "java:/JCAConnectionFactory";
  
   // Must match the value in remoting-http-service.xml
   public static long HTTP_CONNECTOR_CALLBACK_POLL_PERIOD = 102;
  
   // List<ObjectName>
   private List connFactoryObjectNames = new ArrayList();
  
   static
   {
      try
      {
         SERVICE_CONTROLLER_OBJECT_NAME = new ObjectName(
               "jboss.system:service=ServiceController");
         CLASS_LOADER_OBJECT_NAME = new ObjectName(
               "jboss.system:service=ClassLoader");
         TRANSACTION_MANAGER_OBJECT_NAME = new ObjectName(
               "jboss:service=TransactionManager");
         CACHED_CONNECTION_MANAGER_OBJECT_NAME = new ObjectName(
               "jboss.jca:service=CachedConnectionManager");
        
         DEFAULTDS_CONNECTION_MANAGER_OBJECT_NAME = new ObjectName(
               "jboss.jca:name=DefaultDS,service=LocalTxCM");
         DEFAULTDS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME = new ObjectName(
               "jboss.jca:name=DefaultDS,service=ManagedConnectionFactory");
         DEFAULTDS_MANAGED_CONNECTION_POOL_OBJECT_NAME = new ObjectName(
               "jboss.jca:name=DefaultDS,service=ManagedConnectionPool");
         DEFAULTDS_WRAPPER_DATA_SOURCE_SERVICE_OBJECT_NAME = new ObjectName(
               "jboss.jca:name=DefaultDS,service=DataSourceBinding");
        
         JMS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME = new ObjectName(
               "jboss.jca:service=ManagedConnectionFactory,name=JCAConnectionFactory");
         JMS_MANAGED_CONNECTION_POOL_OBJECT_NAME = new ObjectName(
               "jboss.jca:service=ManagedConnectionPool,name=JCAConnectionFactory");
         JMS_CONNECTION_MANAGER_OBJECT_NAME = new ObjectName(
               "jboss.jca:service=TxCM,name=JCAConnectionFactory");
         JMS_CONNECTION_FACTORY_BINDING_SERVICE_OBJECT_NAME = new ObjectName(
               "jboss.jca:service=ConnectionFactoryBinding,name=JCAConnectionFactory");
        
         REMOTING_OBJECT_NAME = new ObjectName(
               "jboss.messaging:service=Connector,transport=bisocket");
        
         HTTP_REMOTING_OBJECT_NAME = new ObjectName(
               "jboss.messaging:service=Connector,transport=http");
        
         SERVER_PEER_OBJECT_NAME = new ObjectName(
               "jboss.messaging:service=ServerPeer");
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }
  
   public static String getCurrentAddress() throws Exception
   {
      String currentAddress = System.getProperty("test.bind.address");
     
      if (currentAddress == null)
      {
         currentAddress = "localhost";
      }
      return currentAddress;
   }
  
   // Attributes
   // -----------------------------------------------------------------------------------
  
   private ServiceContainerConfiguration config;
  
   private TransactionManager tm;
  
   private MBeanServer mbeanServer;
   private ServiceCreator serviceCreator; // the 'creator' helps in creating and
                                          // registering XMBeans
   private InitialContext initialContext;
   private String jndiNamingFactory;
   private Server hsqldbServer;
   private RecoveryManager recoveryManager;
   private JBossManagedConnectionPool mcp;
  
   private boolean transaction;
   private boolean database;
   private boolean jca;
   private boolean remoting;
   private boolean security;
   private boolean httpConnectionFactory;
   private boolean multiplexer; // the JGroups channels multiplexer
  
   private List toUnbindAtExit;
   private String ipAddressOrHostName;
  
   // There may be many service containers on the same machine, so we need to
   // distinguish them
   // so we don't start up multiple servers with services running on the same
   // port
   private int serverIndex;
  
   // Static
   // ---------------------------------------------------------------------------------------
  
   public static Object type(MBeanInfo mbeanInfo, String attributeName,
         String valueAsString) throws Exception
   {
      MBeanAttributeInfo[] attrs = mbeanInfo.getAttributes();
      MBeanAttributeInfo attr = null;
     
      for (int i = 0; i < attrs.length; i++)
      {
         if (attrs[i].getName().equals(attributeName))
         {
            attr = attrs[i];
            break;
         }
      }
     
      if (attr == null)
      {
         throw new Exception("No such attribute: " + attributeName);
      }
     
      String type = attr.getType();
     
      if ("int".equals(type) || "java.lang.Integer".equals(type))
      {
         int i = Integer.parseInt(valueAsString);
         return new Integer(i);
      }
      else if ("long".equals(type) || "java.lang.Long".equals(type))
      {
         long l = Long.parseLong(valueAsString);
         return new Long(l);
      }
      else if ("boolean".equals(type) || "java.lang.Boolean".equals(type))
      {
         boolean b = Boolean.valueOf(valueAsString).booleanValue();
         return new Boolean(b);
      }
      else if ("java.lang.String".equals(type))
      {
         return valueAsString;
      }
      else if ("javax.management.ObjectName".equals(type))
      {
         return new ObjectName(valueAsString);
      }
      else if ("org.w3c.dom.Element".equals(type))
      {
         if (valueAsString == null)
         {
            return null;
         }
         else
         {
            return XMLUtil.stringToElement(valueAsString);
         }
      }
      else if (type.startsWith("org.jboss."))
      {
         Class interfazza = ServiceContainer.class.getClassLoader().loadClass(
               type);
         Class implementation = ServiceContainer.class.getClassLoader()
               .loadClass(valueAsString);
         return implementation.newInstance();
      }
      else if (type.startsWith("java.util.Properties"))
      {
         ByteArrayInputStream is = new ByteArrayInputStream(valueAsString
               .getBytes());
         Properties props = new Properties();
         props.load(is);
         return props;
      }
     
      throw new Exception("Don't know to handle type " + type);
     
   }
  
   // Constructors
   // ---------------------------------------------------------------------------------
  
   public ServiceContainer(String servicesToStart) throws Exception
   {
      this(servicesToStart, null);
   }
  
   public ServiceContainer(String sevicesToStart, int serverIndex)
         throws Exception
   {
      this(sevicesToStart, null, serverIndex);
   }
  
   /**
    * @param sevicesToStart -
    *           A comma separated list of services to be started. Available
    *           services: transaction, jca, database, remoting. Example:
    *           "transaction, database, remoting". "all" will start every
    *           service available. A dash in front of a service name will
    *           disable that service. Example "all,-database".
    * @param tm -
    *           specifies a specific TransactionManager instance to bind into
    *           the mbeanServer. If null, the default JBoss TransactionManager
    *           implementation will be used.
    */
   public ServiceContainer(String sevicesToStart, TransactionManager tm)
         throws Exception
   {
      this.tm = tm;
      parseConfig(sevicesToStart);
      toUnbindAtExit = new ArrayList();
      this.serverIndex = 0;
   }
  
   public ServiceContainer(String sevicesToStart, TransactionManager tm,
         int serverIndex) throws Exception
   {
      this.tm = tm;
      parseConfig(sevicesToStart);
      toUnbindAtExit = new ArrayList();
      this.serverIndex = serverIndex;
   }
  
   // Public
   // ---------------------------------------------------------------------------------------
  
   public void start() throws Exception
   {
      start(true);
   }
  
   public void start(boolean cleanDatabase) throws Exception
   {
      start(cleanDatabase, null);
   }
  
   public void start(boolean cleanDatabase,
         ServiceAttributeOverrides attrOverrides) throws Exception
   {
      try
      {
         readConfigurationFile();
        
         ipAddressOrHostName = getCurrentAddress();
         log.debug("all server sockets will be open on address "
               + ipAddressOrHostName);
        
         toUnbindAtExit.clear();
        
         jndiNamingFactory = System.getProperty("java.naming.factory.initial");
        
         // TODO: need to think more about this; if I don't do it, though,
         // bind() fails because it tries to use "java.naming.provider.url"
         try
         {
            NamingManager
                  .setInitialContextFactoryBuilder(new InVMInitialContextFactoryBuilder());
         }
         catch (IllegalStateException e)
         {
            // OK
         }
        
         Hashtable t = InVMInitialContextFactory
               .getJNDIEnvironment(serverIndex);
         System.setProperty("java.naming.factory.initial", (String) t
               .get("java.naming.factory.initial"));
         System.setProperty(Constants.SERVER_INDEX_PROPERTY_NAME, Integer
               .toString(serverIndex));
        
         initialContext = new InitialContext();
        
         System.setProperty("javax.management.builder.initial",
               "org.jboss.test.messaging.tools.container.MBeanServerBuilder");
        
         mbeanServer = MBeanServerFactory.createMBeanServer("jboss");
        
         serviceCreator = new ServiceCreator(mbeanServer);
        
         startServiceController();
        
         registerClassLoader();
        
         if (transaction)
         {
            startTransactionManager();
         }
        
         if (database)
         {
            startInVMDatabase();
         }
        
         if (jca)
         {
            startCachedConnectionManager(CACHED_CONNECTION_MANAGER_OBJECT_NAME);
           
            // DefaultDS specific
            startManagedConnectionFactory(DEFAULTDS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME);
            startManagedConnectionPool(
                  DEFAULTDS_MANAGED_CONNECTION_POOL_OBJECT_NAME,
                  DEFAULTDS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME,
                  "ByContainer");
            startConnectionManager(DEFAULTDS_CONNECTION_MANAGER_OBJECT_NAME,
                  true, true, TRANSACTION_MANAGER_OBJECT_NAME,
                  CachedConnectionManagerMBean.OBJECT_NAME,
                  DEFAULTDS_MANAGED_CONNECTION_POOL_OBJECT_NAME);
            startWrapperDataSourceService();
         }
        
         if (database && transaction && jca && cleanDatabase)
         {
            // We make sure the database is clean (only if we have all
            // dependencies the database,
            // otherwise we'll get an access error)
            deleteAllData();
         }
        
         if (remoting)
         {
            startRemoting(attrOverrides, config.getRemotingTransport(),
                  REMOTING_OBJECT_NAME);
         }
        
         if (security)
         {
            startSecurityManager();
         }
        
         if (multiplexer)
         {
            startMultiplexer();
         }
        
         loadJNDIContexts();
        
         log.debug("loaded JNDI context");
        
         String transport = config.getRemotingTransport();
        
         log.info("Remoting type: .............. "
               + (remoting ? transport : "DISABLED"));
         log.info("Clustering mode: ............ "
               + (this.isClustered() ? "CLUSTERED" : "NON-CLUSTERED"));
        
         log.debug(this + " started");
      }
      catch (Throwable e)
      {
         log.error("Failed to start ServiceContainer", e);
         throw new Exception("Failed to start ServiceContainer", e);
      }
   }
  
   public void dropTables() throws Exception
   {
      dropAllTables();
   }
  
   public void startConnectionFactories(ServiceAttributeOverrides attrOverrides)
         throws Exception
   {
      deployConnectionFactories(
            "server/default/deploy/connection-factories-service.xml",
            attrOverrides);
     
      log.info("HTTP ConnectionFactory " + httpConnectionFactory);
      if (httpConnectionFactory)
      {
         log.info("Installing HTTP connection factory");
         ServiceAttributeOverrides httpOverride = new ServiceAttributeOverrides();
         startRemoting(httpOverride, "http", HTTP_REMOTING_OBJECT_NAME);
         deployConnectionFactories("connection-factory-http.xml", attrOverrides);
      }
     
      // bind the default JMS provider
      bindDefaultJMSProvider();
      // bind the JCA ConnectionFactory
      bindJCAJMSConnectionFactory();
   }
  
   public void stopConnectionFactories() throws Exception
   {
      for (Iterator i = connFactoryObjectNames.iterator(); i.hasNext();)
      {
         try
         {
            ObjectName on = (ObjectName) i.next();
            invoke(on, "stop", new Object[0], new String[0]);
            invoke(on, "destroy", new Object[0], new String[0]);
            unregisterService(on);
         }
         catch (Exception ignore)
         {
            // If the serverpeer failed when starting up previously, then only
            // some of the
            // services may be started. The ones that didn't start will fail
            // when attempting to shut
            // them down.
            // Hence we must catch and ignore or we won't shut everything down
         }
      }
      connFactoryObjectNames.clear();
     
   }
  
   public void flushManagedConnectionPool()
   {
      mcp.flush();
   }
  
   public void stop() throws Exception
   {
      log.info("Stopping serviceconatiner");
     
      unloadJNDIContexts();
     
      stopService(REMOTING_OBJECT_NAME);
     
      if (httpConnectionFactory)
      {
         stopService(HTTP_REMOTING_OBJECT_NAME);
      }
     
      if (jca)
      {
         stopWrapperDataSourceService();
         stopConnectionManager(DEFAULTDS_CONNECTION_MANAGER_OBJECT_NAME);
         stopManagedConnectionPool(DEFAULTDS_MANAGED_CONNECTION_POOL_OBJECT_NAME);
         stopManagedConnectionFactory(DEFAULTDS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME);
         stopService(CACHED_CONNECTION_MANAGER_OBJECT_NAME);
      }
     
      stopService(TRANSACTION_MANAGER_OBJECT_NAME);
     
      if (database)
      {
         stopInVMDatabase();
      }
     
      unregisterClassLoader();
      stopServiceController();
      MBeanServerFactory.releaseMBeanServer(mbeanServer);
     
      if (security)
      {
         initialContext.unbind(MockJBossSecurityManager.TEST_SECURITY_DOMAIN);
      }
     
      cleanJNDI();
     
      initialContext.close();
     
      if (jndiNamingFactory != null)
      {
         System.setProperty("java.naming.factory.initial", jndiNamingFactory);
      }
     
      log.debug(this + " stopped");
   }
  
   public DataSource getDataSource()
   {
      DataSource ds = null;
      try
      {
         InitialContext ic = new InitialContext();
         ds = (DataSource) ic.lookup(DATA_SOURCE_JNDI_NAME);
         ic.close();
      }
      catch (Exception e)
      {
         log.error("Failed to look up DataSource", e);
      }
      return ds;
   }
  
   public TransactionManager getTransactionManager()
   {
      TransactionManager tm = null;
      try
      {
         InitialContext ic = new InitialContext();
         tm = (TransactionManager) ic.lookup(TRANSACTION_MANAGER_JNDI_NAME);
         ic.close();
      }
      catch (Exception e)
      {
         log.error("Failed to look up transaction manager", e);
      }
      return tm;
   }
  
   public UserTransaction getUserTransaction() throws Exception
   {
      return (UserTransaction) initialContext
            .lookup(USER_TRANSACTION_JNDI_NAME);
   }
  
   public Object getService(ObjectName on) throws Exception
   {
      return mbeanServer
            .invoke(on, "getInstance", new Object[0], new String[0]);
   }
  
   public String getPersistenceConfigFile(boolean clustered)
   {
      String databaseName = getDatabaseName();
     
      return "server/default/deploy/" + databaseName
            + "-persistence-service.xml";
   }
  
   public Properties getPersistenceManagerSQLProperties() throws Exception
   {
      String persistenceConfigFile = getPersistenceConfigFile(false);
      log.info("Persistence config file: .... " + persistenceConfigFile);
     
      MBeanConfigurationElement persistenceManagerConfig = ServiceConfigHelper
            .loadServiceConfiguration(persistenceConfigFile,
                  "PersistenceManager");
     
      String props = persistenceManagerConfig
            .getAttributeValue("SqlProperties");
     
      if (props != null)
      {
         ByteArrayInputStream is = new ByteArrayInputStream(props.getBytes());
        
         Properties sqlProperties = new Properties();
        
         sqlProperties.load(is);
        
         return sqlProperties;
      }
      else
      {
         return null;
      }
   }
  
   public Properties getPostOfficeSQLProperties() throws Exception
   {
      String persistenceConfigFile = getPersistenceConfigFile(true);
      log.info("Persistence config file: .... " + persistenceConfigFile);
     
      MBeanConfigurationElement postOfficeConfig = ServiceConfigHelper
            .loadServiceConfiguration(persistenceConfigFile, "PostOffice");
     
      String props = postOfficeConfig.getAttributeValue("SqlProperties");
     
      if (props != null)
      {
         ByteArrayInputStream is = new ByteArrayInputStream(props.getBytes());
        
         Properties sqlProperties = new Properties();
        
         sqlProperties.load(is);
        
         return sqlProperties;
      }
      else
      {
         return null;
      }
   }
  
   /**
    * @return Set<ObjectName>
    */
   public Set query(ObjectName pattern)
   {
      if (pattern == null)
      {
         return Collections.EMPTY_SET;
      }
      return mbeanServer.queryNames(pattern, null);
   }
  
   /**
    * Creates and registers a service based on the MBean service descriptor
    * element. Supports XMBeans. The implementing class and the ObjectName are
    * inferred from the mbean element. If there are configuration attributed
    * specified in the deployment descriptor, they are applied to the service
    * instance.
    */
   public ObjectName registerAndConfigureService(
         MBeanConfigurationElement mbeanConfig) throws Exception
   {
      ObjectName on = mbeanConfig.getObjectName();
      serviceCreator.install(on, CLASS_LOADER_OBJECT_NAME, mbeanConfig
            .getDelegate());
     
      // inject dependencies
      for (Iterator i = mbeanConfig.dependencyOptionalAttributeNames()
            .iterator(); i.hasNext();)
      {
         String name = (String) i.next();
         String value = mbeanConfig.getDependencyOptionalAttributeValue(name);
         setAttribute(on, name, value);
      }
     
      // apply attributes
      for (Iterator i = mbeanConfig.attributeNames().iterator(); i.hasNext();)
      {
         String name = (String) i.next();
         String value = mbeanConfig.getAttributeValue(name);
         setAttribute(on, name, value);
      }
     
      log.debug(mbeanConfig + " registered and configured");
      return on;
   }
  
   /**
    * Note that this method makes no assumption on whether the service was
    * stopped or destroyed, nor does it attempt to stop/destroy the service.
    */
   public void unregisterService(ObjectName on) throws Exception
   {
      mbeanServer.unregisterMBean(on);
      log.debug(on + " unregistered");
   }
  
   public Object invoke(ObjectName on, String operationName, Object[] params,
         String[] signature) throws Exception
   {
      try
      {
         return mbeanServer.invoke(on, operationName, params, signature);
      }
      catch (MBeanException e)
      {
         // unwrap the exception thrown by the service
         throw (Exception) e.getCause();
      }
   }
  
   /**
    * Set the attribute value, performing String -> Object conversion as
    * appropriate.
    */
   public void setAttribute(ObjectName on, String name, String valueAsString)
         throws Exception
   {
      MBeanInfo mbeanInfo = mbeanServer.getMBeanInfo(on);
      Object value = type(mbeanInfo, name, valueAsString);
      mbeanServer.setAttribute(on, new Attribute(name, value));
   }
  
   public Object getAttribute(ObjectName on, String name) throws Exception
   {
      return mbeanServer.getAttribute(on, name);
   }
  
   public void addNotificationListener(ObjectName on,
         NotificationListener listener) throws Exception
   {
      mbeanServer.addNotificationListener(on, listener, null, null);
   }
  
   public void removeNotificationListener(ObjectName on,
         NotificationListener listener) throws Exception
   {
      mbeanServer.removeNotificationListener(on, listener);
   }
  
   public MBeanServer getMBeanServer()
   {
      return mbeanServer;
   }
  
   public void bindDefaultJMSProvider() throws Exception
   {
      JNDIProviderAdapter pa = new JNDIProviderAdapter();
      pa.setQueueFactoryRef("/ConnectionFactory");
      pa.setTopicFactoryRef("/ConnectionFactory");
      pa.setFactoryRef("/ConnectionFactory");
      initialContext.bind("java:/DefaultJMSProvider", pa);
   }
  
   public void unbindDefaultJMSProvider() throws Exception
   {
      initialContext.unbind("java:/DefaultJMSProvider");
   }
  
   public void bindJCAJMSConnectionFactory() throws Exception
   {
      deployJBossJMSRA(JMS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME);
     
      startManagedConnectionPool(JMS_MANAGED_CONNECTION_POOL_OBJECT_NAME,
            JMS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME, "ByApplication");
     
      startConnectionManager(JMS_CONNECTION_MANAGER_OBJECT_NAME,
            true,
            false, // not local, but XA(!)
            TRANSACTION_MANAGER_OBJECT_NAME,
            CachedConnectionManagerMBean.OBJECT_NAME,
            JMS_MANAGED_CONNECTION_POOL_OBJECT_NAME);
     
      ObjectName on = JMS_CONNECTION_FACTORY_BINDING_SERVICE_OBJECT_NAME;
     
      // create it
      ConnectionFactoryBindingService cfBindingService = new ConnectionFactoryBindingService();
     
      // register it
      mbeanServer.registerMBean(cfBindingService, on);
     
      // configure it
      mbeanServer.setAttribute(on, new Attribute("ConnectionManager",
            JMS_CONNECTION_MANAGER_OBJECT_NAME));
      mbeanServer.setAttribute(on, new Attribute("JndiName",
            JCA_JMS_CONNECTION_FACTORY_JNDI_NAME));
      mbeanServer.setAttribute(on,
            new Attribute("UseJavaContext", Boolean.TRUE));
     
      // start it
      mbeanServer.invoke(on, "start", new Object[0], new String[0]);
     
      log.debug("started " + on);
   }
  
   /**
    * This method may be called twice successively, so it is important to handle
    * graciously this situation.
    */
   public void unbindJCAJMSConnectionFactory() throws Exception
   {
      ObjectName on = JMS_CONNECTION_FACTORY_BINDING_SERVICE_OBJECT_NAME;
     
      if (mbeanServer.isRegistered(on))
      {
         mbeanServer.invoke(on, "stop", new Object[0], new String[0]);
         mbeanServer.invoke(on, "destroy", new Object[0], new String[0]);
         mbeanServer.unregisterMBean(on);
      }
     
      stopConnectionManager(JMS_CONNECTION_MANAGER_OBJECT_NAME);
      stopManagedConnectionPool(JMS_MANAGED_CONNECTION_POOL_OBJECT_NAME);
      undeployJBossJMSRA(JMS_MANAGED_CONNECTION_FACTORY_OBJECT_NAME);
   }
  
   public String getDatabaseName()
   {
      return config.getDatabaseName();
   }
  
   public String getRemotingTransport()
   {
      return config.getRemotingTransport();
   }
  
   public boolean isClustered()
   {
      return config.isClustered();
   }
  
   public void installJMSProviderAdaptor(String jndi, JMSProviderAdapter adaptor)
         throws Exception
   {
      log.info("Binding adaptor " + adaptor + " in JNDI: " + jndi);
      initialContext.bind(jndi, adaptor);
   }
  
   public void uninstallJMSProviderAdaptor(String jndi) throws Exception
   {
      initialContext.unbind(jndi);
   }
  
   public void startRecoveryManager()
   {
      log.info("Starting arjuna recovery manager");
     
      // Need to start the recovery manager manually - if deploying
      // inside JBoss this wouldn't be necessary - since you would use
      // the TransactionManagerService MBean which would start the recovery
      // manager
      // for you
      recoveryManager = RecoveryManager
            .manager(RecoveryManager.INDIRECT_MANAGEMENT);
     
      log.info("Started recovery manager");
   }
  
   public void stopRecoveryManager()
   {
      if (recoveryManager != null)
      {
         recoveryManager.stop();
      }
   }
  
   static boolean storeAlreadySet = false;
  
   // Recovery doesn't play well with reseting the ObjectStore, so we do that
   // per VM
   public static void setupObjectStoreDir()
   {
      String name = "TestObjectStore-";
      if (!storeAlreadySet)
      {
         storeAlreadySet = true;
         String objectStoreDir = System.getProperty("objectstore.dir");
         log.trace("ObjectStoreDir===" + objectStoreDir);
        
         // We must ensure each node has its own object store
        
         String newObjectStore = name + new GUID().toString();
        
         if (objectStoreDir != null)
         {
            // Delete the old one
            // deleteDirectory(new File(objectStoreDir));
           
            newObjectStore = objectStoreDir + "/" + newObjectStore;
         }
        
         log
               .info("Setting com.arjuna.ats.arjuna.common.Environment.OBJECTSTORE_DIR to "
                     + newObjectStore);
        
         System.setProperty(
               com.arjuna.ats.arjuna.common.Environment.OBJECTSTORE_DIR,
               newObjectStore);
        
         // We must also make sure the node identifier is unique for each node
         // Otherwise xids might overlap
         String arjunanodeId = "TestNodeID-" + new GUID().toString();
        
         log
               .info("Setting com.arjuna.ats.arjuna.common.Environment.XA_NODE_IDENTIFIER to "
                     + arjunanodeId);
        
         System.setProperty(
               com.arjuna.ats.arjuna.common.Environment.XA_NODE_IDENTIFIER,
               arjunanodeId);
        
         log.info("Setting objectstore.dir to " + newObjectStore);
      }
   }
  
   public String toString()
   {
      return "ServiceContainer[" + Integer.toHexString(hashCode()) + "]";
   }
  
   // Package protected ---------------------------------------------
  
   // Protected -----------------------------------------------------
  
   // Private
   // --------------------------------------------------------------------------------------
  
   /**
    * Note that this method makes no assumption on whether the service was
    * created or started, nor does it attempt to create/start the service.
    *
    * @param service -
    *           a Standard/DynamicMBean instance.
    */
   private void registerService(Object service, ObjectName on) throws Exception
   {
      mbeanServer.registerMBean(service, on);
      log.debug(service + " registered as " + on);
   }
  
   private void readConfigurationFile() throws Exception
   {
      InputStream cs = getClass().getClassLoader().getResourceAsStream(
            CONFIGURATION_FILE_NAME);
      if (cs == null)
      {
         throw new Exception("Cannot file container's configuration file "
               + CONFIGURATION_FILE_NAME
               + ". Make sure it is in the classpath.");
      }
     
      try
      {
         config = new ServiceContainerConfiguration(cs);
      }
      finally
      {
         cs.close();
      }
   }
  
   private void loadJNDIContexts() throws Exception
   {
      String[] names =
      { ServerManagement.DEFAULT_QUEUE_CONTEXT,
            ServerManagement.DEFAULT_TOPIC_CONTEXT };
     
      for (int i = 0; i < names.length; i++)
      {
         try
         {
            initialContext.lookup(names[i]);
         }
         catch (NameNotFoundException e)
         {
            JNDIUtil.createContext(initialContext, names[i]);
            log.debug("created context /" + names[i]);
         }
      }
   }
  
   private void unloadJNDIContexts() throws Exception
   {
      // ServerPeer should do that upon its shutdown, this is redundant
     
      String[] context =
      { "/topic", "/queue" };
      for (int i = 0; i < context.length; i++)
      {
         try
         {
            Context c = (Context) initialContext.lookup(context[i]);
            JNDIUtil.tearDownRecursively(c);
         }
         catch (NameNotFoundException e)
         {
            // OK
            log.debug("no context " + context[i]
                  + " to unload, cleanup already performed");
         }
      }
   }
  
   private void startServiceController() throws Exception
   {
      // I don't really need it, because I enforce dependencies by hand, but
      // this will keep some
      // services happy.
      ServiceController sc = new ServiceController();
      mbeanServer.registerMBean(sc, SERVICE_CONTROLLER_OBJECT_NAME);
   }
  
   private void stopServiceController() throws Exception
   {
      mbeanServer.unregisterMBean(SERVICE_CONTROLLER_OBJECT_NAME);
   }
  
   /**
    * Register a class loader used to instantiate other services.
    */
   private void registerClassLoader() throws Exception
   {
      ClassLoader cl = getClass().getClassLoader();
      mbeanServer.registerMBean(new ClassLoaderJMXWrapper(cl),
            CLASS_LOADER_OBJECT_NAME);
   }
  
   private void unregisterClassLoader() throws Exception
   {
      mbeanServer.unregisterMBean(CLASS_LOADER_OBJECT_NAME);
   }
  
   private void startInVMDatabase() throws Exception
   {
      if (!"hsqldb".equals(config.getDatabaseName()))
      {
         // is an out-of-process DB, and it must be stared externally
         return;
      }
     
      log.debug("starting " + config.getDatabaseName() + " in-VM");
     
      String url = config.getDatabaseConnectionURL();
      HsqlProperties props = new HsqlProperties();
      props.setProperty("server.database.0", ServiceContainerConfiguration
            .getHypersonicDatabase(url));
      props.setProperty("server.dbname.0", ServiceContainerConfiguration
            .getHypersonicDbname(url));
      props.setProperty("server.trace", "false");
      props.setProperty("server.silent", "true");
      props.setProperty("server.no_system_exit", "true");
      props.setProperty("server.port", 27862);
      props.setProperty("server.address", ipAddressOrHostName);
     
      hsqldbServer = new Server();
      hsqldbServer.setLogWriter(null);
      hsqldbServer.setProperties(props);
      hsqldbServer.start();
     
      log.debug("started " + config.getDatabaseName() + " in-VM");
   }
  
   private void stopInVMDatabase() throws Exception
   {
      if (!"hsqldb".equals(config.getDatabaseName()))
      {
         // is an out-of-process DB, and it must be stopped externally
         return;
      }
     
      log.debug("stop " + hsqldbServer);
     
      Class.forName(config.getDatabaseDriverClass());
     
      Connection conn = DriverManager.getConnection(config
            .getDatabaseConnectionURL(), config.getDatabaseUserName(), config
            .getDatabasePassword());
     
      Statement stat = conn.createStatement();
      stat.executeUpdate("SHUTDOWN");
      conn.close();
     
      // faster stop
      // hsqldbServer.stop();
   }
  
   private void startTransactionManager() throws Exception
   {
      if (tm == null)
      {
         setupObjectStoreDir();
         log.info("Starting arjuna tx mgr");
         tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
      }
     
      TransactionManagerJMXWrapper mbean = new TransactionManagerJMXWrapper(tm);
      mbeanServer.registerMBean(mbean, TRANSACTION_MANAGER_OBJECT_NAME);
      mbeanServer.invoke(TRANSACTION_MANAGER_OBJECT_NAME, "start",
            new Object[0], new String[0]);
      log.debug("started " + TRANSACTION_MANAGER_OBJECT_NAME);
     
      initialContext.bind(TRANSACTION_MANAGER_JNDI_NAME, tm);
      toUnbindAtExit.add(TRANSACTION_MANAGER_JNDI_NAME);
     
      log.debug("bound " + TRANSACTION_MANAGER_JNDI_NAME);
     
      initialContext.rebind(USER_TRANSACTION_JNDI_NAME,
            ServerVMClientUserTransaction.getSingleton());
     
      log.debug("bound " + USER_TRANSACTION_JNDI_NAME);
   }
  
   private static boolean deleteDirectory(File directory)
   {
      if (directory.isDirectory())
      {
         String[] files = directory.list();
        
         for (int j = 0; j < files.length; j++)
         {
            if (!deleteDirectory(new File(directory, files[j])))
            {
               return false;
            }
         }
      }
     
      return directory.delete();
   }
  
   private void startCachedConnectionManager(ObjectName on) throws Exception
   {
      CachedConnectionManager ccm = new CachedConnectionManager();
     
      // dependencies
      ccm.setTransactionManagerServiceName(TRANSACTION_MANAGER_OBJECT_NAME);
     
      mbeanServer.registerMBean(ccm, on);
      mbeanServer.invoke(on, "start", new Object[0], new String[0]);
      log.debug("started " + on);
   }
  
   /**
    * Database specific.
    */
   private void startManagedConnectionFactory(ObjectName on) throws Exception
   {
      LocalManagedConnectionFactory mcf = new LocalManagedConnectionFactory();
     
      log.info("connection url:" + config.getDatabaseConnectionURL());
      log.info("driver:" + config.getDatabaseConnectionURL());
      log.info("username:" + config.getDatabaseUserName());
      log.info("password:" + config.getDatabasePassword());
     
      mcf.setConnectionURL(config.getDatabaseConnectionURL());
      mcf.setDriverClass(config.getDatabaseDriverClass());
      mcf.setUserName(config.getDatabaseUserName());
      mcf.setPassword(config.getDatabasePassword());
      String isolation = config.getDatabaseTransactionIsolation();
      if (isolation != null)
      {
         mcf.setTransactionIsolation(isolation);
      }
     
      ManagedConnectionFactoryJMXWrapper mbean = new ManagedConnectionFactoryJMXWrapper(
            mcf);
      mbeanServer.registerMBean(mbean, on);
      mbeanServer.invoke(on, "start", new Object[0], new String[0]);
      log.debug("started " + on);
   }
  
   /**
    * This method may be called twice successively, so it is important to handle
    * graciously this situation.
    */
   private void stopManagedConnectionFactory(ObjectName on) throws Exception
   {
      stopService(on);
   }
  
   private void startManagedConnectionPool(ObjectName on,
         ObjectName managedConnectionFactoryObjectName, String criteria)
         throws Exception
   {
      mcp = new JBossManagedConnectionPool();
      mcp.setCriteria(criteria);
     
      // dependencies
      mcp.setManagedConnectionFactoryName(managedConnectionFactoryObjectName);
     
      mbeanServer.registerMBean(mcp, on);
      mbeanServer.invoke(on, "start", new Object[0], new String[0]);
      log.debug("started " + on);
     
   }
  
   /**
    * This method may be called twice successively, so it is important to handle
    * graciously this situation.
    */
   private void stopManagedConnectionPool(ObjectName on) throws Exception
   {
      stopService(on);
   }
  
   private TxConnectionManager startConnectionManager(ObjectName on,
         boolean trackConnectionByTx, boolean localTransactions,
         ObjectName transactionManagerObjectName,
         ObjectName cachedConnectionManagerObjectName,
         ObjectName managedConnectionPoolObjectName) throws Exception
   {
      TxConnectionManager cm = new TxConnectionManager();
      cm.preRegister(mbeanServer, on);
      cm.setTrackConnectionByTx(trackConnectionByTx);
      cm.setLocalTransactions(localTransactions);
     
      // dependencies
      cm.setTransactionManagerService(transactionManagerObjectName);
      cm.setCachedConnectionManager(cachedConnectionManagerObjectName);
      cm.setManagedConnectionPool(managedConnectionPoolObjectName);
     
      mbeanServer.registerMBean(cm, on);
      mbeanServer.invoke(on, "start", new Object[0], new String[0]);
      log.debug("started " + on);
     
      return cm;
   }
  
   /**
    * This method may be called twice successively, so it is important to handle
    * graciously this situation.
    */
   private void stopConnectionManager(ObjectName on) throws Exception
   {
      stopService(on);
   }
  
   private void startWrapperDataSourceService() throws Exception
   {
      WrapperDataSourceService wdss = new WrapperDataSourceService();
      wdss.setJndiName(DATA_SOURCE_JNDI_NAME);
     
      // dependencies
      wdss.setConnectionManager(DEFAULTDS_CONNECTION_MANAGER_OBJECT_NAME);
      ObjectName irrelevant = new ObjectName(":name=irrelevant");
      wdss.setJMXInvokerName(irrelevant);
      Registry.bind(irrelevant, new NoopInvoker());
     
      mbeanServer.registerMBean(wdss,
            DEFAULTDS_WRAPPER_DATA_SOURCE_SERVICE_OBJECT_NAME);
      mbeanServer.invoke(DEFAULTDS_WRAPPER_DATA_SOURCE_SERVICE_OBJECT_NAME,
            "start", new Object[0], new String[0]);
     
      log.debug("started " + DEFAULTDS_WRAPPER_DATA_SOURCE_SERVICE_OBJECT_NAME);
   }
  
   private void stopWrapperDataSourceService() throws Exception
   {
      stopService(DEFAULTDS_WRAPPER_DATA_SOURCE_SERVICE_OBJECT_NAME);
   }
  
   private void deployJBossJMSRA(ObjectName managedConnFactoryObjectName)
         throws Exception
   {
      JmsManagedConnectionFactory mcf = new JmsManagedConnectionFactory();
      // mcf.setClientID("");
      // mcf.setUserName("");
      // mcf.setPassword("");
      mcf.setJmsProviderAdapterJNDI("java:/DefaultJMSProvider");
      mcf.setStrict(true);
      mcf.setSessionDefaultType("javax.jms.Queue");
     
      registerService(new ManagedConnectionFactoryJMXWrapper(mcf),
            managedConnFactoryObjectName);
   }
  
   /**
    * This method may be called twice successively, so it is important to handle
    * graciously this situation.
    */
   private void undeployJBossJMSRA(ObjectName managedConnFactoryObjectName)
         throws Exception
   {
      stopService(managedConnFactoryObjectName);
   }
  
   private String buildLocatorURI(String transport, Map overrideMap)
         throws Exception
   {
      // We use this from thirdparty remoting tests when we don't want to send
      // stuff through
      // JMSWireFormat, but we want everything else in the connector's
      // configuration to be
      // identical with what we use in Messaging
      boolean overrideMarshallers = overrideMap != null
            && overrideMap.get(DO_NOT_USE_MESSAGING_MARSHALLERS) != null;
     
      // Note that we DO NOT want the direct thread pool on the server side -
      // since that can lead
      // to deadlocks
     
      String configFileName = "remoting/remoting-" + transport + "-service.xml";
     
      MBeanConfigurationElement connectorServiceConfig = ServiceConfigHelper
            .loadServiceConfiguration(configFileName, "Connector");
     
      String invokerConfig = connectorServiceConfig
            .getAttributeValue("Configuration");
     
      Element invokerElement = (Element) XMLUtil.stringToElement(invokerConfig)
            .getElementsByTagName("invoker").item(0);
     
      NodeList invokerAttributes = invokerElement
            .getElementsByTagName("attribute");
     
      StringBuffer paramsBuffer = new StringBuffer();
     
      for (int i = 0; i < invokerAttributes.getLength(); i++)
      {
         Element attr = (Element) invokerAttributes.item(i);
         String key = attr.getAttribute("name");
        
         if (attr.getAttribute("isParam").equals("")
               && (key == null || !key.equals("serverSocketClass")))
         {
            continue;
         }
        
         String value = attr.getTextContent().trim();
        
         if (overrideMarshallers
               && (key.equals("marshaller") || key.equals("unmarshaller")))
         {
            continue;
         }
        
         if (paramsBuffer.length() > 0)
         {
            paramsBuffer.append('&');
         }
        
         if (overrideMap != null)
         {
            String valueOverride = (String) overrideMap.get(key);
            if (valueOverride != null)
            {
               value = valueOverride;
            }
         }
        
         paramsBuffer.append(key).append('=').append(value);
      }
     
      int freePort = PortUtil.findFreePort(ipAddressOrHostName);
     
      return new StringBuffer().append(transport).append("://").append(
            ipAddressOrHostName).append(':').append(freePort).append("/?")
            .append(paramsBuffer).toString();
   }
  
   private void startRemoting(ServiceAttributeOverrides attrOverrides,
         String transport, ObjectName objectName) throws Exception
   {
      log.debug("Starting remoting transport=" + transport + " objectName="
            + objectName);
      RemotingJMXWrapper mbean;
      String locatorURI = null;
     
      // some tests may want specific locator URI overrides to simulate special
      // conditions; use
      // that with priority, if available
      Map overrideMap = null;
     
      if (attrOverrides != null)
      {
         overrideMap = attrOverrides.get(objectName);
        
         if (overrideMap != null)
         {
            locatorURI = (String) overrideMap.get("LocatorURI");
         }
      }
     
      if (locatorURI == null)
      {
         locatorURI = buildLocatorURI(transport, overrideMap);
         log.info("creating server for: " + locatorURI);
      }
     
      log.debug("Using locator uri: " + locatorURI);
     
      InvokerLocator locator = new InvokerLocator(locatorURI);
     
      log.debug("Started remoting connector on uri:" + locator.getLocatorURI());
     
      mbean = new RemotingJMXWrapper(locator);
      mbeanServer.registerMBean(mbean, objectName);
      mbeanServer.invoke(objectName, "start", new Object[0], new String[0]);
     
      ServerInvocationHandler handler = new JMSServerInvocationHandler();
     
      mbeanServer.invoke(objectName, "addInvocationHandler", new Object[]
      { ServerPeer.REMOTING_JMS_SUBSYSTEM, handler }, new String[]
      { "java.lang.String", "org.jboss.remoting.ServerInvocationHandler" });
     
      log.debug("started " + objectName);
   }
  
   private void startSecurityManager() throws Exception
   {
      MockJBossSecurityManager sm = new MockJBossSecurityManager();
      this.initialContext.bind(MockJBossSecurityManager.TEST_SECURITY_DOMAIN,
            sm);
     
      toUnbindAtExit.add(MockJBossSecurityManager.TEST_SECURITY_DOMAIN);
     
      log.debug("started JBoss Mock Security Manager, using ic: "
            + this.initialContext + " id "
            + System.identityHashCode(this.initialContext));
   }
  
   private void stopService(ObjectName target) throws Exception
   {
      if (mbeanServer.isRegistered(target))
      {
         mbeanServer.invoke(target, "stop", new Object[0], new String[0]);
         mbeanServer.unregisterMBean(target);
         log.debug("stopped " + target);
      }
   }
  
   private void cleanJNDI() throws Exception
   {
      for (Iterator i = toUnbindAtExit.iterator(); i.hasNext();)
      {
         String name = (String) i.next();
        
         initialContext.unbind(name);
      }
   }
  
   private void executeStatement(TransactionManager mgr, DataSource ds,
         String statement) throws Exception
   {
      Connection conn = null;
      boolean exception = false;
     
      try
      {
         try
         {
            mgr.begin();
           
            conn = ds.getConnection();
           
            log.debug("executing " + statement);
           
            PreparedStatement ps = conn.prepareStatement(statement);
           
            ps.executeUpdate();
           
            log.debug(statement + " executed");
           
            ps.close();
         }
         catch (SQLException e)
         {
            // Ignore
            log.debug("Failed to execute statement", e);
            exception = true;
         }
      }
      finally
      {
         if (conn != null)
         {
            conn.close();
         }
        
         if (exception)
         {
            mgr.rollback();
         }
         else
         {
            mgr.commit();
         }
      }
     
   }
  
   protected void dropAllTables() throws Exception
   {
      log.info("DROPPING ALL TABLES FROM DATABASE!");
     
      InitialContext ctx = new InitialContext();
     
      // We need to execute each drop in its own transaction otherwise
      // postgresql will not execute
      // further commands after one fails
     
      TransactionManager mgr = (TransactionManager) ctx
            .lookup(TransactionManagerService.JNDI_NAME);
      DataSource ds = (DataSource) ctx.lookup("java:/DefaultDS");
     
      javax.transaction.Transaction txOld = mgr.suspend();
     
      executeStatement(mgr, ds, "DROP TABLE JBM_POSTOFFICE");
     
      executeStatement(mgr, ds, "DROP TABLE JBM_MSG_REF");
     
      executeStatement(mgr, ds, "DROP TABLE JBM_MSG");
     
      executeStatement(mgr, ds, "DROP TABLE JBM_TX");
     
      executeStatement(mgr, ds, "DROP TABLE JBM_COUNTER");
     
      executeStatement(mgr, ds, "DROP TABLE JBM_USER");
     
      executeStatement(mgr, ds, "DROP TABLE JBM_ROLE");
     
      executeStatement(mgr, ds, "DROP TABLE JBM_DUAL");
     
      if (txOld != null)
      {
         mgr.resume(txOld);
      }
     
      log.debug("done with dropping tables");
   }
  
   protected void deleteAllData() throws Exception
   {
      log.info("DELETING ALL DATA FROM DATABASE!");
     
      InitialContext ctx = new InitialContext();
     
      // We need to execute each drop in its own transaction otherwise
      // postgresql will not execute
      // further commands after one fails
     
      TransactionManager mgr = (TransactionManager) ctx
            .lookup(TransactionManagerService.JNDI_NAME);
      DataSource ds = (DataSource) ctx.lookup("java:/DefaultDS");
     
      javax.transaction.Transaction txOld = mgr.suspend();
     
      executeStatement(mgr, ds, "DELETE FROM JBM_POSTOFFICE");
     
      executeStatement(mgr, ds, "DELETE FROM JBM_MSG_REF");
     
      executeStatement(mgr, ds, "DELETE FROM JBM_MSG");
     
      executeStatement(mgr, ds, "DELETE FROM JBM_TX");
     
      executeStatement(mgr, ds, "DELETE FROM JBM_COUNTER");
     
      executeStatement(mgr, ds, "DELETE FROM JBM_USER");
     
      executeStatement(mgr, ds, "DELETE FROM JBM_ROLE");
     
      executeStatement(mgr, ds, "DELETE FROM JBM_ID_CACHE");
     
      if (txOld != null)
      {
         mgr.resume(txOld);
      }
     
      log.debug("done with the deleting data");
   }
  
   private void startMultiplexer() throws Exception
   {
      log.debug("Starting multiplexer");
     
      String multiplexerConfigFile = "server/default/deploy/multiplexer-service.xml";
      URL multiplexerCofigURL = getClass().getClassLoader().getResource(
            multiplexerConfigFile);
     
      if (multiplexerCofigURL == null)
      {
         throw new Exception("Cannot find " + multiplexerCofigURL
               + " in the classpath");
      }
     
      ServiceDeploymentDescriptor multiplexerDD = ServiceConfigHelper
            .loadConfigFile(multiplexerConfigFile);
     
      List services = multiplexerDD.query("name", "Multiplexer");
     
      if (services.isEmpty())
      {
         log.info("Couldn't find multiplexer config");
      }
      else
      {
         log.info("Could find multiplexer config");
      }
     
      MBeanConfigurationElement multiplexerConfig = (MBeanConfigurationElement) services
            .iterator().next();
      ObjectName nameMultiplexer = registerAndConfigureService(multiplexerConfig);
      invoke(nameMultiplexer, "create", new Object[0], new String[0]);
      invoke(nameMultiplexer, "start", new Object[0], new String[0]);
   }
  
   private void overrideAttributes(ObjectName on,
         ServiceAttributeOverrides attrOverrides) throws Exception
   {
      if (attrOverrides == null)
      {
         return;
      }
     
      Map sao = attrOverrides.get(on);
     
      for (Iterator i = sao.entrySet().iterator(); i.hasNext();)
      {
         Map.Entry entry = (Map.Entry) i.next();
         String attrName = (String) entry.getKey();
         Object attrValue = entry.getValue();
         setAttribute(on, attrName, attrValue.toString());
        
      }
   }
  
   public void deployConnectionFactories(String connFactoryConfigFile,
         ServiceAttributeOverrides attrOverrides) throws Exception
   {
      connFactoryObjectNames.clear();
     
      ServiceDeploymentDescriptor cfdd = ServiceConfigHelper
            .loadConfigFile(connFactoryConfigFile);
     
      List connFactoryElements = cfdd.query("service", "ConnectionFactory");
     
      for (Iterator i = connFactoryElements.iterator(); i.hasNext();)
      {
         MBeanConfigurationElement connFactoryElement = (MBeanConfigurationElement) i
               .next();
         ObjectName on = registerAndConfigureService(connFactoryElement);
         overrideAttributes(on, attrOverrides);
         // dependencies have been automatically injected already
         invoke(on, "create", new Object[0], new String[0]);
         invoke(on, "start", new Object[0], new String[0]);
         connFactoryObjectNames.add(on);
      }
     
      connFactoryElements = cfdd.query("service", "ClusteredConnectionFactory");
     
      for (Iterator i = connFactoryElements.iterator(); i.hasNext();)
      {
         MBeanConfigurationElement connFactoryElement = (MBeanConfigurationElement) i
               .next();
         ObjectName on = registerAndConfigureService(connFactoryElement);
         overrideAttributes(on, attrOverrides);
         // dependencies have been automatically injected already
         invoke(on, "create", new Object[0], new String[0]);
         invoke(on, "start", new Object[0], new String[0]);
         connFactoryObjectNames.add(on);
      }
     
      connFactoryElements = cfdd.query("service", "HTTPConnectionFactory");
     
      for (Iterator i = connFactoryElements.iterator(); i.hasNext();)
      {
         MBeanConfigurationElement connFactoryElement = (MBeanConfigurationElement) i
               .next();
         ObjectName on = registerAndConfigureService(connFactoryElement);
         overrideAttributes(on, attrOverrides);
         // dependencies have been automatically injected already
         invoke(on, "create", new Object[0], new String[0]);
         invoke(on, "start", new Object[0], new String[0]);
         connFactoryObjectNames.add(on);
      }
     
      connFactoryElements = cfdd.query("service",
            "ClusterPullConnectionFactory");
     
      for (Iterator i = connFactoryElements.iterator(); i.hasNext();)
      {
         MBeanConfigurationElement connFactoryElement = (MBeanConfigurationElement) i
               .next();
         ObjectName on = registerAndConfigureService(connFactoryElement);
         overrideAttributes(on, attrOverrides);
         // dependencies have been automatically injected already
         invoke(on, "create", new Object[0], new String[0]);
         invoke(on, "start", new Object[0], new String[0]);
         connFactoryObjectNames.add(on);
      }
   }
  
   private void parseConfig(String config)
   {
      config = config.toLowerCase();
      for (StringTokenizer st = new StringTokenizer(config, ", "); st
            .hasMoreTokens();)
      {
         String tok = st.nextToken();
         boolean minus = false;
        
         if (tok.startsWith("-"))
         {
            tok = tok.substring(1);
            minus = true;
         }
        
         if ("all".equals(tok))
         {
            transaction = true;
            database = true;
            jca = true;
            remoting = true;
            security = true;
         }
         else if ("all+http".equals(tok))
         {
            transaction = true;
            database = true;
            jca = true;
            remoting = true;
            security = true;
            httpConnectionFactory = true;
         }
         else if ("transaction".equals(tok))
         {
            transaction = true;
            if (minus)
            {
               transaction = false;
            }
         }
         else if ("database".equals(tok))
         {
            database = true;
            if (minus)
            {
               database = false;
            }
         }
         else if ("jca".equals(tok))
         {
            jca = true;
            if (minus)
            {
               jca = false;
            }
         }
         else if ("remoting".equals(tok))
         {
            remoting = true;
            if (minus)
            {
               remoting = false;
            }
         }
         else if ("security".equals(tok))
         {
            security = true;
            if (minus)
            {
               security = false;
            }
         }
         else if ("multiplexer".equals(tok))
         {
            multiplexer = true;
            if (minus)
            {
               multiplexer = false;
            }
         }
         else if ("none".equals(tok))
         {
            transaction = false;
            database = false;
            jca = false;
            remoting = false;
            security = false;
            multiplexer = false;
         }
         else
         {
            throw new IllegalArgumentException("Unknown service: " + tok);
         }
      }
   }
  
   // Inner classes
   // --------------------------------------------------------------------------------
}
TOP

Related Classes of org.jboss.test.messaging.tools.container.ServiceContainer

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.