/*
* 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
// --------------------------------------------------------------------------------
}