[jboss-cvs] JBossAS SVN: r90503 - in branches/Branch_5_x: cluster/src/main/org/jboss/ha/framework/server and 2 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Jun 22 13:15:13 EDT 2009
Author: bstansberry at jboss.com
Date: 2009-06-22 13:15:13 -0400 (Mon, 22 Jun 2009)
New Revision: 90503
Added:
branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ChannelInfo.java
branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackConfigInfo.java
branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackUtil.java
branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/managed/
branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/channelfactory/
branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ChannelFactoryManagedObjectsTestCase.java
branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryOverrideUnitTestCase.java
branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/OpenChannelsMapperUnitTestCase.java
branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ProtocolStackConfigurationsMapperUnitTestCase.java
Modified:
branches/Branch_5_x/cluster/build.xml
branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactory.java
branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactoryMBean.java
branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java
branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryUnitTestCase.java
Log:
[JBAS-7016] ChannelFactory managed object interface
[JBAS-7014] Fix addSingletonName handling
[JBAS-7009] Don't subclass JGroups version
[JBAS-7015] Always add singleton_name
Modified: branches/Branch_5_x/cluster/build.xml
===================================================================
--- branches/Branch_5_x/cluster/build.xml 2009-06-22 17:04:50 UTC (rev 90502)
+++ branches/Branch_5_x/cluster/build.xml 2009-06-22 17:15:13 UTC (rev 90503)
@@ -84,6 +84,7 @@
<path refid="jboss.jboss.deployers.classpath"/>
<path refid="jboss.jboss.man.classpath"/>
<path refid="jboss.jboss.mdr.classpath"/>
+ <path refid="jboss.jboss.reflect.classpath"/>
<path refid="jboss.microcontainer.classpath"/>
<path refid="jboss.integration.classpath"/>
<path refid="jboss.jboss.javaee.classpath"/>
Copied: branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ChannelInfo.java (from rev 90500, trunk/cluster/src/main/org/jboss/ha/framework/server/ChannelInfo.java)
===================================================================
--- branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ChannelInfo.java (rev 0)
+++ branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ChannelInfo.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ha.framework.server;
+
+import java.util.List;
+
+import javax.management.ObjectName;
+
+import org.jgroups.Address;
+import org.jgroups.Channel;
+import org.jgroups.View;
+import org.jgroups.conf.ProtocolData;
+
+/**
+ * Information describing an open JGroups Channel.
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class ChannelInfo
+{
+ private final String id;
+ private final String stackName;
+ private final Channel channel;
+ private final ProtocolData[] protocolStackConfiguration;
+ private final ObjectName channelObjectName;
+ private final List<ObjectName> protocolObjectNames;
+
+ public ChannelInfo(String id, String stackName, Channel channel,
+ ProtocolData[] config, ObjectName channelObjectName,
+ List<ObjectName> protocolObjectNames)
+ {
+ if (channel == null)
+ {
+ throw new IllegalArgumentException("null channel");
+ }
+
+ this.id = id;
+ this.stackName = stackName;
+ this.channel = channel;
+ this.protocolStackConfiguration = config;
+ this.channelObjectName = channelObjectName;
+ this.protocolObjectNames = protocolObjectNames;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getClusterName()
+ {
+ return channel.getClusterName();
+ }
+
+ public String getStackName()
+ {
+ return stackName;
+ }
+
+ public Channel getChannel()
+ {
+ return channel;
+ }
+
+ public ProtocolData[] getProtocolStackConfiguration()
+ {
+ return protocolStackConfiguration;
+ }
+
+ public ObjectName getChannelObjectName()
+ {
+ return channelObjectName;
+ }
+
+ public List<ObjectName> getProtocolObjectNames()
+ {
+ return protocolObjectNames;
+ }
+
+ public Address getLocalAddress()
+ {
+ return this.channel.getLocalAddress();
+ }
+
+ public View getCurrentView()
+ {
+ return this.channel.getView();
+ }
+}
Modified: branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactory.java
===================================================================
--- branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactory.java 2009-06-22 17:04:50 UTC (rev 90502)
+++ branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactory.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -21,15 +21,22 @@
*/
package org.jboss.ha.framework.server;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
import java.net.InetAddress;
+import java.net.URL;
import java.rmi.dgc.VMID;
import java.rmi.server.UID;
import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import javax.management.MBeanRegistration;
@@ -37,17 +44,27 @@
import javax.management.ObjectName;
import org.jboss.config.ServerConfigUtil;
+import org.jboss.ha.framework.server.managed.OpenChannelsMapper;
+import org.jboss.ha.framework.server.managed.ProtocolStackConfigurationsMapper;
import org.jboss.logging.Logger;
+import org.jboss.managed.api.annotation.ManagementComponent;
+import org.jboss.managed.api.annotation.ManagementObject;
+import org.jboss.managed.api.annotation.ManagementProperties;
+import org.jboss.managed.api.annotation.ManagementProperty;
+import org.jboss.managed.api.annotation.ViewUse;
+import org.jboss.metatype.api.annotations.MetaMapping;
import org.jboss.system.ServiceMBean;
import org.jboss.util.loading.ContextClassLoaderSwitcher;
import org.jgroups.Channel;
import org.jgroups.ChannelException;
+import org.jgroups.ChannelFactory;
import org.jgroups.ChannelListenerAdapter;
import org.jgroups.Event;
import org.jgroups.Global;
import org.jgroups.JChannel;
import org.jgroups.conf.ConfiguratorFactory;
import org.jgroups.conf.ProtocolData;
+import org.jgroups.conf.ProtocolParameter;
import org.jgroups.conf.ProtocolStackConfigurator;
import org.jgroups.jmx.JmxConfigurator;
import org.jgroups.protocols.TP;
@@ -60,10 +77,11 @@
import org.jgroups.util.ThreadFactory;
import org.jgroups.util.ThreadManager;
import org.jgroups.util.Util;
+import org.w3c.dom.Element;
/**
- * Extension to the JGroups JChannelFactory that supports a number of
- * JBoss AS-specific behaviors:
+ * Implementation of the JGroups <code>ChannelFactory</code> that supports a
+ * number of JBoss AS-specific behaviors:
* <p>
* <ul>
* <li>Passing a config event to newly created channels containing
@@ -76,6 +94,7 @@
* <li>Configures the channel's thread pools and thread factories to ensure
* that application thread context classloaders don't leak to the channel
* threads.</li>
+ * <li>Exposes a ProfileService ManagementView interface.</li>
* </ul>
* </p>
*
@@ -84,13 +103,25 @@
*
* @version $Revision$
*/
-public class JChannelFactory extends org.jgroups.JChannelFactory
- implements JChannelFactoryMBean, MBeanRegistration
+ at ManagementObject(name="JChannelFactory",
+ componentType=@ManagementComponent(type="MCBean", subtype="JGroupsChannelFactory"),
+ properties=ManagementProperties.EXPLICIT,
+ isRuntime=true)
+public class JChannelFactory
+ implements ChannelFactory, JChannelFactoryMBean, MBeanRegistration
{
protected static final Logger log = Logger.getLogger(JChannelFactory.class);
+ /**
+ * Prefix prepended to the protocol stack name to create a synthetic
+ * transport protocol <code>singleton_name</code> value for channels
+ * that don't configure a <code>singleton_name</code>.
+ */
public static final String UNSHARED_TRANSPORT_NAME_BASE = "unnamed_";
+ /** Default value for property {@link #getDomain() domain}. */
+ public static final String DEFAULT_JMX_DOMAIN = "jgroups";
+
private static final int CREATED = ServiceMBean.CREATED;
private static final int STARTING = ServiceMBean.STARTING;
private static final int STARTED = ServiceMBean.STARTED;
@@ -107,10 +138,47 @@
private boolean manageNewThreadClassLoader = true;
private boolean manageReleasedThreadClassLoader = false;
private boolean addMissingSingletonName = true;
- private boolean domainSet;
private final ContextClassLoaderSwitcher classLoaderSwitcher;
- private final Set<String> registeredChannels = new HashSet<String>();
+ private final Map<Channel, ChannelInfo> registeredChannels =
+ new ConcurrentHashMap<Channel, ChannelInfo>(16, 0.75f, 2);
+
+ private ChannelCloseListener closeListener = new ChannelCloseListener();
+ /**
+ * Map<String,ProtocolStackConfigurator>. Hashmap which maps stack names to JGroups
+ * configurations. Keys are stack names, values are plain JGroups stack
+ * configs. This is (re-)populated whenever a setMultiplexerConfig() method
+ * is called
+ */
+ private final Map<String,ProtocolStackConfigInfo> stacks =
+ new ConcurrentHashMap<String, ProtocolStackConfigInfo>(16, 0.75f, 2);
+
+ /**
+ * Placeholder for stacks injected via {@link #setProtocolStackConfigurations(Map)}
+ * until createService is called.
+ */
+ private Map<String,ProtocolStackConfigInfo> injectedStacks;
+
+ /**
+ * The MBeanServer to expose JMX management data with (no management data
+ * will be available if null)
+ */
+ private MBeanServer server = null;
+
+ /** To expose the channels and protocols */
+ private String domain = DEFAULT_JMX_DOMAIN;
+ private boolean domainSet = false;
+
+ /** Whether or not to expose channels via JMX */
+ private boolean expose_channels=true;
+
+ /** Whether to expose the factory only, or all protocols as well */
+ private boolean expose_protocols=true;
+
+ /**
+ * Creates a new JChannelFactory.
+ */
+ @SuppressWarnings("unchecked")
public JChannelFactory()
{
this.classLoaderSwitcher = (ContextClassLoaderSwitcher) AccessController.doPrivileged(ContextClassLoaderSwitcher.INSTANTIATOR);
@@ -119,73 +187,80 @@
/**
* Always throws <code>ChannelException</code>; this method is not supported.
*/
- @Override
public Channel createChannel() throws ChannelException
{
throw new ChannelException("No-arg createChannel() is not supported");
}
- @Override
+ /**
+ * Creates a channel by passing <code>properties</code> to the
+ * <code>org.jgroups.JChannel</code> constructor.
+ *
+ * @param properties protocol stack configuration object; can be <code>null</code>
+ * in which case a default stack will be used
+ *
+ * @return the channel
+ */
public Channel createChannel(Object properties) throws ChannelException
{
checkStarted();
-
- @SuppressWarnings("deprecation")
- Channel channel = super.createChannel(properties);
-
- if (manageNewThreadClassLoader || manageReleasedThreadClassLoader)
+
+ if (properties == null)
+ properties = JChannel.DEFAULT_PROTOCOL_STACK;
+
+ ProtocolStackConfigurator config = null;
+
+ try
{
- fixChannelThreadManagement(channel);
+ @SuppressWarnings("deprecation")
+ ProtocolStackConfigurator c = ConfiguratorFactory.getStackConfigurator(properties);
+ config = c;
}
-
- if (assignLogicalAddresses)
+ catch (Exception x)
{
- setChannelUniqueId(channel);
+ throw new ChannelException("unable to load protocol stack", x);
}
-
- // can't register in JMX as we don't have a channel name
-
+
+ JChannel channel = initializeChannel(config, null, false);
+
+ try
+ {
+ registerChannel(channel, null, null, ProtocolStackUtil.getProtocolData(config));
+ }
+ catch (ChannelException ce)
+ {
+ throw ce;
+ }
+ catch (Exception e)
+ {
+ throw new ChannelException("unable to register channel", e);
+ }
+
return channel;
}
/**
* Create a {@link Channel} using the specified stack. Channel will use a
- * shared transport if the <code>singleton-name</code> attribute is
- * set on the stack's transport protocol.
+ * shared transport.
*
- * @param stack_name the name of the stack
- * @return the channel
+ * @param stack_name
+ * The name of the stack to be used. All stacks are defined in
+ * the configuration with which the factory is configured (see
+ * {@link #setMultiplexerConfig(Object)} for example. If
+ * clients attempt to create a Channel for an undefined stack
+ * name an exception will be thrown.
*
+ * @return an implementation of Channel configured with a shared transport.
+ *
+ * @throws IllegalArgumentException if <code>stack_name</code> is
+ * <code>null</code> or {@link #getConfig(String)} returns <code>null</code>
+ * when <code>stack_name</code> is used.
+ *
* @throws Exception
*/
- @Override
public Channel createChannel(String stack_name) throws Exception
{
- checkStarted();
-
- String props=stack_name != null? getConfig(stack_name) : null;
- if (props == null)
- {
- log.warn("No protocol stack found with name " + stack_name +
- "; creating default channel");
- return createChannel();
- }
-
- JChannel channel = new JChannel(props);
-
- if (manageNewThreadClassLoader || manageReleasedThreadClassLoader)
- {
- fixChannelThreadManagement(channel);
- }
-
- if (assignLogicalAddresses)
- {
- setChannelUniqueId(channel);
- }
-
- // can't register in JMX as we don't have a channel name
-
- return channel;
+ return createChannelFromRegisteredStack(stack_name, null, false);
}
/**
@@ -215,12 +290,12 @@
* {@link #setMultiplexerConfig(Object)} for example. If
* clients attempt to create a Channel for an undefined stack
* name an Exception will be thrown.
- * @param id Only used if the transport protocol configuration for the
- * specified stack does not include the <code>singleton_name</code>
- * attribute; then it is used to create a synthetic singleton-name
- * for the channel's protocol stack.
+ * @param id Only used if {@link #isExposeChannels()} returns <code>true</code>,
+ * in which case, if not <code>null</code>, is used as part of
+ * the <code>ObjectName</code> for the JMX mbeans that represent
+ * the channel and its protocols. Can be <code>null</code>.
*
- * @return An implementation of Channel configured with a shared transport.
+ * @return an implementation of Channel configured with a shared transport.
*
* @throws IllegalStateException if the specified protocol stack does not
* declare a <code>singleton_name</code> and
@@ -228,60 +303,10 @@
* <code>false</code>.
* @throws ChannelException
*/
- @Override
public Channel createMultiplexerChannel(String stack_name, String id) throws Exception
{
- checkStarted();
-
- String configStr = getConfig(stack_name);
-
- if (configStr == null)
- throw new IllegalStateException("Unknown stack_name " + stack_name);
-
- ProtocolStackConfigurator config = ConfiguratorFactory.getStackConfigurator(configStr);
- Map<String, String> tpProps = getTransportProperties(config);
-
- if (!tpProps.containsKey(Global.SINGLETON_NAME))
- {
- if (addMissingSingletonName)
- {
- String singletonName = UNSHARED_TRANSPORT_NAME_BASE + stack_name;
-
- log.warn("Config for " + stack_name + " does not include " +
- "singleton_name; adding a name of " + singletonName +
- ". You should configure a singleton_name for this stack.");
-
- config = addSingletonName(config, singletonName);
- log.debug("Stack config after adding singleton_name is " + config.getProtocolStackString());
- tpProps = getTransportProperties(config);
- }
- else
- {
- throw new IllegalStateException("Config for " + stack_name + " does not include " +
- "singleton_name and MuxChannels are not supported.");
- }
- }
-
- JChannel channel = new JChannel(config);
-
- if (manageNewThreadClassLoader || manageReleasedThreadClassLoader)
- {
- fixChannelThreadManagement(channel);
- }
-
- if (assignLogicalAddresses)
- {
- setChannelUniqueId(channel);
- }
-
- if (isExposeChannels() && id != null && id.length() > 0)
- {
- registerChannel(channel, id);
- }
-
- return channel;
+ return createChannelFromRegisteredStack(stack_name, id, true);
}
-
/**
* Creates and returns a shared transport Channel configured with the specified
@@ -303,19 +328,149 @@
* <code>false</code>.
* @throws ChannelException
*/
- @Override
public Channel createMultiplexerChannel(String stack_name, String id, boolean register_for_state_transfer, String substate_id) throws Exception
{
return createMultiplexerChannel(stack_name, id);
}
- @Override
+ /**
+ * {@link #parse(Element) Parses <code>properties</code>} and then adds
+ * the resulting protocol stack configurations to the set available for use.
+ * Same as
+ * {@link #setMultiplexerConfig(Element, boolean) <code>setMultiplexerConfig(properties, true</code>}.
+ *
+ * @param properties document root node for XML content in the JGroups
+ * <code>stacks.xml</code> format
+ */
+ public void setMultiplexerConfig(Element properties) throws Exception
+ {
+ setMultiplexerConfig(properties, true);
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use. Same as
+ * {@link #setMultiplexerConfig(File, boolean) <code>setMultiplexerConfig(properties, true</code>}.
+ *
+ * @param properties file which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ */
+ public void setMultiplexerConfig(File properties) throws Exception
+ {
+ setMultiplexerConfig(properties, true);
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use. Same as
+ * {@link #setMultiplexerConfig(Object, boolean) <code>setMultiplexerConfig(properties, true</code>}.
+ *
+ * @param properties object that can be {@link ConfiguratorFactory#getConfigStream(Object) converted into a stream}
+ * which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ */
+ public void setMultiplexerConfig(Object properties) throws Exception
+ {
+ setMultiplexerConfig(properties, true);
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use. Same as
+ * {@link #setMultiplexerConfig(String, boolean) <code>setMultiplexerConfig(properties, true</code>}.
+ *
+ * @param properties string that can be {@link ConfiguratorFactory#getConfigStream(String) converted into a stream}
+ * which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ */
+ public void setMultiplexerConfig(String properties) throws Exception
+ {
+ setMultiplexerConfig(properties, true);
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use. Same as
+ * {@link #setMultiplexerConfig(URL, boolean) <code>setMultiplexerConfig(properties, true</code>}.
+ *
+ * @param properties URL which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ */
+ public void setMultiplexerConfig(URL properties) throws Exception
+ {
+ setMultiplexerConfig(properties, true);
+ }
+
+ // ------------------------------------------------------------- Properties
+
+ /**
+ * Gets the MBeanServer to use to register mbeans for channels and protocols
+ * we create.
+ *
+ * @return the MBeanServer, or <code>null</code> if one isn't registered
+ */
+ public MBeanServer getServer()
+ {
+ return server;
+ }
+
+ /**
+ * Sets the MBeanServer to use to register mbeans for channels and protocols
+ * we create.
+ *
+ * @param server the MBeanServer. May be <code>null</code>
+ */
+ public void setServer(MBeanServer server)
+ {
+ this.server=server;
+ }
+
+ /**
+ * Gets the domain portion of the JMX ObjectName to use when registering channels and protocols
+ *
+ * @return the domain. Will not return <code>null</code> after {@link #create()}
+ * has been invoked.
+ */
+ @ManagementProperty(use={ViewUse.CONFIGURATION}, description="The domain portion of the JMX ObjectName to use when registering channels and protocols")
+ public String getDomain()
+ {
+ return domain == null ? "jgroups" : domain;
+ }
+
public void setDomain(String domain)
{
- super.setDomain(domain);
- domainSet = true;
+ this.domain = domain;
+ this.domainSet = true;
}
+ @ManagementProperty(use={ViewUse.CONFIGURATION}, description="Whether to expose channels we create via JMX")
+ public boolean isExposeChannels()
+ {
+ return expose_channels;
+ }
+
+ public void setExposeChannels(boolean expose_channels)
+ {
+ this.expose_channels=expose_channels;
+ }
+
+ @ManagementProperty(use={ViewUse.CONFIGURATION}, description="Whether to expose protocols via JMX as well if we expose channels")
+ public boolean isExposeProtocols()
+ {
+ return expose_protocols;
+ }
+
+ public void setExposeProtocols(boolean expose_protocols)
+ {
+ this.expose_protocols=expose_protocols;
+ if (expose_protocols)
+ this.expose_channels=true;
+ }
+
/**
* Get any logical name assigned to this server; if not null this value
* will be the value of the
@@ -324,6 +479,7 @@
*
* @return the logical name for this server, or <code>null</code>.
*/
+ @ManagementProperty(use={ViewUse.CONFIGURATION}, description="The cluster-unique logical name of this node")
public String getNodeName()
{
return nodeName;
@@ -405,6 +561,7 @@
*
* @see #setAssignLogicalAddresses(boolean)
*/
+ @ManagementProperty(use={ViewUse.CONFIGURATION}, description="Whether this factory should assign a logical address for this node to all channels")
public boolean getAssignLogicalAddresses()
{
return assignLogicalAddresses;
@@ -438,6 +595,7 @@
* @return <code>true</code> if the factories should be updated.
* Default is <code>true</code>.
*/
+ @ManagementProperty(use={ViewUse.CONFIGURATION}, description="Whether this factory should update the standard JGroups thread factories to ensure classloader leaks do not occur")
public boolean getManageNewThreadClassLoader()
{
return manageNewThreadClassLoader;
@@ -464,6 +622,7 @@
* @return <code>true</code> if the pools should be updated.
* Default is <code>false</code>.
*/
+ @ManagementProperty(use={ViewUse.CONFIGURATION}, description="Whether this factory should update the standard JGroups thread pools to ensure classloader leaks do not occur")
public boolean getManageReleasedThreadClassLoader()
{
return manageReleasedThreadClassLoader;
@@ -498,6 +657,8 @@
* @return <code>true</code> if synthetic singleton names should be created.
* Default is <code>true</code>.
*/
+ @ManagementProperty(use={ViewUse.CONFIGURATION},
+ description="Whether this factory should create a synthetic singleton name attribute for a channel's transport protocol if one isn't configured")
public boolean getAddMissingSingletonName()
{
return addMissingSingletonName;
@@ -515,8 +676,207 @@
{
this.addMissingSingletonName = addMissingSingletonName;
}
+
+ // ------------------------------------------------------------- Public
- @Override
+ /**
+ * {@link #parse(Element) Parses <code>properties</code>} and then adds
+ * the resulting protocol stack configurations to the set available for use.
+ *
+ * @param properties document root node for XML content in the JGroups
+ * <code>stacks.xml</code> format
+ * @param replace <code>true</code> if a configuration with the same
+ * stack name as an already registered configuration should
+ * replace that configuration; <code>false</code> if it
+ * should be discarded.
+ */
+ public void setMultiplexerConfig(Element properties, boolean replace) throws Exception
+ {
+ Map<String, ProtocolStackConfigInfo> map = ProtocolStackUtil.parse(properties);
+
+ for (Map.Entry<String, ProtocolStackConfigInfo> entry : map.entrySet())
+ {
+ addConfig(entry.getKey(), entry.getValue(), replace);
+ }
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use.
+ *
+ * @param properties file which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ * @param replace <code>true</code> if a configuration with the same
+ * stack name as an already registered configuration should
+ * replace that configuration; <code>false</code> if it
+ * should be discarded.
+ */
+ public void setMultiplexerConfig(File properties, boolean replace) throws Exception
+ {
+ InputStream input=ConfiguratorFactory.getConfigStream(properties);
+ addConfigs(input, properties.toString(), replace);
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use.
+ *
+ * @param properties object that can be {@link ConfiguratorFactory#getConfigStream(Object) converted into a stream}
+ * which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ * @param replace <code>true</code> if a configuration with the same
+ * stack name as an already registered configuration should
+ * replace that configuration; <code>false</code> if it
+ * should be discarded.
+ */
+ public void setMultiplexerConfig(Object properties, boolean replace) throws Exception
+ {
+ InputStream input=ConfiguratorFactory.getConfigStream(properties);
+ addConfigs(input, properties.toString(), replace);
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use.
+ *
+ * @param properties string that can be {@link ConfiguratorFactory#getConfigStream(String) converted into a stream}
+ * which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ * @param replace <code>true</code> if a configuration with the same
+ * stack name as an already registered configuration should
+ * replace that configuration; <code>false</code> if it
+ * should be discarded.
+ */
+ public void setMultiplexerConfig(String properties, boolean replace) throws Exception
+ {
+ InputStream input=ConfiguratorFactory.getConfigStream(properties);
+ addConfigs(input, properties, replace);
+ }
+
+ /**
+ * {@link #parse(InputStream) Parses} an input stream created from
+ * <code>properties</code> and then adds the resulting protocol stack
+ * configurations to the set available for use.
+ *
+ * @param properties URL which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ * @param replace <code>true</code> if a configuration with the same
+ * stack name as an already registered configuration should
+ * replace that configuration; <code>false</code> if it
+ * should be discarded.
+ */
+ public void setMultiplexerConfig(URL url, boolean replace) throws Exception
+ {
+ InputStream input=ConfiguratorFactory.getConfigStream(url);
+ addConfigs(input, url.toString(), replace);
+ }
+
+
+ // -------------------------------------------------------- Management View
+
+ /**
+ * Gets information on channels created by this factory that are currently
+ * open.
+ */
+ @ManagementProperty(use={ViewUse.STATISTIC},
+ description="Information on channels created by this factory that are currently open",
+ readOnly=true)
+ @MetaMapping(value=OpenChannelsMapper.class)
+ public Set<ChannelInfo> getOpenChannels()
+ {
+ return new HashSet<ChannelInfo>(registeredChannels.values());
+ }
+
+ @ManagementProperty(use={ViewUse.CONFIGURATION, ViewUse.RUNTIME},
+ description="Protocol stack configurations available for use")
+ @MetaMapping(value=ProtocolStackConfigurationsMapper.class)
+ public Map<String, ProtocolStackConfigInfo> getProtocolStackConfigurations()
+ {
+ return Collections.unmodifiableMap(stacks);
+ }
+
+ public void setProtocolStackConfigurations(Map<String, ProtocolStackConfigInfo> configs)
+ {
+ this.injectedStacks = configs;
+
+ if (state == STARTED)
+ {
+ // We're already running so this must be a ManagedComponent update
+ // so apply immediately
+ processInjectedStacks();
+ }
+ }
+
+ // --------------------------------------------------- JChannelFactoryMBean
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clearConfigurations()
+ {
+ this.stacks.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String dumpChannels()
+ {
+ return "";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String dumpConfiguration()
+ {
+ return stacks.keySet().toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getConfig(String stack_name) throws Exception
+ {
+ ProtocolStackConfigInfo cfg = stacks.get(stack_name);
+ if (cfg == null)
+ throw new Exception("stack \"" + stack_name + "\" not found in " + stacks.keySet());
+ return cfg.getConfigurator().getProtocolStackString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getMultiplexerConfig()
+ {
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<String, ProtocolStackConfigInfo> entry : stacks.entrySet())
+ {
+ sb.append(entry.getKey()).append(": ").append(entry.getValue().getConfigurator().getProtocolStackString()).append("\n");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean removeConfig(String stack_name)
+ {
+ return stack_name != null && this.stacks.remove(stack_name) != null;
+ }
+
+ // ------------------------------------------------------------- Lifecycle
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This method largely directly concerns itself with the {@link #getStateString() state}
+ * field, delegating the real work to {@link #createService()}.
+ * </p>
+ */
public void create() throws Exception
{
@@ -531,7 +891,7 @@
try
{
- super.create();
+ createService();
state = CREATED;
}
catch (Exception e)
@@ -543,7 +903,13 @@
log.debug("Created JChannelFactory");
}
- @Override
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This method largely directly concerns itself with the {@link #getStateString() state}
+ * field, delegating the real work to {@link #startService()}.
+ * </p>
+ */
public void start() throws Exception
{
if (state == STARTING || state == STARTED || state == STOPPING)
@@ -563,7 +929,7 @@
try
{
- super.start();
+ startService();
}
catch (Exception e)
{
@@ -577,7 +943,13 @@
}
- @Override
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This method largely directly concerns itself with the {@link #getStateString() state}
+ * field, delegating the real work to {@link #stopService()}.
+ * </p>
+ */
public void stop()
{
if (state != STARTED)
@@ -591,7 +963,7 @@
try
{
- super.stop();
+ stopService();
}
catch (Throwable e)
{
@@ -604,7 +976,13 @@
log.debug("Stopped JChannelFactory");
}
- @Override
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This method largely directly concerns itself with the {@link #getStateString() state}
+ * field, delegating the real work to {@link #destroyService()}.
+ * </p>
+ */
public void destroy()
{
if (state == DESTROYED)
@@ -621,21 +999,9 @@
log.debug("Destroying JChannelFactory");
- // DON'T call super.destroy() as that may deregister the JMX proxy
- // to this pojo service, leading to ugliness when the proxy is destroyed
try
- {
-
- Set<String> toUnregister = null;
- synchronized (registeredChannels)
- {
- toUnregister = new HashSet<String>(registeredChannels);
- }
-
- for (String channelId : toUnregister)
- {
- unregister(channelId);
- }
+ {
+ destroyService();
}
catch (Throwable t)
{
@@ -650,14 +1016,13 @@
public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
{
setServer(server);
- if (!domainSet || getDomain() == null)
+ if (!this.domainSet || this.domain == null)
{
setDomain(name.getDomain());
}
return name;
}
-
public void postRegister(Boolean registrationDone)
{
if (registrationDone != null && registrationDone.booleanValue()
@@ -667,7 +1032,6 @@
}
}
-
public void preDeregister() throws Exception
{
}
@@ -678,6 +1042,8 @@
if (state == ServiceMBean.DESTROYED)
state = ServiceMBean.UNREGISTERED;
}
+
+ // --------------------------------------------------------------- Protected
/**
* Gets the classloader that channel threads should be set to if
@@ -693,6 +1059,57 @@
return getClass().getClassLoader();
}
+ protected void createService() throws Exception
+ {
+ if(expose_channels)
+ {
+ if(server == null)
+ {
+ throw new Exception("No MBeanServer found; JChannelFactory needs to " +
+ "be run with an MBeanServer present, or with ExposeChannels " +
+ "set to false");
+ }
+
+ if(domain == null)
+ {
+ domain= DEFAULT_JMX_DOMAIN;
+ }
+ }
+ }
+
+ /**
+ * The actual startup work.
+ *
+ * @throws Exception
+ */
+ protected void startService() throws Exception
+ {
+ // If the ProfileService injected stacks, process them now
+ processInjectedStacks();
+ }
+
+ /**
+ * The actual service stop work. This base implementation does nothing.
+ *
+ * @throws Exception
+ */
+ protected void stopService() throws Exception
+ {
+ // no-op
+ }
+
+ /**
+ * The actual service destruction work.
+ *
+ */
+ protected void destroyService()
+ {
+ for (Channel ch : registeredChannels.keySet())
+ {
+ unregisterChannel(ch);
+ }
+ }
+
// ----------------------------------------------------------------- Private
@@ -702,6 +1119,160 @@
throw new IllegalStateException("Cannot use factory; state is " + getStateString());
}
+ private void addConfigs(InputStream input, String source, boolean replace) throws Exception
+ {
+ if(input == null)
+ {
+ throw new FileNotFoundException(source);
+ }
+
+ Map<String, ProtocolStackConfigInfo> map = null;
+ try
+ {
+ map = ProtocolStackUtil.parse(input);
+ }
+ catch(Exception ex)
+ {
+ throw new Exception("failed parsing " + source, ex);
+ }
+ finally
+ {
+ Util.close(input);
+ }
+
+ for (Map.Entry<String, ProtocolStackConfigInfo> entry : map.entrySet())
+ {
+ addConfig(entry.getKey(), entry.getValue(), replace);
+ }
+ }
+
+ private boolean addConfig(String st_name, ProtocolStackConfigInfo val, boolean replace)
+ {
+ boolean added = replace;
+ if (replace)
+ {
+ stacks.put(st_name, val);
+ if (log.isTraceEnabled())
+ log.trace("added config '" + st_name + "'");
+ }
+ else
+ {
+ if (!stacks.containsKey(st_name))
+ {
+ stacks.put(st_name, val);
+ if (log.isTraceEnabled())
+ log.trace("added config '" + st_name + "'");
+ added = true;
+ }
+ else
+ {
+ if (log.isTraceEnabled())
+ log.trace("didn't add config '" + st_name + " because one of the same name already existed");
+ }
+ }
+ return added;
+ }
+
+ private synchronized void processInjectedStacks()
+ {
+ if (injectedStacks != null)
+ {
+ clearConfigurations();
+ stacks.putAll(injectedStacks);
+ injectedStacks = null;
+ }
+ }
+
+ /**
+ * Creates a channel from one of the known stack configurations.
+ *
+ * @param stack_name the name of the stack config
+ * @param id optional id for the channel
+ * @param forceSingletonStack <code>true</code> if a singleton_name must be
+ * either configured, or addMissingSingletonName must be true
+ *
+ * @return the channel
+ *
+ * @throws IllegalArgumentException if stack_name is unknown
+ * @throws IllegalStateException if forceSingletonStack is <code>true</code>
+ * but a singleton_name couldn't be configured
+ *
+ * @throws Exception
+ */
+ private Channel createChannelFromRegisteredStack(String stack_name, String id, boolean forceSingletonStack) throws Exception
+ {
+ checkStarted();
+
+ ProtocolStackConfigInfo config = stacks.get(stack_name);
+
+ if (config == null)
+ throw new IllegalArgumentException("Unknown stack_name " + stack_name);
+
+ JChannel channel = initializeChannel(config.getConfigurator(), stack_name, forceSingletonStack);
+
+ registerChannel(channel, id, stack_name, ProtocolStackUtil.getProtocolData(config.getConfigurator()));
+
+ return channel;
+ }
+
+ /**
+ * Construct a JChannel from the given config and then do post-construction
+ * processing like fixing up thread managment or setting a unique id.
+ *
+ * @param config the config
+ *
+ * @return the channel
+ *
+ * @throws ChannelException
+ */
+ private JChannel initializeChannel(ProtocolStackConfigurator config, String stack_name,
+ boolean forceSingletonStack) throws ChannelException
+ {
+ Map<String, String> tpProps = getTransportProperties(config);
+
+ if (!tpProps.containsKey(Global.SINGLETON_NAME))
+ {
+ if (addMissingSingletonName && stack_name != null)
+ {
+ String singletonName = UNSHARED_TRANSPORT_NAME_BASE + stack_name;
+
+ log.warn("Config for " + stack_name + " does not include " +
+ "singleton_name; adding a name of " + singletonName +
+ ". You should configure a singleton_name for this stack.");
+
+ config = addSingletonName(config, singletonName);
+ log.debug("Stack config after adding singleton_name is " + config.getProtocolStackString());
+ tpProps = getTransportProperties(config);
+ }
+ else if (forceSingletonStack)
+ {
+ throw new IllegalStateException("Config for " + stack_name + " does not include " +
+ "singleton_name and MuxChannels are not supported.");
+ }
+ }
+ JChannel channel = new JChannel(config);
+
+ if (manageNewThreadClassLoader || manageReleasedThreadClassLoader)
+ {
+ fixChannelThreadManagement(channel);
+ }
+
+ if (assignLogicalAddresses)
+ {
+ setChannelUniqueId(channel);
+ }
+
+ return channel;
+ }
+
+ /**
+ * Gets the current runtime lifecycle state (e.g. CREATED, STARTED).
+ */
+ private String getStateString()
+ {
+ return ServiceMBean.states[state];
+ }
+
private void setChannelUniqueId(Channel channel)
{
IpAddress address = (IpAddress) channel.getLocalAddress();
@@ -734,11 +1305,6 @@
"additional data -- setting nodeName to " + nodeName);
}
}
-
- private String getStateString()
- {
- return ServiceMBean.states[state];
- }
private String generateUniqueNodeName ()
{
@@ -776,9 +1342,9 @@
else
{
log.warn("JNDI has been found but the service wasn't started. Most likely, " +
- "HAPartition bean is missing dependency on JBoss Naming. " +
- "Instead using host based UID strategy for defining a node " +
- "GUID for the cluster.");
+ "HAPartition bean is missing dependency on JBoss Naming. " +
+ "Instead using host based UID strategy for defining a node " +
+ "GUID for the cluster.");
}
// 2nd: host-GUID strategy
@@ -790,28 +1356,15 @@
private Map<String, String> getTransportProperties(ProtocolStackConfigurator config)
{
Map<String, String> tpProps = null;
- try
+ ProtocolData[] protocols= ProtocolStackUtil.getProtocolData(config);
+ ProtocolData transport=protocols[0];
+ @SuppressWarnings("unchecked")
+ Map<String,ProtocolParameter> tmp=transport.getParameters();
+ tpProps = new HashMap<String,String>();
+ for(Map.Entry<String,ProtocolParameter> entry: tmp.entrySet())
{
- ProtocolData[] protocols=config.getProtocolStack();
- ProtocolData transport=protocols[0];
- tpProps = transport.getParameters();
+ tpProps.put(entry.getKey(), entry.getValue().getValue());
}
- catch (UnsupportedOperationException uoe)
- {
- // JGroups version hasn't implemented ProtocolStackConfigurator.getProtocolStack()
- // So we do it ourselves
- String configStr = config.getProtocolStackString();
- String tpConfigStr = configStr.substring(configStr.indexOf('(') + 1, configStr.indexOf(')'));
- String[] params = tpConfigStr.split(";");
- tpProps = new HashMap<String, String>();
- for (String param : params)
- {
- String[] keyVal = param.split("=");
- if (keyVal.length != 2)
- throw new IllegalStateException("Invalid parameter " + param + " in stack " + configStr);
- tpProps.put(keyVal[0], keyVal[1]);
- }
- }
return tpProps;
}
@@ -824,9 +1377,8 @@
{
ProtocolData[] protocols=orig.getProtocolStack();
ProtocolData transport=protocols[0];
- Map<String, String> tpProps = transport.getParameters();
- tpProps.put(Global.SINGLETON_NAME, singletonName);
- // we've now updated the state of orig; just return it
+ ProtocolParameter singletonParam = new ProtocolParameter(Global.SINGLETON_NAME, singletonName);
+ transport.override(new ProtocolParameter[]{ singletonParam});
result = orig;
}
catch (UnsupportedOperationException uoe)
@@ -1009,40 +1561,124 @@
classLoaderSwitcher.setContextClassLoader(thread, classLoader);
}
- private void registerChannel(JChannel ch, String channelId) throws Exception
+ private void registerChannel(JChannel ch, String channelId, String stackName, ProtocolData[] config) throws Exception
{
- if(getServer() != null)
+ // Register for channel closed notification so we can unregister
+ ch.addChannelListener(closeListener);
+
+ ObjectName chName = null;
+ List<ObjectName> protNames = null;
+ List<ObjectName> allNames = registerInJmx(ch, channelId);
+ if (allNames != null && allNames.size() > 0)
{
- // Register for channel closed notification so we can unregister
- JmxDeregistrationChannelListener listener = new JmxDeregistrationChannelListener(channelId);
- ch.addChannelListener(listener);
- JmxConfigurator.registerChannel(ch, getServer(), getDomain(), channelId, isExposeProtocols());
- synchronized (registeredChannels)
+ chName = allNames.get(0);
+ if (allNames.size() > 1)
{
- registeredChannels.add(channelId);
+ protNames = allNames.subList(1, allNames.size());
}
}
+
+ ChannelInfo info = new ChannelInfo(channelId, stackName, ch, config, chName, protNames);
+ registeredChannels.put(ch, info);
}
- private void unregister(String channelId)
+ private List<ObjectName> registerInJmx(JChannel ch, String channelId) throws Exception
{
- if(getServer() != null && registeredChannels.contains(channelId))
+ List<ObjectName> allNames = null;
+
+ if(isExposeChannels() && getServer() != null && channelId != null && channelId.length() > 0)
{
- String oname = getDomain() + ":type=channel,cluster=" + channelId;
- try
+ allNames = new ArrayList<ObjectName>();
+ ObjectName channelName = new ObjectName(getDomain() + ":type=channel,cluster=" + channelId);
+ getServer().registerMBean(new org.jgroups.jmx.JChannel(ch), channelName);
+ allNames.add(channelName);
+ if (isExposeProtocols())
{
- getServer().unregisterMBean(new ObjectName(oname));
- oname = getDomain() + ":type=protocol,cluster=" + channelId + ",*";
- JmxConfigurator.unregister(getServer(), oname);
- synchronized (registeredChannels)
+ String baseName = getDomain() + ":type=protocol,cluster=" + channelId;
+ ProtocolStack stack=ch.getProtocolStack();
+ List<Protocol> protocols=stack.getProtocols();
+
+ for(Protocol prot : protocols)
{
- registeredChannels.remove(channelId);
+ org.jgroups.jmx.Protocol p=null;
+ try {
+ String prot_name = prot.getClass().getName();
+ String clname = prot_name.replaceFirst("org.jgroups.", "org.jgroups.jmx.");
+ Class<?> cl = Util.loadClass(clname, JmxConfigurator.class);
+ if (cl != null)
+ {
+ p = (org.jgroups.jmx.Protocol) cl.newInstance();
+ }
+ }
+ catch(ClassNotFoundException e)
+ {
+ // ignore;
+ }
+ catch(Throwable e) {
+ log.error("failed creating a JMX wrapper instance for " + prot, e);
+ p = null;
+ }
+ if(p == null)
+ {
+ // Use default
+ p = new org.jgroups.jmx.Protocol(prot);
+ }
+ ObjectName prot_name=new ObjectName(baseName + ",protocol=" + prot.getName());
+ server.registerMBean(p, prot_name);
+ allNames.add(prot_name);
}
}
+ }
+
+ return allNames;
+ }
+
+ private void unregisterChannel(Channel ch)
+ {
+ ChannelInfo info = registeredChannels.remove(ch);
+ if (info == null)
+ {
+ log.warn("Unknown channel " + ch.getClusterName());
+ }
+ else
+ {
+ unregisterFromJmx(info);
+ }
+
+ ch.removeChannelListener(closeListener);
+ }
+
+ private void unregisterFromJmx(ChannelInfo info)
+ {
+ ObjectName oname = info.getChannelObjectName();
+ MBeanServer mbs = getServer();
+ if(info != null && mbs != null)
+ {
+ try
+ {
+ mbs.unregisterMBean(oname);
+ }
catch(Exception e)
{
log.error("failed unregistering " + oname, e);
}
+
+ List<ObjectName> onames = info.getProtocolObjectNames();
+ if (onames != null)
+ {
+ for (ObjectName protName : onames)
+ {
+ try
+ {
+ mbs.unregisterMBean(protName);
+ }
+ catch(Exception e)
+ {
+ log.error("failed unregistering " + protName, e);
+ }
+
+ }
+ }
}
}
@@ -1082,18 +1718,11 @@
}
- private class JmxDeregistrationChannelListener extends ChannelListenerAdapter
+ private class ChannelCloseListener extends ChannelListenerAdapter
{
- private final String channelId;
-
- JmxDeregistrationChannelListener(String channelId)
- {
- this.channelId = channelId;
- }
-
public void channelClosed(Channel channel)
{
- unregister(channelId);
+ unregisterChannel(channel);
}
}
Modified: branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactoryMBean.java
===================================================================
--- branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactoryMBean.java 2009-06-22 17:04:50 UTC (rev 90502)
+++ branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/JChannelFactoryMBean.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -27,9 +27,7 @@
import org.jgroups.ChannelException;
/**
- * StandardMBean interface for {@link JChannelFactory}. Based on the
- * <code>org.jgroups.jmx.JChannelFactoryMBean</code> interface, which
- * is scheduled to be removed.
+ * StandardMBean interface for {@link JChannelFactory}.
* <p>
* The plain-old-java-interface for the channel factory is
* <code>org.jgroups.ChannelFactory</code>; users are encouraged to dependency
@@ -130,7 +128,7 @@
void setExposeProtocols(boolean f);
/**
- * Returns the stack configuration as a string (valid to be fed into new JChannel()). Throws an exception
+ * Returns the stack configuration as a string (valid to be fed into new JChannel(String)). Throws an exception
* if the stack_name is not found. One of the setMultiplexerConfig() methods had to be called beforehand.
*
* @return The protocol stack config as a plain string
@@ -154,9 +152,19 @@
* shared transport if the <code>singleton-name</code> attribute is
* set on the stack's transport protocol.
*
- * @param stack_name the name of the stack
+ * @param stack_name
+ * The name of the stack to be used. All stacks are defined in
+ * the configuration with which the factory is configured (see
+ * {@link #setMultiplexerConfig(Object)} for example. If
+ * clients attempt to create a Channel for an undefined stack
+ * name an exception will be thrown.
+ *
* @return the channel
*
+ * @throws IllegalArgumentException if <code>stack_name</code> is
+ * <code>null</code> or {@link #getConfig(String)} returns <code>null</code>
+ * when <code>stack_name</code> is used.
+ *
* @throws Exception
*/
Channel createChannel(String stack_name) throws Exception;
Copied: branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackConfigInfo.java (from rev 90500, trunk/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackConfigInfo.java)
===================================================================
--- branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackConfigInfo.java (rev 0)
+++ branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackConfigInfo.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ha.framework.server;
+
+import org.jgroups.conf.ProtocolData;
+import org.jgroups.conf.ProtocolStackConfigurator;
+
+/**
+ *
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class ProtocolStackConfigInfo
+{
+ private final String name;
+ private final String description;
+ private final ProtocolStackConfigurator configurator;
+
+ public ProtocolStackConfigInfo(String name, String description, ProtocolStackConfigurator configurator)
+ {
+ if (name == null)
+ {
+ throw new IllegalArgumentException("null name");
+ }
+ if (configurator == null)
+ {
+ throw new IllegalArgumentException("null configurator");
+ }
+ this.name = name;
+ this.description = description;
+ this.configurator = configurator;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ ProtocolStackConfigurator getConfigurator()
+ {
+ return configurator;
+ }
+
+ public ProtocolData[] getConfiguration()
+ {
+ return ProtocolStackUtil.getProtocolData(configurator);
+ }
+}
Copied: branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackUtil.java (from rev 90500, trunk/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackUtil.java)
===================================================================
--- branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackUtil.java (rev 0)
+++ branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/ProtocolStackUtil.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -0,0 +1,217 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ha.framework.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.jboss.logging.Logger;
+import org.jgroups.conf.ConfiguratorFactory;
+import org.jgroups.conf.ProtocolData;
+import org.jgroups.conf.ProtocolParameter;
+import org.jgroups.conf.ProtocolStackConfigurator;
+import org.jgroups.conf.XmlConfigurator;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Utilities related to JGroups protocol stack manipulation.
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public final class ProtocolStackUtil
+{
+ private static final Logger log = Logger.getLogger(ProtocolStackUtil.class);
+
+ private static final String PROTOCOL_STACKS="protocol_stacks";
+ private static final String STACK="stack";
+ private static final String NAME="name";
+ private static final String DESCR="description";
+ private static final String CONFIG="config";
+
+ /**
+ * Parses the contents of <code>input</code> into a map of the
+ * protocol stack configurations contained in the XML.
+ *
+ * @param input stream which must contain XML content in the JGroups
+ * <code>stacks.xml</code> format
+ *
+ * @return a map of the protocol stack configurations contained in the XML
+ *
+ * @throws IllegalArgumentException if <code>input</code> is <code>null</code>
+ * @throws Exception
+ */
+ public static Map<String, ProtocolStackConfigInfo> parse(InputStream input) throws Exception
+ {
+ if (input == null)
+ {
+ throw new IllegalArgumentException("null input");
+ }
+
+ DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
+ factory.setValidating(false); //for now
+ DocumentBuilder builder=factory.newDocumentBuilder();
+ Document document=builder.parse(input);
+
+ // The root element of the document should be the "config" element,
+ // but the parser(Element) method checks this so a check is not
+ // needed here.
+ Element configElement = document.getDocumentElement();
+ return parse(configElement);
+ }
+
+ /**
+ * Parses the contents of <code>root</code> into a map of the
+ * protocol stack configurations contained in the XML.
+ *
+ * @param root document root node for XML content in the JGroups
+ * <code>stacks.xml</code> format
+ *
+ * @return a map of the protocol stack configurations contained in the XML
+ *
+ * @throws IllegalArgumentException if <code>input</code> is <code>null</code>
+ * @throws Exception
+ */
+ public static Map<String, ProtocolStackConfigInfo> parse(Element root) throws Exception
+ {
+ if (root == null)
+ {
+ throw new IllegalArgumentException("null root");
+ }
+
+ String root_name = root.getNodeName();
+ if (!PROTOCOL_STACKS.equals(root_name.trim().toLowerCase()))
+ {
+ throw new IOException("Invalid XML configuration: configuration does not start with a '" +
+ PROTOCOL_STACKS + "' element");
+ }
+
+ Map<String, ProtocolStackConfigInfo> result = new HashMap<String, ProtocolStackConfigInfo>();
+
+ NodeList tmp_stacks = root.getChildNodes();
+ for (int i = 0; i < tmp_stacks.getLength(); i++)
+ {
+ Node node = tmp_stacks.item(i);
+ if (node.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+
+ Element stack = (Element) node;
+ String tmp = stack.getNodeName();
+ if (!STACK.equals(tmp.trim().toLowerCase()))
+ {
+ throw new IOException("Invalid configuration: didn't find a \"" + STACK + "\" element under \""
+ + PROTOCOL_STACKS + "\"");
+ }
+
+ NamedNodeMap attrs = stack.getAttributes();
+ Node name = attrs.getNamedItem(NAME);
+ String st_name = name.getNodeValue();
+ Node descr=attrs.getNamedItem(DESCR);
+ String stack_descr=descr.getNodeValue();
+ if (log.isTraceEnabled())
+ {
+ log.trace("Parsing \"" + st_name + "\" (" + stack_descr + ")");
+ }
+ NodeList configs = stack.getChildNodes();
+ for (int j = 0; j < configs.getLength(); j++)
+ {
+ Node tmp_config = configs.item(j);
+ if (tmp_config.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+ Element cfg = (Element) tmp_config;
+ tmp = cfg.getNodeName();
+ if (!CONFIG.equals(tmp))
+ {
+ throw new IOException("Invalid configuration: didn't find a \"" +
+ CONFIG + "\" element under \"" + STACK + "\"");
+ }
+
+ XmlConfigurator conf = XmlConfigurator.getInstance(cfg);
+ // fixes http://jira.jboss.com/jira/browse/JGRP-290
+ ConfiguratorFactory.substituteVariables(conf); // replace vars with system props
+
+ result.put(st_name, new ProtocolStackConfigInfo(st_name, stack_descr, conf));
+ }
+ }
+
+ return result;
+ }
+
+ public static ProtocolData[] getProtocolData(ProtocolStackConfigurator config)
+ {
+ ProtocolData[] result = null;
+ try
+ {
+ result = config.getProtocolStack();
+ }
+ catch (UnsupportedOperationException e)
+ {
+ String s = config.getProtocolStackString();
+ String[] prots = s.split(":");
+ result = new ProtocolData[prots.length];
+ for (int i = 0; i < prots.length; i++)
+ {
+ ProtocolParameter[] params = null;
+ int paren = prots[i].indexOf('(');
+ String name = paren > - 1 ? prots[i].substring(0, paren) : prots[1];
+ if (paren > -1 && paren < prots[1].length() - 2)
+ {
+ String unsplit = prots[i].substring(paren + 1, prots[i].length() -1);
+ String[] split = unsplit.split(";");
+ params = new ProtocolParameter[split.length];
+ for (int j = 0; j < split.length; j++)
+ {
+ String[] keyVal = split[j].split("=");
+ params[j] = new ProtocolParameter(keyVal[0], keyVal[1]);
+ }
+ }
+ else
+ {
+ params = new ProtocolParameter[0];
+ }
+
+ result[i] = new ProtocolData(name, null, name, params);
+ }
+ }
+
+ return result == null ? new ProtocolData[0] : result;
+ }
+
+ /**
+ * Prevent instantiation.
+ */
+ private ProtocolStackUtil()
+ {
+ }
+
+}
Copied: branches/Branch_5_x/cluster/src/main/org/jboss/ha/framework/server/managed (from rev 90500, trunk/cluster/src/main/org/jboss/ha/framework/server/managed)
Copied: branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/channelfactory (from rev 90500, trunk/testsuite/src/main/org/jboss/test/cluster/channelfactory)
Copied: branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ChannelFactoryManagedObjectsTestCase.java (from rev 90500, trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ChannelFactoryManagedObjectsTestCase.java)
===================================================================
--- branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ChannelFactoryManagedObjectsTestCase.java (rev 0)
+++ branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ChannelFactoryManagedObjectsTestCase.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -0,0 +1,317 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.cluster.defaultcfg.test;
+
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import org.jboss.deployers.spi.management.ManagementView;
+import org.jboss.managed.api.ComponentType;
+import org.jboss.managed.api.ManagedComponent;
+import org.jboss.managed.api.ManagedObject;
+import org.jboss.managed.api.ManagedProperty;
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.values.CollectionValue;
+import org.jboss.metatype.api.values.CollectionValueSupport;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.MapCompositeValueSupport;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.metatype.api.values.SimpleValueSupport;
+import org.jboss.profileservice.spi.ProfileService;
+import org.jboss.test.JBossClusteredTestCase;
+import org.jboss.test.cluster.channelfactory.managed.ManagedObjectTestUtil;
+import org.jboss.virtual.VFS;
+
+/**
+ * Validates the expected ChannelFactory-related ManagedObjects are there
+ *
+ * @author Brian Stansberry
+ * @version $Revision: 90011 $
+ */
+public class ChannelFactoryManagedObjectsTestCase
+ extends JBossClusteredTestCase
+{
+ protected ManagementView activeView;
+
+ public ChannelFactoryManagedObjectsTestCase(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Look at the JGroups ChannelFactory ManagedComponent
+ * @throws Exception
+ */
+ public void testChannelFactory()
+ throws Exception
+ {
+ ManagedComponent mc = getChannelFactoryManagedComponent();
+ assertNotNull(mc);
+ assertEquals("JChannelFactory", mc.getNameType());
+ assertEquals("JChannelFactory", mc.getName());
+
+ for (Map.Entry<String, ManagedProperty> entry : mc.getProperties().entrySet())
+ {
+ getLog().debug(entry.getKey() + " == " + entry.getValue());
+ ManagedObject mo = entry.getValue().getTargetManagedObject();
+ if (mo != null)
+ {
+ getLog().debug(entry.getKey() + " -- ManagedObject == " + mo);
+ }
+ }
+
+ ManagedProperty prop = mc.getProperty("domain");
+ assertNotNull("ChannelFactory has property domain", prop);
+ MetaValue metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ Object val = ((SimpleValue) metaVal).getValue();
+ assertEquals("jboss.jgroups", val);
+
+ prop = mc.getProperty("exposeChannels");
+ assertNotNull("ChannelFactory has property exposeChannels", prop);
+ metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ val = ((SimpleValue) metaVal).getValue();
+ assertEquals(Boolean.TRUE, val);
+
+ prop = mc.getProperty("exposeProtocols");
+ assertNotNull("ChannelFactory has property exposeProtocols", prop);
+ metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ val = ((SimpleValue) metaVal).getValue();
+ assertEquals(Boolean.TRUE, val);
+
+ prop = mc.getProperty("nodeName");
+ assertNotNull("ChannelFactory has property nodeName", prop);
+ metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ val = ((SimpleValue) metaVal).getValue();
+ assertNotNull(val);
+ assertTrue(val instanceof String);
+
+ prop = mc.getProperty("assignLogicalAddresses");
+ assertNotNull("ChannelFactory has property assignLogicalAddresses", prop);
+ metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ val = ((SimpleValue) metaVal).getValue();
+ assertEquals(Boolean.TRUE, val);
+
+ prop = mc.getProperty("manageNewThreadClassLoader");
+ assertNotNull("ChannelFactory has property manageNewThreadClassLoader", prop);
+ metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ val = ((SimpleValue) metaVal).getValue();
+ assertEquals(Boolean.TRUE, val);
+
+ prop = mc.getProperty("manageReleasedThreadClassLoader");
+ assertNotNull("ChannelFactory has property manageReleasedThreadClassLoader", prop);
+ metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ val = ((SimpleValue) metaVal).getValue();
+ assertTrue(val instanceof Boolean);
+
+ prop = mc.getProperty("addMissingSingletonName");
+ assertNotNull("ChannelFactory has property addMissingSingletonName", prop);
+ metaVal = prop.getValue();
+ assertTrue(metaVal instanceof SimpleValue);
+ val = ((SimpleValue) metaVal).getValue();
+ assertEquals(Boolean.TRUE, val);
+
+ prop = mc.getProperty("state");
+ assertNotNull("ChannelFactory has property state", prop);
+
+ // FIXME ProfileService messes with this prop -- figure out how to validate
+// metaVal = prop.getValue();
+// assertNotNull(metaVal);
+// assertTrue(metaVal instanceof SimpleValue);
+// val = ((SimpleValue) metaVal).getValue();
+// assertEquals(ServiceMBean.states[ServiceMBean.STARTED], val);
+
+ prop = mc.getProperty("protocolStackConfigurations");
+ assertNotNull("ChannelFactory has property protocolStackConfigurations", prop);
+ metaVal = prop.getValue();
+ ManagedObjectTestUtil.validateProtocolStackConfigurations(metaVal, new String[]{"udp", "tcp"});
+
+ prop = mc.getProperty("openChannels");
+ assertNotNull("ChannelFactory has property openChannels", prop);
+ try
+ {
+ metaVal = prop.getValue();
+ }
+ catch (UndeclaredThrowableException ute)
+ {
+ log.error("Undeclared throwable: ", ute.getUndeclaredThrowable());
+ }
+ ManagedObjectTestUtil.validateOpenChannels(metaVal);
+ }
+
+ public void testUpdateProtocolStackConfigurations() throws Exception
+ {
+ ManagedComponent component = getChannelFactoryManagedComponent();
+ ManagedProperty prop = component.getProperty("protocolStackConfigurations");
+ MetaValue mapValue = prop.getValue();
+ assertTrue(mapValue instanceof CompositeValue);
+ MetaValue stackValue = ((CompositeValue) mapValue).get("udp-async");
+ assertTrue(stackValue instanceof CompositeValue);
+ MetaValue configurationValue = ((CompositeValue) stackValue).get("configuration");
+ assertTrue(configurationValue instanceof CollectionValue);
+ MetaValue[] protocols = ((CollectionValue) configurationValue).getElements();
+ MetaValue udp = protocols[0];
+ assertTrue(udp instanceof CompositeValue);
+ MetaValue parametersValue = ((CompositeValue) udp).get("protocolParameters");
+ assertTrue(parametersValue instanceof CompositeValue);
+ Set<String> params = ((CompositeValue) parametersValue).getMetaType().keySet();
+ int maxThreads = -1;
+ MapCompositeValueSupport newVal = null;
+ for (String name : params)
+ {
+ if ("oob_thread_pool.max_threads".equals(name))
+ {
+ CompositeValue param = (CompositeValue) ((CompositeValue) parametersValue).get(name);
+ String value = (String) ((SimpleValue) param.get("value")).getValue();
+ maxThreads = Integer.parseInt(value);
+ newVal = cloneCompositeValue(param);
+ newVal.put("value", SimpleValueSupport.wrap(String.valueOf(maxThreads + 1)));
+ break;
+ }
+ }
+ assertNotNull("updated max_threads config", newVal);
+
+ MapCompositeValueSupport newParametersValue = cloneCompositeValue((CompositeValue) parametersValue);
+ newParametersValue.put("oob_thread_pool.max_threads", newVal);
+ MapCompositeValueSupport newUdp = cloneCompositeValue((CompositeValue) udp);
+ newUdp.put("protocolParameters", newParametersValue);
+ protocols[0] = newUdp;
+ CollectionValue newConfigurationValue =
+ new CollectionValueSupport(((CollectionValue) configurationValue).getMetaType(), protocols);
+ MapCompositeValueSupport updatedStack = cloneCompositeValue((CompositeValue) stackValue);
+ updatedStack.put("configuration", newConfigurationValue);
+ MapCompositeValueSupport newMapValue = cloneCompositeValue((CompositeValue) mapValue);
+ newMapValue.put("udp-async", updatedStack);
+
+ // Add a stack
+ MapCompositeValueSupport newStack = cloneCompositeValue((CompositeValue) stackValue);
+ newStack.put("name", SimpleValueSupport.wrap("new-stack"));
+ newMapValue.put("new-stack", newStack);
+
+ // Remove a stack
+ newMapValue.remove("tcp-async");
+
+ // Store the updates
+ prop.setValue(newMapValue);
+ getManagementView().updateComponent(component);
+
+ // Re-read the component and validate the changes took
+
+ component = getChannelFactoryManagedComponent();
+ prop = component.getProperty("protocolStackConfigurations");
+ mapValue = prop.getValue();
+ assertTrue(mapValue instanceof CompositeValue);
+ stackValue = ((CompositeValue) mapValue).get("udp-async");
+ assertTrue(stackValue instanceof CompositeValue);
+ configurationValue = ((CompositeValue) stackValue).get("configuration");
+ assertTrue(configurationValue instanceof CollectionValue);
+ protocols = ((CollectionValue) configurationValue).getElements();
+ udp = protocols[0];
+ assertTrue(udp instanceof CompositeValue);
+ parametersValue = ((CompositeValue) udp).get("protocolParameters");
+ assertTrue(parametersValue instanceof CompositeValue);
+ params = ((CompositeValue) parametersValue).getMetaType().keySet();
+ boolean sawIt = false;
+ for (String name : params)
+ {
+ if ("oob_thread_pool.max_threads".equals(name))
+ {
+ CompositeValue param = (CompositeValue) ((CompositeValue) parametersValue).get(name);
+
+ String value = (String) ((SimpleValue) param.get("value")).getValue();
+ assertEquals(String.valueOf(maxThreads + 1), value);
+ sawIt = true;
+ break;
+ }
+ }
+ assertTrue(sawIt);
+
+ assertTrue(((CompositeValue) mapValue).containsKey("new-stack"));
+ assertFalse(((CompositeValue) mapValue).containsKey("tcp-async"));
+ }
+
+ private ManagedComponent getChannelFactoryManagedComponent() throws Exception
+ {
+ ManagementView mgtView = getManagementView();
+ ComponentType type = new ComponentType("MCBean", "JGroupsChannelFactory");
+ ManagedComponent mc = mgtView.getComponent("JChannelFactory", type);
+ return mc;
+ }
+
+ /**
+ * Obtain the ProfileService.ManagementView
+ * @return
+ * @throws Exception
+ */
+ protected ManagementView getManagementView()
+ throws Exception
+ {
+ if( activeView == null )
+ {
+ String[] urls = getNamingURLs();
+ Properties env = new Properties();
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+ "org.jnp.interfaces.NamingContextFactory");
+ env.setProperty(Context.PROVIDER_URL, urls[0]);
+ Context ctx = new InitialContext(env);
+
+ ProfileService ps = (ProfileService) ctx.lookup("ProfileService");
+ activeView = ps.getViewManager();
+ // Init the VFS to setup the vfs* protocol handlers
+ VFS.init();
+ }
+ activeView.load();
+ return activeView;
+ }
+
+ private static MapCompositeValueSupport cloneCompositeValue(CompositeValue toClone)
+ {
+ if (toClone instanceof MapCompositeValueSupport)
+ {
+ return (MapCompositeValueSupport) toClone.clone();
+ }
+ else
+ {
+ CompositeMetaType type = toClone.getMetaType();
+ Map<String, MetaValue> map = new HashMap<String, MetaValue>();
+ for (String key : type.keySet())
+ {
+ map.put(key, toClone.get(key));
+ }
+ return new MapCompositeValueSupport(map, type);
+ }
+ }
+
+}
Modified: branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java
===================================================================
--- branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java 2009-06-22 17:04:50 UTC (rev 90502)
+++ branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -69,6 +69,12 @@
haProxyFailoverTest("jmx/HAServicePooled");
}
+ public void testHttpHAProxyFailover()
+ throws Exception
+ {
+ haProxyFailoverTest("jmx/HAServiceHttp");
+ }
+
public void testJRMPHAProxyFailover()
throws Exception
{
Copied: branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryOverrideUnitTestCase.java (from rev 90501, trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryOverrideUnitTestCase.java)
===================================================================
--- branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryOverrideUnitTestCase.java (rev 0)
+++ branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryOverrideUnitTestCase.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -0,0 +1,231 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.jboss.ha.framework.server.JChannelFactory;
+import org.jboss.ha.framework.server.ProtocolStackConfigInfo;
+import org.jboss.ha.framework.server.managed.ProtocolDataProtocolStackConfigurator;
+import org.jboss.logging.Logger;
+import org.jgroups.Channel;
+import org.jgroups.JChannel;
+import org.jgroups.conf.ProtocolData;
+import org.jgroups.conf.ProtocolParameter;
+
+/**
+ * Tests JChannelFactory's handling of configuration overrides via
+ * @[link {@link JChannelFactory#setProtocolStackConfigurations(java.util.Map)}}
+ *
+ * @author Brian Stansberry
+ */
+public class JChannelFactoryOverrideUnitTestCase extends TestCase
+{
+ private static final Logger log = Logger.getLogger(JChannelFactoryOverrideUnitTestCase.class);
+
+ private JChannelFactory factory;
+ private Channel channel1;
+ private Channel channel2;
+ private String jgroups_bind_addr;
+
+ /**
+ * Create a new JChannelFactoryUnitTestCase.
+ *
+ * @param name
+ */
+ public JChannelFactoryOverrideUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ jgroups_bind_addr = System.getProperty("jgroups.bind_addr");
+ if (jgroups_bind_addr == null)
+ {
+ System.setProperty("jbosstest.cluster.node0", System.getProperty("jbosstest.cluster.node0", "localhost"));
+ }
+
+ factory = new JChannelFactory();
+ factory.setAssignLogicalAddresses(false);
+ factory.setNodeAddress(InetAddress.getByName("localhost"));
+ factory.setNamingServicePort(123);
+ factory.setExposeChannels(false);
+ factory.setManageReleasedThreadClassLoader(true);
+ }
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (jgroups_bind_addr == null)
+ System.clearProperty("jgroups.bind_addr");
+
+ if (channel1 != null && channel1.isOpen())
+ channel1.close();
+
+ if (channel2 != null && channel2.isOpen())
+ channel2.close();
+
+ if (factory != null)
+ {
+ factory.stop();
+ factory.destroy();
+ }
+ }
+
+ public void testOverrideAfterStart() throws Exception
+ {
+ overrideTest(true);
+ }
+
+ public void testOverrideBeforeStart() throws Exception
+ {
+ overrideTest(false);
+ }
+
+ private void overrideTest(boolean startBeforeOverride) throws Exception
+ {
+ factory.setMultiplexerConfig("cluster/channelfactory/stacks.xml");
+ if (startBeforeOverride)
+ {
+ factory.create();
+ factory.start();
+ }
+
+ Map<String, ProtocolStackConfigInfo> origMap = factory.getProtocolStackConfigurations();
+ Set<String> origKeys = new HashSet<String>(origMap.keySet());
+ ProtocolStackConfigInfo unshared1 = origMap.get("unshared1");
+ assertNotNull(unshared1);
+ ProtocolData[] origConfig = unshared1.getConfiguration();
+ assertNotNull(origConfig);
+ // Copy it off so we know it's unchanged for later assertion comparisons
+ origConfig = origConfig.clone();
+ ProtocolData origTransport = origConfig[0];
+ assertNotNull(origTransport);
+ ProtocolParameter[] origParams = origTransport.getParametersAsArray();
+ ProtocolParameter[] newParams = origParams.clone();
+ ProtocolData newTransport = new ProtocolData(origTransport.getProtocolName(), origTransport.getDescription(), origTransport.getClassName(), newParams);
+ ProtocolParameter overrideParam = new ProtocolParameter("max_bundle_size", "50000");
+ newTransport.override(new ProtocolParameter[]{overrideParam});
+ ProtocolData[] newConfig = origConfig.clone();
+ newConfig[0] = newTransport;
+
+ ProtocolStackConfigInfo updated = new ProtocolStackConfigInfo(unshared1.getName(), unshared1.getDescription(), new ProtocolDataProtocolStackConfigurator(newConfig));
+
+ Map<String, ProtocolStackConfigInfo> newMap = new HashMap<String, ProtocolStackConfigInfo>(origMap);
+ newMap.put("unshared1", updated);
+
+ ProtocolData[] addedConfig = origConfig.clone();
+ ProtocolStackConfigInfo added = new ProtocolStackConfigInfo("added", "added", new ProtocolDataProtocolStackConfigurator(addedConfig));
+ newMap.put("added", added);
+
+ assertTrue(newMap.containsKey("shared2"));
+ newMap.remove("shared2");
+
+ factory.setProtocolStackConfigurations(newMap);
+
+ if (startBeforeOverride == false)
+ {
+ factory.create();
+ factory.start();
+ }
+
+ Map<String, ProtocolStackConfigInfo> reread = factory.getProtocolStackConfigurations();
+ origKeys.remove("shared2");
+ origKeys.add("added");
+ assertEquals(origKeys, reread.keySet());
+
+ ProtocolStackConfigInfo addedInfo = reread.get("added");
+ assertEquals("added", addedInfo.getName());
+ assertEquals("added", addedInfo.getDescription());
+ ProtocolData[] readAdded = addedInfo.getConfiguration();
+ assertEquals(addedConfig.length, readAdded.length);
+ for (int i = 0; i < readAdded.length; i++)
+ {
+ assertEquals(addedConfig[i], readAdded[i]);
+ ProtocolParameter[] inputParams = addedConfig[i].getParametersAsArray();
+ ProtocolParameter[] outputParams = readAdded[i].getParametersAsArray();
+ assertEquals(inputParams.length, outputParams.length);
+ @SuppressWarnings("unchecked")
+ Map<String, ProtocolParameter> paramMap = readAdded[i].getParameters();
+ for (int j = 0; j < inputParams.length; j++)
+ {
+ ProtocolParameter param = paramMap.get(inputParams[j].getName());
+ assertNotNull(param);
+ assertEquals(inputParams[j].getValue(), param.getValue());
+ }
+ }
+
+ ProtocolStackConfigInfo updatedInfo = reread.get("unshared1");
+ assertEquals("unshared1", updatedInfo.getName());
+ ProtocolData[] readUpdated = updatedInfo.getConfiguration();
+ assertEquals(origConfig.length, readUpdated.length);
+ for (int i = 0; i < readUpdated.length; i++)
+ {
+ assertEquals(origConfig[i], readUpdated[i]);
+ ProtocolParameter[] inputParams = origConfig[i].getParametersAsArray();
+ ProtocolParameter[] outputParams = readUpdated[i].getParametersAsArray();
+ assertEquals(inputParams.length, outputParams.length);
+ @SuppressWarnings("unchecked")
+ Map<String, ProtocolParameter> paramMap = readUpdated[i].getParameters();
+ for (int j = 0; j < inputParams.length; j++)
+ {
+ String name = inputParams[j].getName();
+ ProtocolParameter param = paramMap.get(name);
+ assertNotNull(param);
+ if ("max_bundle_size".equals(name))
+ {
+ assertEquals("50000", param.getValue());
+ }
+ else
+ {
+ assertEquals(inputParams[j].getValue(), param.getValue());
+ }
+ }
+ }
+
+ // Validate that the overrides actuall affect created channels
+ channel1 = factory.createChannel("unshared1");
+ assertEquals("50000", ((JChannel) channel1).getProtocolStack().findProtocol("UDP").getProperties().get("max_bundle_size"));
+ channel2 = factory.createChannel("added");
+ assertEquals("64000", ((JChannel) channel2).getProtocolStack().findProtocol("UDP").getProperties().get("max_bundle_size"));
+ try
+ {
+ factory.createChannel("shared2");
+ fail("should not be able to create a channel for 'shared2'");
+ }
+ catch (IllegalArgumentException good) {}
+
+ }
+
+
+}
Modified: branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryUnitTestCase.java
===================================================================
--- branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryUnitTestCase.java 2009-06-22 17:04:50 UTC (rev 90502)
+++ branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/JChannelFactoryUnitTestCase.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -73,7 +73,7 @@
{
super.setUp();
- String jgroups_bind_addr = System.getProperty("jgroups.bind_addr");
+ jgroups_bind_addr = System.getProperty("jgroups.bind_addr");
if (jgroups_bind_addr == null)
{
System.setProperty("jbosstest.cluster.node0", System.getProperty("jbosstest.cluster.node0", "localhost"));
@@ -158,15 +158,19 @@
channel3 = factory1.createMultiplexerChannel("unshared1", "test");
assertFalse(channel3 instanceof MuxChannel);
- channel3.connect("test");
+ // JBAS-7015 use unique name
+ //channel3.connect("test");
+ channel3.connect("test3");
TP tp3 = getTP((JChannel) channel3);
- assertNotSame(tp1, tp3);
+ //JBAS-7015 -- change assert
+ //assertNotSame(tp1, tp3);
+ assertSame(tp1, tp3);
assertNotSame(tp2, tp3);
channel4 = factory1.createMultiplexerChannel("unshared1", "test2");
assertFalse(channel4 instanceof MuxChannel);
- channel4.connect("test2");
+ channel4.connect("test4");
TP tp4 = getTP((JChannel) channel4);
assertSame(tp3, tp4);
Copied: branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/OpenChannelsMapperUnitTestCase.java (from rev 90500, trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/OpenChannelsMapperUnitTestCase.java)
===================================================================
--- branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/OpenChannelsMapperUnitTestCase.java (rev 0)
+++ branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/OpenChannelsMapperUnitTestCase.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -0,0 +1,155 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.net.InetAddress;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+
+import junit.framework.TestCase;
+
+import org.jboss.ha.framework.server.ChannelInfo;
+import org.jboss.ha.framework.server.JChannelFactory;
+import org.jboss.ha.framework.server.managed.OpenChannelsMapper;
+import org.jboss.logging.Logger;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.test.cluster.channelfactory.managed.ManagedObjectTestUtil;
+import org.jboss.test.cluster.channelfactory.managed.ManagedObjectTestUtil.ChannelIds;
+import org.jgroups.Channel;
+
+/**
+ * Unit tests for OpenChannelsMapper
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class OpenChannelsMapperUnitTestCase extends TestCase
+{
+
+ private static final Logger log = Logger.getLogger(OpenChannelsMapperUnitTestCase.class);
+
+ private JChannelFactory factory;
+ private Channel channel1;
+ private Channel channel2;
+ private Channel channel3;
+ private Channel channel4;
+ private String jgroups_bind_addr;
+ private MBeanServer mbeanServer;
+
+ /**
+ * Create a new ProtocolStackConfigurationsMapperUnitTestCase.
+ *
+ * @param name
+ */
+ public OpenChannelsMapperUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ String jgroups_bind_addr = System.getProperty("jgroups.bind_addr");
+ if (jgroups_bind_addr == null)
+ {
+ System.setProperty("jbosstest.cluster.node0", System.getProperty("jbosstest.cluster.node0", "localhost"));
+ }
+
+ mbeanServer = MBeanServerFactory.createMBeanServer("jchannelfactorytest");
+
+ factory = new JChannelFactory();
+ factory.setMultiplexerConfig("cluster/channelfactory/stacks.xml");
+ factory.setAssignLogicalAddresses(false);
+ factory.setNodeAddress(InetAddress.getByName("localhost"));
+ factory.setNamingServicePort(123);
+ factory.setExposeChannels(true);
+ factory.setServer(mbeanServer);
+ factory.setManageReleasedThreadClassLoader(true);
+ factory.create();
+ factory.start();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (mbeanServer != null)
+ MBeanServerFactory.releaseMBeanServer(mbeanServer);
+
+ if (jgroups_bind_addr == null)
+ System.clearProperty("jgroups.bind_addr");
+
+ if (channel1 != null && channel1.isOpen())
+ channel1.close();
+
+ if (channel2 != null && channel2.isOpen())
+ channel2.close();
+
+ if (channel3 != null && channel3.isOpen())
+ channel3.close();
+
+ if (channel4 != null && channel4.isOpen())
+ channel4.close();
+
+ if (factory != null)
+ {
+ factory.stop();
+ factory.destroy();
+ }
+ }
+
+ public void testCreateMetaValue() throws Exception
+ {
+ channel1 = factory.createMultiplexerChannel("unshared1", "no1");
+ channel1.connect("channel1");
+ channel2 = factory.createMultiplexerChannel("shared1", "no2");
+ channel2.connect("channel2");
+
+ Set<ChannelInfo> channels = factory.getOpenChannels();
+ OpenChannelsMapper testee = new OpenChannelsMapper();
+ MetaValue val = testee.createMetaValue(testee.getMetaType(), channels);
+ Set<ChannelIds> ids = ManagedObjectTestUtil.validateOpenChannels(val);
+
+ for (ChannelIds cid : ids)
+ {
+ if ("no1".equals(cid.id))
+ {
+ assertEquals("unshared1", cid.stackName);
+ assertEquals("channel1", cid.clusterName);
+ }
+ else if ("no2".equals(cid.id))
+ {
+ assertEquals("shared1", cid.stackName);
+ assertEquals("channel2", cid.clusterName);
+ }
+ else
+ {
+ fail("unknown id " + cid.id);
+ }
+ }
+ }
+}
Copied: branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ProtocolStackConfigurationsMapperUnitTestCase.java (from rev 90500, trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ProtocolStackConfigurationsMapperUnitTestCase.java)
===================================================================
--- branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ProtocolStackConfigurationsMapperUnitTestCase.java (rev 0)
+++ branches/Branch_5_x/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ProtocolStackConfigurationsMapperUnitTestCase.java 2009-06-22 17:15:13 UTC (rev 90503)
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.net.InetAddress;
+import java.util.Map;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+
+import junit.framework.TestCase;
+
+import org.jboss.ha.framework.server.JChannelFactory;
+import org.jboss.ha.framework.server.ProtocolStackConfigInfo;
+import org.jboss.ha.framework.server.managed.ProtocolStackConfigurationsMapper;
+import org.jboss.logging.Logger;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.test.cluster.channelfactory.managed.ManagedObjectTestUtil;
+import org.jgroups.Channel;
+
+/**
+ * Unit tests for ProtocolStackConfigurationsMapper
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class ProtocolStackConfigurationsMapperUnitTestCase extends TestCase
+{
+
+ private static final Logger log = Logger.getLogger(ProtocolStackConfigurationsMapper.class);
+
+ private JChannelFactory factory;
+ private String jgroups_bind_addr;
+ private MBeanServer mbeanServer;
+
+ /**
+ * Create a new ProtocolStackConfigurationsMapperUnitTestCase.
+ *
+ * @param name
+ */
+ public ProtocolStackConfigurationsMapperUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ String jgroups_bind_addr = System.getProperty("jgroups.bind_addr");
+ if (jgroups_bind_addr == null)
+ {
+ System.setProperty("jbosstest.cluster.node0", System.getProperty("jbosstest.cluster.node0", "localhost"));
+ }
+
+ mbeanServer = MBeanServerFactory.createMBeanServer("jchannelfactorytest");
+
+ factory = new JChannelFactory();
+ factory.setMultiplexerConfig("cluster/channelfactory/stacks.xml");
+ factory.setAssignLogicalAddresses(false);
+ factory.setNodeAddress(InetAddress.getByName("localhost"));
+ factory.setNamingServicePort(123);
+ factory.setExposeChannels(true);
+ factory.setServer(mbeanServer);
+ factory.setManageReleasedThreadClassLoader(true);
+ factory.create();
+ factory.start();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (mbeanServer != null)
+ MBeanServerFactory.releaseMBeanServer(mbeanServer);
+
+ if (jgroups_bind_addr == null)
+ System.clearProperty("jgroups.bind_addr");
+
+ if (factory != null)
+ {
+ factory.stop();
+ factory.destroy();
+ }
+ }
+
+ public void testRoundTrip() throws Exception
+ {
+ Map<String, ProtocolStackConfigInfo> map = factory.getProtocolStackConfigurations();
+
+ ProtocolStackConfigurationsMapper testee = new ProtocolStackConfigurationsMapper();
+
+ MetaValue metaValue = testee.createMetaValue(ProtocolStackConfigurationsMapper.TYPE, map);
+ ManagedObjectTestUtil.validateProtocolStackConfigurations(metaValue, new String[]{"unshared1", "shared1"});
+
+ Map<String, ProtocolStackConfigInfo> restored = testee.unwrapMetaValue(metaValue);
+ assertEquals(map.keySet(), restored.keySet());
+
+ // FIXME go deeper
+ }
+
+}
More information about the jboss-cvs-commits
mailing list