Package org.jboss.test.messaging.tools.jmx

Source Code of org.jboss.test.messaging.tools.jmx.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.jmx;


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.jms.util.JNDIUtil;
import org.jboss.jms.util.XMLUtil;
import org.jboss.logging.Logger;
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.test.messaging.tools.jndi.Constants;
import org.jboss.test.messaging.tools.jndi.InVMInitialContextFactory;
import org.jboss.test.messaging.tools.jndi.InVMInitialContextFactoryBuilder;
import org.jboss.tm.TransactionManagerService;
import org.jboss.tm.TxManager;
import org.jboss.tm.usertx.client.ServerVMClientUserTransaction;

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@jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision: 2386 $</tt>
*
* $Id: ServiceContainer.java 2386 2007-02-21 18:07:44Z 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 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";

   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");
      }
      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 boolean transaction;
   private boolean jbossjta; //To use the ex-Arjuna tx mgr
   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))
      {
         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();
      }

      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 ---------------------------------------------------------------------------------------

   /**
    * By default, starting the container DELETES ALL DATA previously existing in the database.
    */
   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();

         boolean java5 = false;

         try
         {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            cl.loadClass("java.lang.management.ManagementFactory");
            java5 = true;
         }
         catch(ClassNotFoundException e)
         {
            // OK
         }

         if (java5)
         {
            System.setProperty("javax.management.builder.initial",
                               "org.jboss.test.messaging.tools.jmx.MBeanServerBuilder");
         }

         mbeanServer = MBeanServerFactory.createMBeanServer("jboss");

         serviceCreator = new ServiceCreator(mbeanServer);

         startServiceController();

         registerClassLoader();

         if (jbossjta)
         {
            deleteObjectStore();
         }

         if (transaction || jbossjta)
         {
            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 || jbossjta) && jca && cleanDatabase)
         {
            // We make sure the database is clean (only if we have all dependencies the database,
            // othewise we'll get an access error)
            dropAllTables();
         }

         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("Serialization type: ......... " + config.getSerializationType());
         log.info("Database: ................... " + config.getDatabaseType());
         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 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("server/default/deploy/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 stop() throws Exception
   {

      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);
      }

      initialContext.close();

      cleanJNDI();

      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 Properties getPersistenceManagerSQLProperties() throws Exception
   {
      String databaseType = getDatabaseType();

      String persistenceConfigFile =
         "server/default/deploy/" + databaseType + "-persistence-service.xml";

      log.info("Persistence config file: .... " + persistenceConfigFile);
     
      URL persistenceConfigFileURL = getClass().getClassLoader().getResource(persistenceConfigFile);
      if (persistenceConfigFileURL == null)
      {
         throw new Exception("Cannot find " + persistenceConfigFile + " in the classpath");
      }

      ServiceDeploymentDescriptor pdd = new ServiceDeploymentDescriptor(persistenceConfigFileURL);

      MBeanConfigurationElement persistenceManagerConfig =
         (MBeanConfigurationElement)pdd.query("service", "PersistenceManager").iterator().next();

      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 databaseType = getDatabaseType();

      String persistenceConfigFile =
         "server/default/deploy/" + databaseType + "-persistence-service.xml";

      log.info("Peristence config file: .. " + persistenceConfigFile);

      URL persistenceConfigFileURL = getClass().getClassLoader().getResource(persistenceConfigFile);
      if (persistenceConfigFileURL == null)
      {
         throw new Exception("Cannot find " + persistenceConfigFile + " in the classpath");
      }

      ServiceDeploymentDescriptor pdd = new ServiceDeploymentDescriptor(persistenceConfigFileURL);

      MBeanConfigurationElement postOfficeConfig =
         (MBeanConfigurationElement)pdd.query("service", "PostOffice").iterator().next();

      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;
      }
   }

   public Properties getClusteredPostOfficeSQLProperties() throws Exception
   {
      String databaseType = getDatabaseType();

      String persistenceConfigFile;
      if (databaseType.equals("hsqldb"))
      {
         persistenceConfigFile =
            "server/default/deploy/" + databaseType + "-persistence-service.xml";
      }
      else
      {
         persistenceConfigFile =
            "server/default/deploy/clustered-" + databaseType + "-persistence-service.xml";
      }

      log.info("Persistence config file: .... " + persistenceConfigFile);

      URL persistenceConfigFileURL = getClass().getClassLoader().getResource(persistenceConfigFile);
      if (persistenceConfigFileURL == null)
      {
         throw new Exception("Cannot find " + persistenceConfigFile + " in the classpath");
      }

      ServiceDeploymentDescriptor pdd = new ServiceDeploymentDescriptor(persistenceConfigFileURL);

      MBeanConfigurationElement postOfficeConfig =
         (MBeanConfigurationElement)pdd.query("service", "PostOffice").iterator().next();

      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 getDatabaseType()
   {
      return config.getDatabaseType();
   }

   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();
      }     
   }

   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.getDatabaseType()))
      {
         // is an out-of-process DB, and it must be stared externally
         return;
      }

      log.debug("starting " + config.getDatabaseType() + " 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.getDatabaseType() + " in-VM");
   }

   private void stopInVMDatabase() throws Exception
   {
      if (!"hsqldb".equals(config.getDatabaseType()))
      {
         // 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)
      {
         if (jbossjta)
         {
            log.info("Starting arjuna tx mgr");
            tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
         }
         else
         {
            log.info("Starting non arjuna tx mgr");
            tm = TxManager.getInstance();
         }
      }

      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 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 deleteObjectStore()
   {
      // First delete the object store - might have been left over from a previous run

      String objectStoreDir = System.getProperty("objectstore.dir");

      log.info("Deleting object store: " + objectStoreDir);

      if (objectStoreDir == null)
      {
         log.warn("Cannot find objectstore.dir parameter");
      }
      else
      {
         File f = new File(objectStoreDir);

         deleteDirectory(f);
      }
   }



   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
   {
      JBossManagedConnectionPool 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 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)
      {
         // TODO - use remoting-service.xml parameters, not these ...

         String serializationType = config.getSerializationType();

         //TODO - Actually serializationType is irrelevant since we pass a DataOutput/InputStream
         //       into the marshaller and don't use serialization apart from one specific case with
         //       a JMS ObjectMessage in which case Java serialization is always currently used -
         //       (we could make this configurable)

         long clientLeasePeriod = 20000;

         String marshallers =
            "marshaller=org.jboss.jms.server.remoting.JMSWireFormat&" +
            "unmarshaller=org.jboss.jms.server.remoting.JMSWireFormat&";
         String dataType = "dataType=jms&";

         // 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
         if (overrideMap != null && overrideMap.get(DO_NOT_USE_MESSAGING_MARSHALLERS) != null)
         {
            marshallers = "";
            dataType = "";
            serializationType = "java";
         }
        
         // Note that we DO NOT want the direct thread pool on the server side - since that can lead
         // to deadlocks

         String params =
            "/?" +
            marshallers +
            "serializationtype=" + serializationType + "&" +
            dataType +
            "socket.check_connection=false&" +
            "clientLeasePeriod=" + clientLeasePeriod + "&" +
            "callbackStore=org.jboss.remoting.callback.BlockingCallbackStore&" +
            "clientSocketClass=org.jboss.jms.client.remoting.ClientSocketWrapper&" +
            "serverSocketClass=org.jboss.jms.server.remoting.ServerSocketWrapper&" +
            "NumberOfRetries=1&" +
            "NumberOfCallRetries=2&" +
            "callbackErrorsAllowed=1";
        
        
        
         // specific parameters per transport

         if ("http".equals(transport))
         {
            params += "&callbackPollPeriod=" + HTTP_CONNECTOR_CALLBACK_POLL_PERIOD;
         }
         else
         {
            params += "&timeout=0";
         }
        
         if ("sslbisocket".equals(transport) || "sslsocket".equals(transport))
         {
            System.setProperty("javax.net.ssl.keyStorePassword", "secureexample");
            String keyStoreFilePath = this.getClass().getResource("../../../../../../../etc/messaging.keystore").getFile();
            System.setProperty("javax.net.ssl.keyStore", keyStoreFilePath);
         }
        
         int freePort = PortUtil.findFreePort(ipAddressOrHostName);
         locatorURI = transport + "://" + ipAddressOrHostName + ":" + freePort + params;
         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);

      log.debug("started JBoss Mock Security Manager");
   }

   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
   {
      InitialContext ic = new InitialContext();

      for(Iterator i = toUnbindAtExit.iterator(); i.hasNext(); )
      {
         String name = (String)i.next();
         ic.unbind(name);
      }
      ic.close();
   }
  
   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");
     
      if (txOld != null)
      {
         mgr.resume(txOld);
      }

      log.debug("done with the database");
   }

   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 =
         new ServiceDeploymentDescriptor(multiplexerCofigURL);

      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
   {

      URL connFactoryConfigFileURL =
         getClass().getClassLoader().getResource(connFactoryConfigFile);

      if (connFactoryConfigFileURL == null)
      {
         throw new Exception("Cannot find " + connFactoryConfigFile + " in the classpath");
      }

      ServiceDeploymentDescriptor cfdd =
         new ServiceDeploymentDescriptor(connFactoryConfigFileURL);
      List connFactoryElements = cfdd.query("service", "ConnectionFactory");
      if (connFactoryElements.isEmpty())
      {
         connFactoryElements = cfdd.query("service", "HTTPConnectionFactory");
      }
      connFactoryObjectNames.clear();
      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 ("jbossjta".equals(tok))
         {
            if (transaction)
            {
               throw new IllegalArgumentException("Cannot have the old JBoss transaction manager AND the JBoss Transactions transaction manager");
            }
           
            //Use the JBoss Transactions (ex Arjuna) JTA
            jbossjta = true;
            if (minus)
            {
               jbossjta = 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.jmx.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.