[jboss-cvs] JBossAS SVN: r76670 - in trunk: cluster/src/main/org/jboss/ha/singleton and 4 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Aug 5 12:17:02 EDT 2008
Author: pferraro
Date: 2008-08-05 12:17:01 -0400 (Tue, 05 Aug 2008)
New Revision: 76670
Added:
trunk/cluster/src/main/org/jboss/ha/jmx/AbstractHAServiceMBeanSupport.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ClusteredMCMPHandlerRpcHandler.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ModClusterServiceRpcHandler.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ResetRequestSourceRpcHandler.java
Removed:
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicy.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyBase.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyMBean.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElector.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceHASingletonElectionPolicy.java
Modified:
trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBean.java
trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBeanSupport.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingleton.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonController.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonControllerMBean.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimple.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimpleMBean.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonMBean.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupport.java
trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupportMBean.java
trunk/cluster/src/main/org/jboss/ha/singleton/PreferredMasterElectionPolicy.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PreferredMasterElectionPolicyUnitTestCase.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterService.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterServiceMBean.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ClusteredMCMPHandlerImpl.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/HASingletonAwareResetRequestSource.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceDRMEntry.java
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/PeerMCMPDiscoveryStatus.java
Log:
Refactored HASingletonSupport into pojo + mbean wrapper.
Simplified responsibility of HASingletonElectionPolicy.
Added: trunk/cluster/src/main/org/jboss/ha/jmx/AbstractHAServiceMBeanSupport.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jmx/AbstractHAServiceMBeanSupport.java (rev 0)
+++ trunk/cluster/src/main/org/jboss/ha/jmx/AbstractHAServiceMBeanSupport.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -0,0 +1,401 @@
+/*
+ * 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.ha.jmx;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.management.AttributeChangeNotification;
+import javax.management.Notification;
+import javax.management.ObjectName;
+
+import org.jboss.beans.metadata.api.annotations.Inject;
+import org.jboss.beans.metadata.api.model.FromContext;
+import org.jboss.ha.framework.interfaces.DistributedState;
+import org.jboss.ha.framework.interfaces.HAPartition;
+import org.jboss.ha.framework.interfaces.HAService;
+import org.jboss.ha.framework.server.ClusterPartitionMBean;
+import org.jboss.ha.framework.server.EventFacility;
+import org.jboss.ha.framework.server.EventFactory;
+import org.jboss.system.ServiceMBeanSupport;
+
+/**
+ * Abstract implementation of HAServiceMBean for use by subclasses, e.g. {@link org.jboss.ha.singleton.HASingletonSupport}.
+ *
+ * @param S the class of the HAService delegate
+ * @author Paul Ferraro
+ */
+ at SuppressWarnings("deprecation")
+public abstract class AbstractHAServiceMBeanSupport<S extends HAService<Notification>>
+ extends ServiceMBeanSupport
+ implements HAServiceMBean, HAService<Notification>, EventFactory<Notification>, EventFacility<Notification>
+{
+ private final S service = this.createHAService();
+
+ private volatile boolean sendLocalLifecycleNotifications = true;
+ private volatile boolean sendRemoteLifecycleNotifications = true;
+
+ /**
+ * Defines the object used to delegate service methods.
+ * @return an {@link HAService} delegate
+ */
+ protected abstract S createHAService();
+
+ /**
+ * @return the object created by {@link #createHAService()}.
+ */
+ protected final S getHAService()
+ {
+ return this.service;
+ }
+
+ // Public --------------------------------------------------------
+
+ public HAPartition getHAPartition()
+ {
+ return this.service.getHAPartition();
+ }
+
+ public void setHAPartition(HAPartition partition)
+ {
+ this.service.setHAPartition(partition);
+ }
+
+ public void setClusterPartition(ClusterPartitionMBean clusterPartition)
+ {
+ if ((this.getState() != STARTED) && (this.getState() != STARTING))
+ {
+ this.service.setHAPartition(clusterPartition.getHAPartition());
+ }
+ }
+
+ public String getPartitionName()
+ {
+ return this.service.getHAPartition().getPartitionName();
+ }
+
+ public boolean isRegisterThreadContextClassLoader()
+ {
+ return this.service.isRegisterThreadContextClassLoader();
+ }
+
+ public void setRegisterThreadContextClassLoader(boolean register)
+ {
+ this.service.setRegisterThreadContextClassLoader(register);
+ }
+
+ // Protected ------------------------------
+
+ /**
+ *
+ *
+ * Convenience method for sharing state across a cluster partition.
+ * Delegates to the DistributedStateService
+ *
+ * @param key key for the distributed object
+ * @param value the distributed object
+ *
+ */
+ public void setDistributedState(String key, Serializable value) throws Exception
+ {
+ DistributedState ds = this.getHAPartition().getDistributedStateService();
+ ds.set(this.getServiceHAName(), key, value);
+ }
+
+ /**
+ *
+ * Convenience method for sharing state across a cluster partition.
+ * Delegates to the DistributedStateService
+ *
+ * @param key key for the distributed object
+ * @return Serializable the distributed object
+ *
+ */
+ public Serializable getDistributedState(String key)
+ {
+ DistributedState ds = this.getHAPartition().getDistributedStateService();
+ return ds.get(this.getServiceHAName(), key);
+ }
+
+ /**
+ * @see org.jboss.system.ServiceMBeanSupport#createService()
+ */
+ @Override
+ protected void createService() throws Exception
+ {
+ this.service.create();
+ }
+
+ /**
+ * <p>
+ * Implementors of this method should not
+ * code the singleton logic here.
+ * The MBean lifecycle create/start/stop are separate from
+ * the singleton logic.
+ * Singleton logic should originate in becomeMaster().
+ * </p>
+ *
+ * <p>
+ * <b>Attention</b>: Always call this method when you overwrite it in a subclass
+ * because it elects the master singleton node.
+ * </p>
+ *
+ */
+ @Override
+ protected void startService() throws Exception
+ {
+ this.log.debug("start HAServiceMBeanSupport");
+
+ if (this.getHAPartition() == null)
+ {
+ throw new IllegalStateException("HAPartition property must be set before starting HAServiceMBeanSupport");
+ }
+
+ this.setupPartition();
+
+ this.service.start();
+ }
+
+ /**
+ * <p>
+ * <b>Attention</b>: Always call this method when you overwrite it in a subclass
+ * </p>
+ *
+ */
+ @Override
+ protected void stopService() throws Exception
+ {
+ this.log.debug("stop HAServiceMBeanSupport");
+
+ this.service.stop();
+ }
+
+ /**
+ * @see org.jboss.system.ServiceMBeanSupport#destroyService()
+ */
+ @Override
+ protected void destroyService() throws Exception
+ {
+ this.service.destroy();
+ }
+
+ protected void setupPartition() throws Exception
+ {
+ // method no longer used by base implementation
+ }
+
+ @SuppressWarnings("unchecked")
+ public List callMethodOnPartition(String methodName, Object[] args, Class[] types) throws Exception
+ {
+ return this.getHAPartition().callMethodOnCluster(this.getServiceHAName(), methodName, args, types, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void callAsyncMethodOnPartition(String methodName, Object[] args, Class[] types) throws Exception
+ {
+ this.getHAPartition().callAsynchMethodOnCluster(this.getServiceHAName(), methodName, args, types, true);
+ }
+
+ /**
+ * Gets whether JMX Notifications should be sent to local (same JVM) listeners
+ * if the notification is for an attribute change to attribute "State".
+ * <p>
+ * Default is <code>true</code>.
+ * </p>
+ * @see #sendNotification(Notification)
+ */
+ public boolean getSendLocalLifecycleNotifications()
+ {
+ return this.sendLocalLifecycleNotifications;
+ }
+
+ /**
+ * Sets whether JMX Notifications should be sent to local (same JVM) listeners
+ * if the notification is for an attribute change to attribute "State".
+ * <p>
+ * Default is <code>true</code>.
+ * </p>
+ * @see #sendNotification(Notification)
+ */
+ public void setSendLocalLifecycleNotifications(boolean sendLocalLifecycleNotifications)
+ {
+ this.sendLocalLifecycleNotifications = sendLocalLifecycleNotifications;
+ }
+
+ /**
+ * Gets whether JMX Notifications should be sent to remote listeners
+ * if the notification is for an attribute change to attribute "State".
+ * <p>
+ * Default is <code>true</code>.
+ * </p>
+ * <p>
+ * See http://jira.jboss.com/jira/browse/JBAS-3194 for an example of a
+ * use case where this property should be set to false.
+ * </p>
+ *
+ * @see #sendNotification(Notification)
+ */
+ public boolean getSendRemoteLifecycleNotifications()
+ {
+ return this.sendRemoteLifecycleNotifications;
+ }
+
+ /**
+ * Sets whether JMX Notifications should be sent to remote listeners
+ * if the notification is for an attribute change to attribute "State".
+ * <p>
+ * Default is <code>true</code>.
+ * </p>
+ * <p>
+ * See http://jira.jboss.com/jira/browse/JBAS-3194 for an example of a
+ * use case where this property should be set to false.
+ * </p>
+ *
+ * @see #sendNotification(Notification)
+ */
+ public void setSendRemoteLifecycleNotifications(boolean sendRemoteLifecycleNotifications)
+ {
+ this.sendRemoteLifecycleNotifications = sendRemoteLifecycleNotifications;
+ }
+
+ /**
+ * Broadcast the notification to the remote listener nodes (if any) and then
+ * invoke super.sendNotification() to notify local listeners.
+ *
+ * @param notification sent out to local listeners and other nodes. It should be serializable.
+ * It is recommended that the source of the notification is an ObjectName of an MBean that
+ * is is available on all nodes where the broadcaster MBean is registered.
+ *
+ * @see #getSendLocalLifecycleNotifications()
+ * @see #getSendRemoteLifecycleNotifications()
+ * @see javax.management.NotificationBroadcasterSupport#sendNotification(Notification)
+ * @see org.jboss.mx.util.JBossNotificationBroadcasterSupport#sendNotification(javax.management.Notification)
+ */
+ public void sendNotification(Notification notification)
+ {
+ boolean stateChange = (notification instanceof AttributeChangeNotification) ? "State".equals(((AttributeChangeNotification) notification).getAttributeName()) : false;
+
+ if (!stateChange || this.sendRemoteLifecycleNotifications)
+ {
+ try
+ {
+ this.sendNotificationRemote(notification);
+ }
+ catch (Throwable e)
+ {
+ // even if broadcast failed, local notification should still be sent
+ this.log.warn("handleNotification( " + notification + " ) failed ", e);
+ }
+ }
+
+ if (!stateChange || this.sendLocalLifecycleNotifications)
+ {
+ this.sendNotificationToLocalListeners(notification);
+ }
+ }
+
+ /**
+ *
+ * Broadcast a notifcation remotely to the partition participants
+ *
+ * @param notification
+ */
+ protected void sendNotificationRemote(Notification notification) throws Exception
+ {
+ // Overriding the source MBean with its ObjectName
+ // to ensure that it can be safely transferred over the wire
+ notification.setSource(this.getServiceName());
+
+ this.handleEvent(notification);
+ }
+
+ protected void sendNotificationToLocalListeners(Notification notification)
+ {
+ this.notifyListeners(notification);
+ }
+
+ /**
+ * @see org.jboss.ha.framework.server.EventFacility#notifyListeners(java.util.EventObject)
+ */
+ public void notifyListeners(Notification notification)
+ {
+ super.sendNotification(notification);
+ }
+
+ /**
+ * @see org.jboss.ha.framework.interfaces.EventListener#handleEvent(java.util.EventObject)
+ */
+ public void handleEvent(Notification notification) throws Exception
+ {
+ this.service.handleEvent(notification);
+ }
+
+ /**
+ * @see org.jboss.ha.framework.server.EventFactory#createEvent(java.lang.Object, java.lang.String)
+ */
+ public Notification createEvent(Object source, String type)
+ {
+ return new Notification(type, this, this.getNextNotificationSequenceNumber());
+ }
+
+ /**
+ *
+ * Override this method only if you need to provide a custom partition wide unique service name.
+ * The default implementation will usually work, provided that
+ * the getServiceName() method returns a unique canonical MBean name.
+ *
+ * @return partition wide unique service name
+ */
+ public String getServiceHAName()
+ {
+ String name = this.service.getServiceHAName();
+
+ if (name == null)
+ {
+ ObjectName on = this.getServiceName();
+
+ if (on != null)
+ {
+ name = on.getCanonicalName();
+
+ this.service.setServiceHAName(name);
+ }
+ else
+ {
+ // This shouldn't occur as the service name is now injected by the microcontainer.
+ // If injection fails, the service name should then be used.
+ throw new IllegalStateException("Cannot determine ServiceHAName for " +
+ getClass().getName() + "; " +
+ "either set it explicitly or register this object in JMX " +
+ "before calling create");
+ }
+ }
+
+ return name;
+ }
+
+ @Inject(fromContext = FromContext.NAME)
+ public void setServiceHAName(String haName)
+ {
+ this.service.setServiceHAName(haName);
+ }
+}
Modified: trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBean.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBean.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -42,9 +42,8 @@
*/
public interface HAServiceMBean
- extends org.jboss.system.ServiceMBean, NotificationBroadcaster
+ extends org.jboss.system.ServiceMBean, NotificationBroadcaster
{
-
/**
* Gets the name of the partition used by this service. This is a
* convenience method as the partition name is an attribute of HAPartition.
@@ -52,13 +51,6 @@
* @return the name of the partition
*/
String getPartitionName();
-
- /**
- * Get the underlying partition used by this service.
- *
- * @return the partition
- */
- HAPartition getHAPartition();
/**
* Sets the underlying partition used by this service.
@@ -66,7 +58,7 @@
* @param clusterPartition the partition
*/
void setHAPartition(HAPartition clusterPartition);
-
+
/**
* Sets the underlying partition used by this service.
*
@@ -75,77 +67,56 @@
* @deprecated use {@link #setHAPartition(HAPartition)}
*/
void setClusterPartition(ClusterPartitionMBean clusterPartition);
-
+
/**
- * Test whether the thread context classloader should be used in RPC calls.
*
- * @return whether the thread context classloader should be used in RPC calls.
+ * Convenience method for broadcasting a call to all members of a partition.
+ *
+ * @param methodName
+ * @param args array of Java Object representing the set of parameters to be
+ * given to the remote method
+ * @param types The types of the parameters
+ * @return a list of responses from remote nodes
+ * @throws Exception
*/
- public boolean isRegisterThreadContextClassLoader();
-
+ @SuppressWarnings("unchecked")
+ List callMethodOnPartition(String methodName, Object[] args, Class[] types) throws Exception;
+
/**
- * Sets a flag specifying whether the calling thread's context classloader
- * should be used when making RPC calls. This flag must be set before the
- * RPC handler is registered in startService(). The default value is false.
- * This would typically be used in conjunction with a scoped classloader.
*
- * @param register whether to use the thread context classloader when
- * registering the service's RPC handler.
+ * Convenience method for sharing state across a cluster partition.
+ * Delegates to the DistributedStateService
*
+ * @param key key for the distributed object
+ * @return Serializable the distributed object
+ *
*/
- public void setRegisterThreadContextClassLoader(boolean register);
+ Serializable getDistributedState(String key);
- /**
- *
- * Convenience method for broadcasting a call to all members of a partition.
- *
- * @param methodName
- * @param args array of Java Object representing the set of parameters to be
- * given to the remote method
- * @param types The types of the parameters
- * @return a list of responses from remote nodes
- * @throws Exception
- */
- public List callMethodOnPartition(String methodName, Object[] args, Class[] types)
- throws Exception;
-
- /**
- *
- * Convenience method for sharing state across a cluster partition.
- * Delegates to the DistributedStateService
- *
- * @param key key for the distributed object
- * @return Serializable the distributed object
- *
- */
- public Serializable getDistributedState(String key);
-
- /**
- *
- *
- * Convenience method for sharing state across a cluster partition.
- * Delegates to the DistributedStateService
- *
- * @param key key for the distributed object
- * @param value the distributed object
- *
- */
- public void setDistributedState(String key, Serializable value)
- throws Exception;
-
- /**
- *
- * Broadcast the notification to the remote listener nodes (if any) and then
- * invoke super.sendNotification() to notify local listeners.
- *
- * @param notification sent out to local listeners and other nodes. It should be serializable.
- * It is recommended that the source of the notification is an ObjectName of an MBean that
- * is is available on all nodes where the broadcaster MBean is registered.
- *
- *
- * @see javax.management.NotificationBroadcasterSupport#sendNotification(Notification)
- *
- */
- public void sendNotification(Notification notification);
-
+ /**
+ *
+ *
+ * Convenience method for sharing state across a cluster partition.
+ * Delegates to the DistributedStateService
+ *
+ * @param key key for the distributed object
+ * @param value the distributed object
+ *
+ */
+ void setDistributedState(String key, Serializable value) throws Exception;
+
+ /**
+ *
+ * Broadcast the notification to the remote listener nodes (if any) and then
+ * invoke super.sendNotification() to notify local listeners.
+ *
+ * @param notification sent out to local listeners and other nodes. It should be serializable.
+ * It is recommended that the source of the notification is an ObjectName of an MBean that
+ * is is available on all nodes where the broadcaster MBean is registered.
+ *
+ *
+ * @see javax.management.NotificationBroadcasterSupport#sendNotification(Notification)
+ *
+ */
+ void sendNotification(Notification notification);
}
Modified: trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBeanSupport.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBeanSupport.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/jmx/HAServiceMBeanSupport.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -21,23 +21,12 @@
*/
package org.jboss.ha.jmx;
-import java.io.Serializable;
-import java.util.List;
-
-import javax.management.AttributeChangeNotification;
import javax.management.Notification;
-import javax.management.ObjectName;
-import org.jboss.beans.metadata.api.annotations.Inject;
-import org.jboss.beans.metadata.api.model.FromContext;
-import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
-import org.jboss.ha.framework.interfaces.DistributedState;
-import org.jboss.ha.framework.interfaces.HAPartition;
-import org.jboss.ha.framework.server.ClusterPartitionMBean;
-import org.jboss.system.ServiceMBeanSupport;
+import org.jboss.ha.framework.interfaces.HAService;
+import org.jboss.ha.framework.server.HAServiceImpl;
/**
- *
* Management Bean for an HA-Service.
* Provides a convenient common base for cluster symmetric MBeans.
*
@@ -49,454 +38,23 @@
* will notify all listeners in the same cluster partition.
* TODO: The performance can be further optimized by avoiding broadcast messages
* when remote listener nodes are not interested (e.g. have no local subscribers)
- * or by iterating locally over filters or remote listeners.
- *
- * @author Ivelin Ivanov <ivelin at apache.org> *
+ * or by iterating locally over filters or remote listeners.
+ *
+ * @author Ivelin Ivanov <ivelin at apache.org>
+ * @author Paul Ferraro
* @version $Revision$
*
*/
public class HAServiceMBeanSupport
- extends ServiceMBeanSupport
- implements HAServiceMBean
+ extends AbstractHAServiceMBeanSupport<HAService<Notification>>
{
- // Constants -----------------------------------------------------
-
- // Attributes ----------------------------------------------------
- private HAPartition clusterPartition;
- private boolean registerClassloader = false;
-
- private DistributedReplicantManager.ReplicantListener drmListener = null;
-
- /**
- * DRM participation TOKEN
- */
- private String REPLICANT_TOKEN = "";
-
- private boolean sendLocalLifecycleNotifications = true;
- private boolean sendRemoteLifecycleNotifications = true;
-
- private String serviceHAName;
-
- // Public --------------------------------------------------------
-
- public HAServiceMBeanSupport()
- {
- // for JMX
- }
-
- public HAPartition getHAPartition()
- {
- return clusterPartition;
- }
-
- public void setHAPartition(HAPartition clusterPartition)
- {
- this.clusterPartition = clusterPartition;
- }
-
- public void setClusterPartition(ClusterPartitionMBean clusterPartition)
- {
- if ((getState() != STARTED) && (getState() != STARTING))
- {
- this.clusterPartition = clusterPartition.getHAPartition();
- }
- }
-
- public String getPartitionName()
- {
- return clusterPartition.getPartitionName();
- }
-
- public boolean isRegisterThreadContextClassLoader()
- {
- return registerClassloader;
- }
-
- public void setRegisterThreadContextClassLoader(boolean register)
- {
- registerClassloader = register;
- }
-
- // Protected ------------------------------
-
/**
- *
- *
- * Convenience method for sharing state across a cluster partition.
- * Delegates to the DistributedStateService
- *
- * @param key key for the distributed object
- * @param value the distributed object
- *
+ * @see org.jboss.ha.jmx.AbstractHAServiceMBeanSupport#createHAService()
*/
- public void setDistributedState(String key, Serializable value)
- throws Exception
+ @Override
+ protected HAService<Notification> createHAService()
{
- DistributedState ds = clusterPartition.getDistributedStateService();
- ds.set(getServiceHAName(), key, value);
+ return new HAServiceImpl<Notification>(this, this);
}
-
- /**
- *
- * Convenience method for sharing state across a cluster partition.
- * Delegates to the DistributedStateService
- *
- * @param key key for the distributed object
- * @return Serializable the distributed object
- *
- */
- public Serializable getDistributedState(String key)
- {
- DistributedState ds = clusterPartition.getDistributedStateService();
- return ds.get(getServiceHAName(), key);
- }
-
- /**
- * <p>
- * Implementors of this method should not
- * code the singleton logic here.
- * The MBean lifecycle create/start/stop are separate from
- * the singleton logic.
- * Singleton logic should originate in becomeMaster().
- * </p>
- *
- * <p>
- * <b>Attention</b>: Always call this method when you overwrite it in a subclass
- * because it elects the master singleton node.
- * </p>
- *
- */
- protected void startService() throws Exception
- {
- log.debug("start HAServiceMBeanSupport");
-
- if (clusterPartition == null)
- {
- throw new IllegalStateException("HAPartition property must be set before starting HAServiceMBeanSupport");
- }
-
- setupPartition();
-
- registerRPCHandler();
-
- registerDRMListener();
-
- }
-
- /**
- * <p>
- * <b>Attention</b>: Always call this method when you overwrite it in a subclass
- * </p>
- *
- */
- protected void stopService() throws Exception
- {
- log.debug("stop HAServiceMBeanSupport");
-
- unregisterDRMListener();
-
- unregisterRPCHandler();
- }
-
- protected void setupPartition() throws Exception
- {
- // method no longer used by base implementation
- }
-
- /**
- * Returns the object upon which incoming RPC invocations will be made.
- *
- * @return the default implementation returns <code>this</code>
- */
- protected Object getRPCHandler()
- {
- return this;
- }
-
- protected void registerRPCHandler()
- {
- if (isRegisterThreadContextClassLoader())
- clusterPartition.registerRPCHandler(getServiceHAName(), getRPCHandler(), Thread.currentThread().getContextClassLoader());
- else
- clusterPartition.registerRPCHandler(getServiceHAName(), getRPCHandler());
- }
-
- protected void unregisterRPCHandler()
- {
- clusterPartition.unregisterRPCHandler(getServiceHAName(), this);
- }
-
- protected Serializable getReplicant()
- {
- return REPLICANT_TOKEN;
- }
-
- protected void registerDRMListener() throws Exception
- {
- DistributedReplicantManager drm = clusterPartition.getDistributedReplicantManager();
-
- // register to listen to topology changes, which might cause the election of a new master
- drmListener = new DistributedReplicantManager.ReplicantListener()
- {
- Object mutex = new Object();
-
- public void replicantsChanged(
- String key,
- List newReplicants,
- int newReplicantsViewId,
- boolean merge)
- {
- if (key.equals(getServiceHAName()))
- {
- // This synchronized block was added when the internal behavior of
- // DistributedReplicantManagerImpl was changed so that concurrent
- // replicantsChanged notifications are possible. Synchronization
- // ensures that this change won't break non-thread-safe
- // subclasses of HAServiceMBeanSupport.
- synchronized(mutex)
- {
- // change in the topology callback
- HAServiceMBeanSupport.this.partitionTopologyChanged(newReplicants, newReplicantsViewId, merge);
- }
- }
- }
- };
- drm.registerListener(getServiceHAName(), drmListener);
-
- // this ensures that the DRM knows that this node has the MBean deployed
- drm.add(getServiceHAName(), getReplicant());
- }
-
- protected void unregisterDRMListener() throws Exception
- {
- DistributedReplicantManager drm = clusterPartition.getDistributedReplicantManager();
-
- // remove replicant node
- drm.remove(getServiceHAName());
-
- // unregister
- drm.unregisterListener(getServiceHAName(), drmListener);
- }
-
- public void partitionTopologyChanged(List newReplicants, int newReplicantsViewId, boolean merge)
- {
- if (log.isDebugEnabled())
- {
- log.debug("partitionTopologyChanged(). cluster view id: " + newReplicantsViewId);
- }
- }
-
- protected boolean isDRMMasterReplica()
- {
- DistributedReplicantManager drm = clusterPartition.getDistributedReplicantManager();
-
- return drm.isMasterReplica(getServiceHAName());
- }
-
- public List callMethodOnPartition(String methodName, Object[] args, Class[] types)
- throws Exception
- {
- return clusterPartition.callMethodOnCluster(
- getServiceHAName(),
- methodName,
- args, types,
- true);
- }
-
- /**
- * Gets whether JMX Notifications should be sent to local (same JVM) listeners
- * if the notification is for an attribute change to attribute "State".
- * <p>
- * Default is <code>true</code>.
- * </p>
- * @see #sendNotification(Notification)
- */
- public boolean getSendLocalLifecycleNotifications()
- {
- return sendLocalLifecycleNotifications;
- }
-
- /**
- * Sets whether JMX Notifications should be sent to local (same JVM) listeners
- * if the notification is for an attribute change to attribute "State".
- * <p>
- * Default is <code>true</code>.
- * </p>
- * @see #sendNotification(Notification)
- */
- public void setSendLocalLifecycleNotifications(boolean sendLocalLifecycleNotifications)
- {
- this.sendLocalLifecycleNotifications = sendLocalLifecycleNotifications;
- }
-
- /**
- * Gets whether JMX Notifications should be sent to remote listeners
- * if the notification is for an attribute change to attribute "State".
- * <p>
- * Default is <code>true</code>.
- * </p>
- * <p>
- * See http://jira.jboss.com/jira/browse/JBAS-3194 for an example of a
- * use case where this property should be set to false.
- * </p>
- *
- * @see #sendNotification(Notification)
- */
- public boolean getSendRemoteLifecycleNotifications()
- {
- return sendRemoteLifecycleNotifications;
- }
-
- /**
- * Sets whether JMX Notifications should be sent to remote listeners
- * if the notification is for an attribute change to attribute "State".
- * <p>
- * Default is <code>true</code>.
- * </p>
- * <p>
- * See http://jira.jboss.com/jira/browse/JBAS-3194 for an example of a
- * use case where this property should be set to false.
- * </p>
- *
- * @see #sendNotification(Notification)
- */
- public void setSendRemoteLifecycleNotifications(boolean sendRemoteLifecycleNotifications)
- {
- this.sendRemoteLifecycleNotifications = sendRemoteLifecycleNotifications;
- }
-
- /**
- * Broadcast the notification to the remote listener nodes (if any) and then
- * invoke super.sendNotification() to notify local listeners.
- *
- * @param notification sent out to local listeners and other nodes. It should be serializable.
- * It is recommended that the source of the notification is an ObjectName of an MBean that
- * is is available on all nodes where the broadcaster MBean is registered.
- *
- * @see #getSendLocalLifecycleNotifications()
- * @see #getSendRemoteLifecycleNotifications()
- * @see javax.management.NotificationBroadcasterSupport#sendNotification(Notification)
- */
- public void sendNotification(Notification notification)
- {
- boolean stateChange = isStateChangeNotification(notification);
-
- if (!stateChange || sendRemoteLifecycleNotifications)
- {
- try
- {
- // Overriding the source MBean with its ObjectName
- // to ensure that it can be safely transferred over the wire
- notification.setSource(this.getServiceName());
- sendNotificationRemote(notification);
- }
-
- catch (Throwable th)
- {
- boolean debug = log.isDebugEnabled();
- if (debug)
- log.debug("sendNotificationRemote( " + notification + " ) failed ", th);
- // even if broadcast failed, local notification should still be sent
-
- }
- }
-
- if (!stateChange || sendLocalLifecycleNotifications)
- {
- sendNotificationToLocalListeners(notification);
- }
- }
-
- private boolean isStateChangeNotification(Notification notification)
- {
- boolean stateChange = false;
- if (notification instanceof AttributeChangeNotification)
- {
- stateChange = "State".equals(((AttributeChangeNotification) notification).getAttributeName());
- }
- return stateChange;
- }
-
- protected void sendNotificationToLocalListeners(Notification notification)
- {
- super.sendNotification(notification);
- }
-
- protected void callAsyncMethodOnPartition(String methodName, Object[] args, Class[] types)
- throws Exception
- {
- clusterPartition.callAsynchMethodOnCluster(
- getServiceHAName(),
- methodName,
- args, types,
- true);
- }
-
-
- /**
- *
- * Broadcast a notifcation remotely to the partition participants
- *
- * @param notification
- */
- protected void sendNotificationRemote(Notification notification)
- throws Exception
- {
- callAsyncMethodOnPartition("_receiveRemoteNotification",
- new Object[]{notification}, new Class[]{Notification.class});
- }
-
- /**
- *
- * Invoked by remote broadcasters.
- * Delegates to the super class
- *
- */
- public void _receiveRemoteNotification(Notification notification)
- {
- super.sendNotification(notification);
- }
-
-
- /**
- *
- * Override this method only if you need to provide a custom partition wide unique service name.
- * The default implementation will usually work, provided that
- * the getServiceName() method returns a unique canonical MBean name.
- *
- * @return partition wide unique service name
- */
- public String getServiceHAName()
- {
- if (serviceHAName == null)
- {
- ObjectName on = getServiceName();
- if (on != null)
- {
- serviceHAName = on.getCanonicalName();
- }
- else
- {
- // This shouldn't occur as the service name is now injected by the microcontainer.
- // If injection fails, the service name should then be used.
- throw new IllegalStateException("Cannot determine ServiceHAName for " +
- getClass().getName() + "; " +
- "either set it explicitly or register this object in JMX " +
- "before calling create");
- }
- }
- return serviceHAName;
- }
-
- @Inject(fromContext = FromContext.NAME)
- public void setServiceHAName(String haName)
- {
- this.serviceHAName = haName;
- }
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-
}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingleton.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingleton.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingleton.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -21,24 +21,17 @@
*/
package org.jboss.ha.singleton;
+import org.jboss.ha.framework.interfaces.HASingletonLifecycle;
+
/**
* Basic interface for clustered singleton services
*
+ * Replaced by {@link HASingletonLifecycle}.
+ *
* @author Ivelin Ivanov <ivelin at apache.org>
* @version $Revision$
*/
-public interface HASingleton
+ at Deprecated
+public interface HASingleton extends HASingletonLifecycle
{
- /**
- * Invoked when this mbean is elected to run the singleton service,
- * or in other words when this node is elected for master.
- */
- void startSingleton();
-
- /**
- * Invoked when this mbean is elected to no longer run the singleton service,
- * or in other words when this node is elected for slave.
- */
- void stopSingleton();
-
}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonController.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonController.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonController.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -61,23 +61,13 @@
private static final Object[] NO_ARGS = new Object[0];
private static final String[] NO_TYPE_NAMES = new String[0];
- private static final Class[] NO_TYPES = new Class[0];
-
- // Constructors --------------------------------------------------
+ private static final Class<?>[] NO_TYPES = new Class[0];
- /**
- * Default CTOR
- */
- public HASingletonController()
- {
- // empty
- }
-
// Attributes ----------------------------------------------------
-
+
public Object getTarget()
{
- return mSingleton;
+ return this.mSingleton;
}
public void setTarget(Object target)
@@ -87,7 +77,7 @@
public ObjectName getTargetName()
{
- return mSingletonMBean;
+ return this.mSingletonMBean;
}
public void setTargetName(ObjectName targetObjectName)
@@ -97,47 +87,51 @@
public String getTargetStartMethod()
{
- return mSingletonStartMethod;
+ return this.mSingletonStartMethod;
}
public void setTargetStartMethod(String targetStartMethod)
throws InvalidParameterException
{
if (targetStartMethod != null)
- mSingletonStartMethod = targetStartMethod;
+ {
+ this.mSingletonStartMethod = targetStartMethod;
+ }
}
public String getTargetStopMethod()
{
- return mSingletonStopMethod;
+ return this.mSingletonStopMethod;
}
public void setTargetStopMethod(String targetStopMethod)
throws InvalidParameterException
{
if (targetStopMethod != null)
- mSingletonStopMethod = targetStopMethod;
+ {
+ this.mSingletonStopMethod = targetStopMethod;
+ }
}
public String getTargetStartMethodArgument()
{
- return mSingletonStartMethodArgument ;
+ return this.mSingletonStartMethodArgument ;
}
public void setTargetStartMethodArgument(String targetStartMethodArgument)
{
- mSingletonStartMethodArgument = targetStartMethodArgument;
+ this.mSingletonStartMethodArgument = targetStartMethodArgument;
}
public String getTargetStopMethodArgument()
{
- return mSingletonStopMethodArgument ;
+ return this.mSingletonStopMethodArgument ;
}
public void setTargetStopMethodArgument(String targetStopMethodArgument)
{
- mSingletonStopMethodArgument = targetStopMethodArgument;
+ this.mSingletonStopMethodArgument = targetStopMethodArgument;
}
// HASingleton implementation ------------------------------------
@@ -147,36 +141,29 @@
*
* @see org.jboss.ha.singleton.HASingletonSupport#startSingleton()
*/
+ @Override
public void startSingleton()
{
super.startSingleton();
try
{
- if (mSingleton != null)
+ if (this.mSingleton != null)
{
- invokeSingletonMethod(
- mSingleton,
- mSingletonStartMethod,
- mSingletonStartMethodArgument
- );
+ this.invokeSingletonMethod( this.mSingleton, this.mSingletonStartMethod, this.mSingletonStartMethodArgument);
}
- else if (mSingletonMBean != null)
+ else if (this.mSingletonMBean != null)
{
- invokeSingletonMBeanMethod(
- mSingletonMBean,
- mSingletonStartMethod,
- mSingletonStartMethodArgument
- );
+ this.invokeSingletonMBeanMethod( this.mSingletonMBean, this.mSingletonStartMethod, this.mSingletonStartMethodArgument);
}
else
{
- log.warn("No singleton configured; cannot start");
+ this.log.warn("No singleton configured; cannot start");
}
}
catch (Exception e)
{
- log.error("Controlled Singleton failed to become master", e);
+ this.log.error("Controlled Singleton failed to become master", e);
}
}
@@ -185,36 +172,29 @@
*
* @see org.jboss.ha.singleton.HASingletonSupport#stopSingleton()
*/
+ @Override
public void stopSingleton()
{
super.stopSingleton();
try
{
- if (mSingleton != null)
+ if (this.mSingleton != null)
{
- invokeSingletonMethod(
- mSingleton,
- mSingletonStopMethod,
- mSingletonStopMethodArgument
- );
+ this.invokeSingletonMethod( this.mSingleton, this.mSingletonStopMethod, this.mSingletonStopMethodArgument);
}
- else if (mSingletonMBean != null)
- {
- invokeSingletonMBeanMethod(
- mSingletonMBean,
- mSingletonStopMethod,
- mSingletonStopMethodArgument
- );
+ else if (this.mSingletonMBean != null)
+ {
+ this.invokeSingletonMBeanMethod( this.mSingletonMBean, this.mSingletonStopMethod, this.mSingletonStopMethodArgument);
}
else
{
- log.warn("No singleton configured; cannot start");
+ this.log.warn("No singleton configured; cannot start");
}
}
catch (Exception e)
{
- log.error("Controlled Singleton failed to resign from master position", e);
+ this.log.error("Controlled Singleton failed to resign from master position", e);
}
}
@@ -227,35 +207,31 @@
if (target != null && operationName != null)
{
Object[] params;
- Class[] types;
+ Class<?>[] types;
- if (param != null)
+ if (param != null)
{
params = new Object[] { param };
types = new Class[] { param.getClass() };
- log.debug("Calling operation: " + operationName +
- "(" + param + "), on target: '" + target + "'");
+ this.log.debug("Calling operation: " + operationName + "(" + param + "), on target: '" + target + "'");
}
else
{
params = NO_ARGS;
types = NO_TYPES;
- log.debug("Calling operation: " + operationName +
- "(), on target: '" + target + "'");
+ this.log.debug("Calling operation: " + operationName + "(), on target: '" + target + "'");
}
Method method = getTargetMethod(target, operationName, types);
return method.invoke(target, params);
}
- else
- {
- log.debug("No configured target mbean or operation to call");
-
- return null;
- }
+
+ this.log.debug("No configured target mbean or operation to call");
+
+ return null;
}
protected Object invokeSingletonMBeanMethod(ObjectName target,
@@ -267,37 +243,35 @@
Object[] params;
String[] signature;
- if (param != null)
+ if (param != null)
{
params = new Object[] { param };
signature = new String[] { param.getClass().getName() };
- log.debug("Calling operation: " + operationName +
- "(" + param + "), on target: '" + target + "'");
+ this.log.debug("Calling operation: " + operationName +
+ "(" + param + "), on target: '" + target + "'");
}
else
{
params = NO_ARGS;
signature = NO_TYPE_NAMES;
- log.debug("Calling operation: " + operationName +
- "(), on target: '" + target + "'");
+ this.log.debug("Calling operation: " + operationName +
+ "(), on target: '" + target + "'");
}
- return server.invoke(target, operationName, params, signature);
+ return this.server.invoke(target, operationName, params, signature);
}
- else
- {
- log.debug("No configured target mbean or operation to call");
-
- return null;
- }
+
+ this.log.debug("No configured target mbean or operation to call");
+
+ return null;
}
- public static Method getTargetMethod(Object target, String methodName, Class[] types)
+ public static Method getTargetMethod(Object target, String methodName, Class<?>[] types)
throws NoSuchMethodException
{
- Class clazz = target.getClass();
+ Class<?> clazz = target.getClass();
NoSuchMethodException nsme = null;
while (clazz != null)
{
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonControllerMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonControllerMBean.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonControllerMBean.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -26,7 +26,7 @@
/**
* The management interface for the singleton controller service.
*
- * @see org.jboss.ha.singleton.HASingletonMBean
+ * @see org.jboss.ha.framework.interfaces.HASingletonMBean
*
* @author <a href="mailto:ivelin at apache.org">Ivelin Ivanov</a>
* @author <a href="mailto:scott.stark at jboss.org">Scott Stark</a>
@@ -34,7 +34,7 @@
* @author <a href="mailto:dimitris at jboss.org">Dimitris Andreadis</a>
* @version $Revision$
*/
-public interface HASingletonControllerMBean extends HASingletonSupportMBean
+public interface HASingletonControllerMBean extends HASingletonSupportMBean
{
/**
* Sets the controlled target singleton
Deleted: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicy.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicy.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicy.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -1,52 +0,0 @@
-package org.jboss.ha.singleton;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.framework.interfaces.HAPartition;
-
-/**
- * HASingletonElectionPolicy.
- *
- * @author <a href="mailto:Alex.Fu at novell.com">Alex Fu</a>
- * @author Brian Stansberry
- * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
- */
-public interface HASingletonElectionPolicy
-{
- /**
- * Called by the HASingleton, during the create service phase, to set the
- * name with which the singleton is registered with the HAPartition.
- *
- * @param serviceName the singleton service name.
- */
- void setSingletonName(String serviceName);
-
- /**
- * Get the singleton name for this election policy.
- *
- * @return the singleton service name.
- */
- String getSingletonName();
-
- /**
- * Called by the HASingleton, during the create service phase to sets the
- * HAPartition; from this the election policy can gain access to the
- * DistributedReplicantManager for tracking the deployment topology for
- * the singleton service and to the HAPartition for making group RPC calls.
- */
- void setHAPartition(HAPartition partition);
-
- /**
- * Get the HA partition where the singleton is deployed, which can be used,
- * amongst other things, to find out which nodes is the singleton available
- * in.
- *
- * @return the HA partition.
- */
- HAPartition getHAPartition();
-
- /**
- * Return the elected master node.
- * @return the master node or null if there're no possible master nodes.
- */
- ClusterNode elect();
-}
\ No newline at end of file
Deleted: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyBase.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyBase.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyBase.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -1,129 +0,0 @@
-/*
- * 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.ha.singleton;
-
-import java.util.List;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.framework.interfaces.HAPartition;
-import org.jboss.system.ServiceMBeanSupport;
-
-/**
- * A base class for policy service that decides which node in the cluster should be
- * the master node to run certain HASingleton service.
- *
- * @author <a href="mailto:afu at novell.com">Alex Fu</a>
- * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
- * @version $Revision$
- */
-public abstract class HASingletonElectionPolicyBase
- extends ServiceMBeanSupport
- implements HASingletonElectionPolicyMBean
-{
- private String mSingletonName;
- private HAPartition mPartition;
- private String mPreferredMaster;
-
- /**
- * @see HASingletonElectionPolicy#setSingletonName
- */
- public void setSingletonName(String singletonName)
- {
- this.mSingletonName = singletonName;
- log.debug("set singleton name to " + this.mSingletonName);
- }
-
- /**
- * @see HASingletonElectionPolicy#getSingletonName
- */
- public String getSingletonName()
- {
- return this.mSingletonName;
- }
-
- /**
- * @see HASingletonElectionPolicy#setPreferredMaster(ClusterNode)
- */
- public void setPreferredMaster(String node)
- {
- this.mPreferredMaster = node;
- }
-
- /**
- * @see HASingletonElectionPolicy#getPreferredMaster()
- */
- public String getPreferredMaster()
- {
- return this.mPreferredMaster;
- }
-
- /**
- * @see HASingletonElectionPolicy#setHAPartition(HAPartition)
- */
- public void setHAPartition(HAPartition partition)
- {
- this.mPartition = partition;
- }
-
- /**
- * @see HASingletonElectionPolicy#getHAPartition()
- */
- public HAPartition getHAPartition()
- {
- return this.mPartition;
- }
-
- /**
- * @see HASingletonElectionPolicy#elect()
- */
- public ClusterNode elect()
- {
- List<ClusterNode> candidates = getCandidates();
- if (candidates == null)
- {
- log.debug("list of cluster node candidates where to run the singleton is null");
- return null;
- }
-
- return elect(candidates);
- }
-
- /**
- * Get the list of candidate {@link ClusterNode} instances where the
- * singleton could be deployed.
- *
- * @return List of {@link ClusterNode} instances.
- */
- protected List<ClusterNode> getCandidates()
- {
- return getHAPartition().getDistributedReplicantManager().lookupReplicantsNodes(getSingletonName());
- }
-
- /**
- * Given a List of candidate {@link ClusterNode} instances, return the
- * elected node where the singleton should run.
- *
- * @param candidates List of {@link ClusterNode}.
- * @return {@link ClusterNode} instance.
- */
- protected abstract ClusterNode elect(List<ClusterNode> candidates);
-}
Deleted: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyMBean.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicyMBean.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -1,36 +0,0 @@
-/*
- * 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.ha.singleton;
-
-
-
-/**
- * Management Bean for HASinigleton Election Policy.
-
- * @author <a href="mailto:Alex.Fu at novell.com">Alex Fu</a>.
- * @version $Revision$
- *
- */
-public interface HASingletonElectionPolicyMBean
- extends org.jboss.system.ServiceMBean, HASingletonElectionPolicy
-{
-}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimple.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimple.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimple.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -25,6 +25,7 @@
import java.util.List;
import org.jboss.ha.framework.interfaces.ClusterNode;
+import org.jboss.ha.framework.interfaces.HASingletonElectionPolicy;
/**
* A simple concrete policy service that decides which node in the cluster should be
@@ -47,22 +48,19 @@
* <attribute name="Position">2</attribute>
*
* If no election policy is defined, the oldest node in the cluster runs the
- * singleton. This behavior can be achieved with this policy when "position"
+ * singleton. This behaivour can be achieved with this policy when "position"
* is set to 0.
*
* @author <a href="mailto:Alex.Fu at novell.com">Alex Fu</a>
* @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
* @version $Revision$
*/
-public class HASingletonElectionPolicySimple
- extends HASingletonElectionPolicyBase
- implements HASingletonElectionPolicySimpleMBean, HASingletonElector
+public class HASingletonElectionPolicySimple
+ implements HASingletonElectionPolicy, HASingletonElectionPolicySimpleMBean
{
// Attributes
private int mPosition = 0; // Default
- // ------------------------------------------------------------- Properties
-
/**
* @see HASingletonElectionPolicySimpleMBean#setPosition(int)
*/
@@ -79,8 +77,6 @@
return this.mPosition;
}
- // ----------------------------------------------------- HASingletonElector
-
public ClusterNode elect(List<ClusterNode> candidates)
{
int size = candidates.size();
@@ -88,5 +84,4 @@
return candidates.get(remainder);
}
-
}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimpleMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimpleMBean.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElectionPolicySimpleMBean.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -29,7 +29,6 @@
*
*/
public interface HASingletonElectionPolicySimpleMBean
- extends HASingletonElectionPolicyMBean
{
/**
* Attribute: position.
Deleted: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElector.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElector.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonElector.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -1,44 +0,0 @@
-/*
- * 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.ha.singleton;
-
-import java.util.List;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-
-/**
- * Serves as an elector in an HASingleton master election by choosing a master
- * node from a list of candidates.
- * <p>
- * Differs from {@link HASingletonElectionPolicy} in that an election policy
- * is also responsible for identifying the list of candidates. An election
- * policy implementation could potentially prepare the list of candidates and
- * then delegate the actual election to an injected
- * <code>HASingletonElector</code>.
- * </p>
- * @author Brian Stansberry
- */
-public interface HASingletonElector
-{
- ClusterNode elect(List<ClusterNode> candidates);
-}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonMBean.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonMBean.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -33,11 +33,14 @@
* Concrete mbeans would usually do activities like regular clean up of database tables
* or saving statistics about cluster usage.
*
+ * Replaced by {@link org.jboss.ha.framework.interfaces.HASingletonMBean}
+ *
* @author <a href="mailto:ivelin at apache.org">Ivelin Ivanov</a>
* @author <a href="mailto:dimitris at jboss.org">Dimitris Andreadis</a>
* @version $Revision$
*/
-public interface HASingletonMBean extends HAServiceMBean
+ at Deprecated
+public interface HASingletonMBean extends HAServiceMBean, org.jboss.ha.framework.interfaces.HASingletonMBean
{
// Constants -----------------------------------------------------
@@ -46,10 +49,4 @@
String HASINGLETON_STARTED_NOTIFICATION = "org.jboss.ha.singleton.started";
String HASINGLETON_STOPPING_NOTIFICATION = "org.jboss.ha.singleton.stopping";
String HASINGLETON_STOPPED_NOTIFICATION = "org.jboss.ha.singleton.stopped";
-
- // Attributes ----------------------------------------------------
-
- /** True if this cluster node has the active mbean singleton, false otherwise */
- boolean isMasterNode();
-
}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupport.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupport.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupport.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -21,16 +21,17 @@
*/
package org.jboss.ha.singleton;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
import javax.management.Notification;
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.jmx.HAServiceMBeanSupport;
+import org.jboss.ha.framework.interfaces.HASingleton;
+import org.jboss.ha.framework.interfaces.HASingletonElectionPolicy;
+import org.jboss.ha.framework.interfaces.HASingletonLifecycle;
+import org.jboss.ha.framework.server.HASingletonImpl;
+import org.jboss.ha.jmx.AbstractHAServiceMBeanSupport;
+
/**
- * Base class for HA-Singleton services.
+ * Base class for HA-Singleton legacy mbean services.
*
* @author <a href="mailto:ivelin at apache.org">Ivelin Ivanov</a>
* @author <a href="mailto:scott.stark at jboss.org">Scott Stark</a>
@@ -39,88 +40,53 @@
* @author <a href="mailto:pferraro at redhat.com">Paul Ferraro</a>
* @version $Revision$
*/
-public class HASingletonSupport extends HAServiceMBeanSupport
- implements HASingletonMBean, HASingleton
+public class HASingletonSupport
+ extends AbstractHAServiceMBeanSupport<HASingleton<Notification>>
+ implements HASingleton<Notification>
{
- // Private Data --------------------------------------------------
-
- private final AtomicBoolean master = new AtomicBoolean(false);
-
- private volatile HASingletonElectionPolicy mElectionPolicyMB = null;
- private volatile boolean restartOnMerge = true;
-
- // Constructors --------------------------------------------------
-
/**
- * Default CTOR
+ * @see org.jboss.ha.framework.interfaces.HASingletonMBean#isMasterNode()
*/
- public HASingletonSupport()
+ public boolean isMasterNode()
{
- // empty
+ return this.getHAService().isMasterNode();
}
-
- // Attributes ----------------------------------------------------
/**
- * @jmx:managed-attribute
- *
- * @return true if this cluster node has the active mbean singleton, false otherwise
+ * @see org.jboss.ha.framework.interfaces.HASingleton#setElectionPolicy(org.jboss.ha.framework.interfaces.HASingletonElectionPolicy)
*/
- public boolean isMasterNode()
+ public void setElectionPolicy(HASingletonElectionPolicy electionPolicy)
{
- return this.master.get();
+ this.getHAService().setElectionPolicy(electionPolicy);
}
-
- /**
- * @see HASingletonSupportMBean#setElectionPolicy(HASingletonElectionPolicyMBean)
- */
- public void setElectionPolicy(HASingletonElectionPolicy mb)
- {
- this.mElectionPolicyMB = mb;
- }
/**
- * @see HASingletonSupportMBean#getElectionPolicy()
+ * @see org.jboss.ha.framework.interfaces.HASingleton#getElectionPolicy()
*/
public HASingletonElectionPolicy getElectionPolicy()
{
- return this.mElectionPolicyMB;
+ return this.getHAService().getElectionPolicy();
}
-
+
/**
- * Gets whether this singleton will stop and restart itself if it is the
- * master and a cluster merge occurs.
- * <p/>
- * A restart allows the service to reset any state that may
- * have gotten out-of-sync with the rest of the cluster while
- * the just-merged split was in effect.
- *
- * @return <code>true</code> if a restart will occur, <code>false</code>
- * otherwise
+ * @see org.jboss.ha.framework.interfaces.HASingleton#getRestartOnMerge()
*/
public boolean getRestartOnMerge()
{
- return this.restartOnMerge;
+ return this.getHAService().getRestartOnMerge();
}
-
+
/**
- * Sets whether this singleton will stop and restart itself if it is the
- * master and a cluster merge occurs?
- * <p/>
- * A restart allows the service to reset any state that may
- * have gotten out-of-sync with the rest of the cluster while
- * the just-merged split was in effect.
- *
- * @param restartOnMerge <code>true</code> if a restart should occur,
- * <code>false</code> otherwise
+ * @see org.jboss.ha.framework.interfaces.HASingleton#setRestartOnMerge(boolean)
*/
public void setRestartOnMerge(boolean restartOnMerge)
{
- this.restartOnMerge = restartOnMerge;
+ this.getHAService().setRestartOnMerge(restartOnMerge);
}
-
+
+
// Public --------------------------------------------------------
-
+
/**
* Extending classes should override this method and implement the custom
* singleton logic. Only one node in the cluster is the active master.
@@ -133,172 +99,32 @@
* the cluster environment information that will be needed by the next node
* elected for master should the current master node fail.
*
- * @see HASingleton
+ * @see HASingletonLifecycle
*/
public void startSingleton()
{
- this.log.debug("startSingleton() : elected for master singleton node");
-
- // Extending classes will implement the singleton logic here
+ this.getHAService().startSingleton();
}
-
+
/**
* Extending classes should override this method and implement the custom
* singleton logic. Only one node in the cluster is the active master.
* If the current node is master and another node is elected for master, this
* method is invoked.
*
- * @see HASingleton
+ * @see HASingletonLifecycle
*/
public void stopSingleton()
{
- this.log.debug("stopSingleton() : another node in the partition (if any) is elected for master");
-
- // Extending classes will implement the singleton logic here
+ this.getHAService().stop();
}
-
-
+
/**
- * When topology changes, a new master is elected based on the result
- * of the isDRMMasterReplica() call.
- *
- * @see HAServiceMBeanSupport#partitionTopologyChanged(List, int)
- * @see org.jboss.ha.framework.interfaces.DistributedReplicantManager#isMasterReplica(String)
+ * @see org.jboss.ha.jmx.AbstractHAServiceMBeanSupport#createHAService()
*/
@Override
- public void partitionTopologyChanged(List newReplicants, int newViewID, boolean merge)
+ protected HASingleton<Notification> createHAService()
{
- boolean isElectedNewMaster;
- if (this.mElectionPolicyMB != null)
- {
- ClusterNode electedNode = this.mElectionPolicyMB.elect();
- isElectedNewMaster = electedNode != null ? electedNode.equals(this.getHAPartition().getClusterNode()) : false;
- }
- else
- {
- isElectedNewMaster = this.isDRMMasterReplica();
- }
-
- this.log.debug("partitionTopologyChanged, isElectedNewMaster=" + isElectedNewMaster
- + ", isMasterNode=" + this.master + ", viewID=" + newViewID);
-
- boolean isMaster = this.master.get();
-
- // if this node is already the master, don't bother electing it again
- if (isElectedNewMaster && isMaster)
- {
- // JBAS-4229
- if (this.restartOnMerge && merge)
- {
- this.restartMaster();
- }
- }
- // just becoming master
- else if (isElectedNewMaster && !isMaster)
- {
- this.makeThisNodeMaster();
- }
- // transition from master to slave
- else if (isMaster)
- {
- this._stopOldMaster();
- }
+ return new HASingletonImpl<Notification>(this, this, this);
}
-
- /**
- * This method will be invoked twice by the local node
- * when it stops as well as by the remote
- */
- public void _stopOldMaster()
- {
- this.log.debug("_stopOldMaster, isMasterNode=" + this.master);
-
- try
- {
- // since this is a cluster call, all nodes will hear it
- // so if the node is not the master, then ignore
- if (this.master.compareAndSet(true, false))
- {
- // notify stopping
- this.sendLocalNotification(HASINGLETON_STOPPING_NOTIFICATION);
-
- // stop the singleton
- this.stopSingleton();
-
- // notify stopped
- this.sendLocalNotification(HASINGLETON_STOPPED_NOTIFICATION);
- }
- }
- catch (Exception ex)
- {
- this.log.error(
- "_stopOldMaster failed. Will still try to start new master. " +
- "You need to examine the reason why the old master wouldn't stop and resolve it. " +
- "It is bad that the old singleton may still be running while we are starting a new one, " +
- "so you need to resolve this ASAP.", ex);
- }
- }
-
- // Protected -----------------------------------------------------
-
- protected void makeThisNodeMaster()
- {
- try
- {
- // stop the old master (if there is one) before starting the new one
-
- // ovidiu 09/02/04 - temporary solution for Case 1843, use an asynchronous
- // distributed call.
- //callMethodOnPartition("_stopOldMaster", new Object[0], new Class[0]);
- this.callAsyncMethodOnPartition("_stopOldMaster", new Object[0], new Class[0]);
-
- this.startNewMaster();
- }
- catch (Exception ex)
- {
- this.log.error("_stopOldMaster failed. New master singleton will not start.", ex);
- }
- }
-
- protected void startNewMaster()
- {
- this.log.debug("startNewMaster, isMasterNode=" + this.master);
-
- this.master.set(true);
-
- // notify starting
- this.sendLocalNotification(HASINGLETON_STARTING_NOTIFICATION);
-
- // start new master
- this.startSingleton();
-
- // notify started
- this.sendLocalNotification(HASINGLETON_STARTED_NOTIFICATION);
- }
-
- protected void restartMaster()
- {
- this._stopOldMaster();
- this.startNewMaster();
- }
-
- @Override
- protected void createService() throws Exception
- {
- super.createService();
-
- if (this.mElectionPolicyMB != null)
- {
- this.mElectionPolicyMB.setHAPartition(this.getHAPartition());
- this.mElectionPolicyMB.setSingletonName(this.getServiceHAName());
- }
- }
-
- // Private -------------------------------------------------------
-
- private void sendLocalNotification(String type)
- {
- Notification n = new Notification(type, this, this.getNextNotificationSequenceNumber());
- super.sendNotificationToLocalListeners(n);
- }
}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupportMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupportMBean.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/HASingletonSupportMBean.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -21,6 +21,8 @@
*/
package org.jboss.ha.singleton;
+import javax.management.Notification;
+
/**
* The management interface for the singleton support service.
*
@@ -28,50 +30,8 @@
* @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
* @version $Revision$
*/
-public interface HASingletonSupportMBean extends HASingletonMBean
+ at SuppressWarnings("deprecation")
+public interface HASingletonSupportMBean
+ extends org.jboss.ha.framework.interfaces.HASingletonMBean, org.jboss.ha.framework.interfaces.HASingleton<Notification>, HASingletonMBean, HASingleton
{
- /**
- * Sets the policy used to determine which cluster node will
- * become the master when the service topology changes. Injection of common
- * attributes into the election policy should be done during createService()
- * method call.
- *
- * @param policy the policy. Can be <code>null</code>.
- */
- void setElectionPolicy(HASingletonElectionPolicy policy);
-
- /**
- * Gets the policy used to determine which cluster node will
- * become the master when the service topology changes.
- *
- * @return the policy. Can be <code>null</code>.
- */
- HASingletonElectionPolicy getElectionPolicy();
-
- /**
- * Gets whether this singleton will stop and restart itself if it is the
- * master and a cluster merge occurs.
- * <p/>
- * A restart allows the service to reset any state that may
- * have gotten out-of-sync with the rest of the cluster while
- * the just-merged split was in effect.
- *
- * @return <code>true</code> if a restart will occur, <code>false</code>
- * otherwise
- */
- boolean getRestartOnMerge();
-
- /**
- * Sets whether this singleton will stop and restart itself if it is the
- * master and a cluster merge occurs.
- * <p/>
- * A restart allows the service to reset any state that may
- * have gotten out-of-sync with the rest of the cluster while
- * the just-merged split was in effect.
- *
- * @param restartOnMerge <code>true</code> if a restart should occur,
- * <code>false</code> otherwise. Default is
- * <code>true</code>.
- */
- void setRestartOnMerge(boolean restartOnMerge);
}
Modified: trunk/cluster/src/main/org/jboss/ha/singleton/PreferredMasterElectionPolicy.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/singleton/PreferredMasterElectionPolicy.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/cluster/src/main/org/jboss/ha/singleton/PreferredMasterElectionPolicy.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -28,6 +28,7 @@
import java.util.List;
import org.jboss.ha.framework.interfaces.ClusterNode;
+import org.jboss.logging.Logger;
/**
* Election policy that chooses the node where the singleton should run based on
@@ -37,10 +38,14 @@
* invalid, it delegates to the standard policy.
*
* @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ * @author Paul Ferraro
*/
-public class PreferredMasterElectionPolicy extends HASingletonElectionPolicySimple
+public class PreferredMasterElectionPolicy
+ extends HASingletonElectionPolicySimple
implements PreferredMasterElectionPolicyMBean
{
+ protected Logger log = Logger.getLogger(this.getClass());
+
private String preferredMaster;
// ------------------------------------------------------------- Properties
@@ -50,7 +55,7 @@
*/
public void setPreferredMaster(String node)
{
- preferredMaster = node;
+ this.preferredMaster = node;
}
/**
@@ -58,7 +63,7 @@
*/
public String getPreferredMaster()
{
- return preferredMaster;
+ return this.preferredMaster;
}
// ----------------------------------------------------- HASingletonElector
@@ -67,14 +72,14 @@
public ClusterNode elect(List<ClusterNode> candidates)
{
// If preferred master is defined and contained in cluster, return it
- if (preferredMaster != null)
+ if (this.preferredMaster != null)
{
- log.debug("Checking if " + preferredMaster + " is in candidate list " + candidates);
+ this.log.debug("Checking if " + this.preferredMaster + " is in candidate list " + candidates);
// First just match on names
for (ClusterNode node : candidates)
{
- if (node.getName().equals(preferredMaster))
+ if (node.getName().equals(this.preferredMaster))
{
return node;
}
@@ -85,7 +90,7 @@
// Create a URI out of the preferred master and try retrieving host
// and port.
- URI uri = createUri(preferredMaster);
+ URI uri = createUri(this.preferredMaster);
// See if we can parse out an InetAddress and port from preferredMaster.
InetAddress addr = parseInetAddress(uri);
@@ -93,7 +98,7 @@
{
int port = uri.getPort();
String rewritten = addr.getHostAddress() + ":" + port;
- if (preferredMaster.equals(rewritten))
+ if (this.preferredMaster.equals(rewritten))
{
rewritten = addr.getHostName() + ":" + port;
}
@@ -123,11 +128,11 @@
{
try
{
- return new URI("cluster://" + preferredMaster);
+ return new URI("cluster://" + this.preferredMaster);
}
catch (URISyntaxException use)
{
- log.debug("Cannot extract URI from " + preferredMaster, use);
+ this.log.debug("Cannot extract URI from " + this.preferredMaster, use);
}
return null;
@@ -154,12 +159,12 @@
try
{
InetAddress addr = InetAddress.getByName(host);
- log.debug("Parsed " + preferredMaster + " into " + addr + " and " + port);
+ this.log.debug("Parsed " + this.preferredMaster + " into " + addr + " and " + port);
return addr;
}
catch (UnknownHostException uhe)
{
- log.debug("Cannot extract InetAddress from " + preferredMaster, uhe);
+ this.log.debug("Cannot extract InetAddress from " + this.preferredMaster, uhe);
}
}
}
Modified: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -1,25 +1,24 @@
/*
- * 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.
- */
-
+ * 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.cluster.defaultcfg.test;
import java.util.EmptyStackException;
@@ -33,128 +32,111 @@
/**
*
- * @author Ivelin Ivanov <ivelin at apache.org>
+ * @author Ivelin Ivanov <ivelin at apache.org>
*
*/
public class HAServiceMBeanSupportUnitTestCase extends TestCase
{
+ private HAServiceMBeanSupportTester haServiceMBeanSupportTester = null;
- private HAServiceMBeanSupportTester haServiceMBeanSupportTester_ = null;
+ public HAServiceMBeanSupportUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public void setUp()
+ {
+ this.haServiceMBeanSupportTester = new HAServiceMBeanSupportTester();
+ }
- public HAServiceMBeanSupportUnitTestCase(String name)
- {
- super(name);
- }
- public void setUp()
- {
- haServiceMBeanSupportTester_ = new HAServiceMBeanSupportTester();
- }
+ @Override
+ public void tearDown()
+ {
+ this.haServiceMBeanSupportTester = null;
+ }
-
- public void tearDown()
- {
- haServiceMBeanSupportTester_ = null;
- }
+ /**
+ *
+ * messages should be sent out to both remote and local listeners.
+ *
+ */
+ public void testSendNotificationBroadcastsToClusterAndLocally()
+ {
+ Notification notification = new Notification("test.notification", "some:name=tester", 1);
+ this.haServiceMBeanSupportTester.sendNotification(notification);
- /**
- *
- * messages should be sent out to both remote and local listeners.
- *
- */
- public void testSendNotificationBroadcastsToClusterAndLocally()
- {
- Notification notification = new Notification("test.notification", "some:name=tester", 1);
- haServiceMBeanSupportTester_.sendNotification( notification );
+ assertSame("sendNotificationToLocalListeners() was not handed the original notification", this.haServiceMBeanSupportTester.invocationStack.pop(), notification);
- assertEquals("sendNotificationToLocalListeners() was not handed the original notification",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+ assertEquals("method not invoked as expected", this.haServiceMBeanSupportTester.invocationStack.pop(), "sendNotificationToLocalListeners");
- assertEquals("method not invoked as expected",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationToLocalListeners");
+ assertSame("sendNotificationRemote() was not handed the original notification", this.haServiceMBeanSupportTester.invocationStack.pop(), notification);
+
+ assertEquals("method not invoked as expected", this.haServiceMBeanSupportTester.invocationStack.pop(), "sendNotificationRemote");
+ }
- assertEquals("sendNotificationRemote() was not handed the original notification",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
-
- assertEquals("method not invoked as expected",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationRemote");
- }
+ /**
+ *
+ * Even if the message cannot be sent out to the cluster,
+ * it should still be delivered to local listeners.
+ *
+ */
+ public void testSendNotificationAfterClusterFailureContinueWithLocal()
+ {
+ this.haServiceMBeanSupportTester.shouldSendNotificationRemoteFail = true;
- /**
- *
- * Even if the message cannot be sent out to the cluster,
- * it should still be delivered to local listeners.
- *
- */
- public void testSendNotificationAfterClusterFailureContinueWithLocal()
- {
- haServiceMBeanSupportTester_.__shouldSendNotificationRemoteFail__ = true;
+ Notification notification = new Notification("test.notification", "some:name=tester", 1);
+ this.haServiceMBeanSupportTester.sendNotification( notification );
+
+ assertEquals("sendNotificationToLocalListeners() was not handed the original notification", this.haServiceMBeanSupportTester.invocationStack.pop(), notification );
- Notification notification = new Notification("test.notification", "some:name=tester", 1);
- haServiceMBeanSupportTester_.sendNotification( notification );
-
- assertEquals("sendNotificationToLocalListeners() was not handed the original notification",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+ assertEquals("method not invoked as expected", this.haServiceMBeanSupportTester.invocationStack.pop(), "sendNotificationToLocalListeners");
+ }
+
+ public void testSendLifecycleNotifications()
+ {
+ Notification notification = new AttributeChangeNotification(this.haServiceMBeanSupportTester, 1, System.currentTimeMillis(), "test", "State", "java.lang.Integer", new Integer(0), new Integer(1));
+
+ this.haServiceMBeanSupportTester.setSendRemoteLifecycleNotifications(false);
+
+ this.haServiceMBeanSupportTester.sendNotification( notification );
+
+ assertEquals("sendNotificationToLocalListeners() was handed the original notification", this.haServiceMBeanSupportTester.invocationStack.pop(), notification );
- assertEquals("method not invoked as expected",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationToLocalListeners");
- }
-
- public void testSendLifecycleNotifications()
- {
- Notification notification = new AttributeChangeNotification(
- haServiceMBeanSupportTester_,
- 1, System.currentTimeMillis(), "test",
- "State", "java.lang.Integer",
- new Integer(0), new Integer(1)
- );
-
- haServiceMBeanSupportTester_.setSendRemoteLifecycleNotifications(false);
-
- haServiceMBeanSupportTester_.sendNotification( notification );
-
- assertEquals("sendNotificationToLocalListeners() was handed the original notification",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+ assertEquals("method invoked as expected", this.haServiceMBeanSupportTester.invocationStack.pop(), "sendNotificationToLocalListeners");
- assertEquals("method invoked as expected",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationToLocalListeners");
+ try
+ {
+ this.haServiceMBeanSupportTester.invocationStack.pop();
+ fail("sendNotificationRemote() was not handed the original notification");
+ }
+ catch (EmptyStackException good) {}
+
+ this.haServiceMBeanSupportTester.setSendRemoteLifecycleNotifications(true);
+ this.haServiceMBeanSupportTester.setSendLocalLifecycleNotifications(false);
+
+ this.haServiceMBeanSupportTester.sendNotification( notification );
- try
- {
- haServiceMBeanSupportTester_.__invokationStack__.pop();
- fail("sendNotificationRemote() was not handed the original notification");
- }
- catch (EmptyStackException good) {}
-
- haServiceMBeanSupportTester_.setSendRemoteLifecycleNotifications(true);
- haServiceMBeanSupportTester_.setSendLocalLifecycleNotifications(false);
-
- haServiceMBeanSupportTester_.sendNotification( notification );
-
- assertEquals("sendNotificationRemote() was handed the original notification",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
-
- assertEquals("method invoked as expected",
- haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationRemote");
-
- try
- {
- haServiceMBeanSupportTester_.__invokationStack__.pop();
- fail("sendNotificationToLocalListeners() was not handed the original notification");
- }
- catch (EmptyStackException good) {}
- }
-
- public void testServiceHAName() throws Exception
- {
- assertEquals("Default name correct", HAServiceMBeanSupportTester.SERVICE_NAME,
- haServiceMBeanSupportTester_.getServiceHAName());
-
- haServiceMBeanSupportTester_.setServiceHAName("Test");
-
- assertEquals("Specified name correct", "Test",
- haServiceMBeanSupportTester_.getServiceHAName());
- }
-
+ assertEquals("sendNotificationRemote() was handed the original notification", this.haServiceMBeanSupportTester.invocationStack.pop(), notification );
+
+ assertEquals("method invoked as expected", this.haServiceMBeanSupportTester.invocationStack.pop(), "sendNotificationRemote");
+
+ try
+ {
+ this.haServiceMBeanSupportTester.invocationStack.pop();
+ fail("sendNotificationToLocalListeners() was not handed the original notification");
+ }
+ catch (EmptyStackException good) {}
+ }
+
+ public void testServiceHAName() throws Exception
+ {
+ assertEquals("Default name correct", HAServiceMBeanSupportTester.SERVICE_NAME, this.haServiceMBeanSupportTester.getServiceHAName());
+
+ this.haServiceMBeanSupportTester.setServiceHAName("Test");
+
+ assertEquals("Specified name correct", "Test", this.haServiceMBeanSupportTester.getServiceHAName());
+ }
}
Modified: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -1,24 +1,24 @@
/*
- * 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.
- */
+ * 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.util.ArrayList;
@@ -30,229 +30,214 @@
/**
* Tests of the HASingletonSupport class.
*
- * @author Ivelin Ivanov <ivelin at jboss.org>
- * @author Brian Stansberry
+ * @author Ivelin Ivanov <ivelin at jboss.org>
+ * @author Brian Stansberry
*
*/
public class HASingletonSupportUnitTestCase extends TestCase
{
- private HASingletonSupportTester singletonSupportTester = null;
+ private HASingletonSupportTester singletonSupportTester = null;
- public HASingletonSupportUnitTestCase(String testCaseName)
- {
- super(testCaseName);
- }
+ public HASingletonSupportUnitTestCase(String testCaseName)
+ {
+ super(testCaseName);
+ }
- public void setUp()
- {
- singletonSupportTester = new HASingletonSupportTester();
- singletonSupportTester.setRestartOnMerge(true);
- }
-
- public void tearDown()
- {
- singletonSupportTester = null;
- }
-
- public void testStartService() throws Exception
- {
- singletonSupportTester.start();
+ @Override
+ public void setUp()
+ {
+ this.singletonSupportTester = new HASingletonSupportTester();
+ this.singletonSupportTester.setRestartOnMerge(true);
+ }
+
+ @Override
+ public void tearDown()
+ {
+ this.singletonSupportTester = null;
+ }
+
+ public void testStartService() throws Exception
+ {
+ this.singletonSupportTester.start();
- // test that the correct start sequence was followed correctly
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "registerDRMListener");
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "registerRPCHandler");
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "setupPartition");
- }
+ // test that the correct start sequence was followed correctly
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "registerDRMListener");
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "registerRPCHandler");
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "setupPartition");
+ }
- public void testStopService() throws Exception
- {
- singletonSupportTester.start();
- singletonSupportTester.stop();
+ public void testStopService() throws Exception
+ {
+ this.singletonSupportTester.start();
+ this.singletonSupportTester.stop();
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "unregisterRPCHandler");
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "unregisterDRMListener");
- }
-
- public void testBecomeMasterNode() throws Exception
- {
- becomeMasterNodeTest(false);
- }
-
- private void becomeMasterNodeTest(boolean merge) throws Exception
- {
- singletonSupportTester.start();
-
- // register DRM Listener is expected to call back
- singletonSupportTester.__isDRMMasterReplica__ = true;
- singletonSupportTester.partitionTopologyChanged( new ArrayList(2), 1, merge);
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "unregisterRPCHandler");
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "unregisterDRMListener");
+ }
+
+ public void testBecomeMasterNode() throws Exception
+ {
+ this.becomeMasterNodeTest(false);
+ }
+
+ private void becomeMasterNodeTest(boolean merge) throws Exception
+ {
+ this.singletonSupportTester.start();
+
+ // register DRM Listener is expected to call back
+ this.singletonSupportTester.isDRMMasterReplica = true;
+ this.singletonSupportTester.getDelegate().partitionTopologyChanged(new ArrayList<Integer>(2), 1, merge);
- // test whether it was elected
- assertTrue("expected to become master", singletonSupportTester.isMasterNode());
-
- // test whether the election sequence was followed correctly
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "startSingleton");
- //assertEquals("method not invoked as expected",
- // singletonSupportTester.__invokationStack__.pop(), "callMethodOnCluster:_stopOldMaster");
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "makeThisNodeMaster");
- }
-
- public void testBecomeSlaveNodeWithAnotherMaster() throws Exception
- {
- becomeSlaveNodeWithAnotherMasterTest(false);
- }
-
- private void becomeSlaveNodeWithAnotherMasterTest(boolean merge) throws Exception
- {
- singletonSupportTester.start();
-
- boolean savedIsMasterNode = singletonSupportTester.isMasterNode();
-
- // register DRM Listener is expected to call back
- singletonSupportTester.__isDRMMasterReplica__ = false;
- singletonSupportTester.partitionTopologyChanged(new ArrayList(2), 1, merge);
-
- // this call back should not change the master/slave status
- assertEquals("expected to be still in old master/slave state", singletonSupportTester.isMasterNode(), savedIsMasterNode );
-
- // the new master is expected to call back
- singletonSupportTester._stopOldMaster();
-
- if (savedIsMasterNode)
- {
- assertEquals("this node was the old master, but method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "stopSingleton");
- }
+ // test whether it was elected
+ assertTrue("expected to become master", this.singletonSupportTester.isMasterNode());
- // now it should be slave
- assertTrue("expected to be slave", !singletonSupportTester.isMasterNode());
-
- }
+ // test whether the election sequence was followed correctly
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "startSingleton");
+ //assertEquals("method not invoked as expected", singletonSupportTester.invocationStack.pop(), "callMethodOnCluster:_stopOldMaster");
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "makeThisNodeMaster");
+ }
+
+ public void testBecomeSlaveNodeWithAnotherMaster() throws Exception
+ {
+ this.becomeSlaveNodeWithAnotherMasterTest(false);
+ }
+
+ private void becomeSlaveNodeWithAnotherMasterTest(boolean merge) throws Exception
+ {
+ this.singletonSupportTester.start();
+
+ boolean savedIsMasterNode = this.singletonSupportTester.isMasterNode();
+
+ // register DRM Listener is expected to call back
+ this.singletonSupportTester.isDRMMasterReplica = false;
+ this.singletonSupportTester.getDelegate().partitionTopologyChanged(new ArrayList<Integer>(2), 1, merge);
+
+ // this call back should not change the master/slave status
+ assertEquals("expected to be still in old master/slave state", this.singletonSupportTester.isMasterNode(), savedIsMasterNode );
+
+ // the new master is expected to call back
+ this.singletonSupportTester.getDelegate().stopIfMaster();
+
+ if (savedIsMasterNode)
+ {
+ assertEquals("this node was the old master, but method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "stopSingleton");
+ }
+
+ // now it should be slave
+ assertTrue("expected to be slave", !this.singletonSupportTester.isMasterNode());
+
+ }
- public void testStopOnlyNode() throws Exception
- {
- singletonSupportTester.start();
-
- // register DRM Listener is expected to call back
- singletonSupportTester.__isDRMMasterReplica__ = true;
- singletonSupportTester.partitionTopologyChanged( new ArrayList(2), 1, false);
+ public void testStopOnlyNode() throws Exception
+ {
+ this.singletonSupportTester.start();
+
+ // register DRM Listener is expected to call back
+ this.singletonSupportTester.isDRMMasterReplica = true;
+ this.singletonSupportTester.getDelegate().partitionTopologyChanged(new ArrayList<Integer>(2), 1, false);
- // test whether it was elected for master
- assertTrue("expected to become master", singletonSupportTester.isMasterNode());
-
- singletonSupportTester.stop();
-
- // register DRM Listener is expected to call back
- singletonSupportTester.__isDRMMasterReplica__ = false;
- // since the only node (this one) in the partition is now removed, the replicants list should be empty
- singletonSupportTester.partitionTopologyChanged(new ArrayList(0), 1, false);
-
- assertTrue("expected to have made a call to _stopOldMaster(), thus become slave", !singletonSupportTester.isMasterNode() );
-
- assertEquals("method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "stopSingleton");
+ // test whether it was elected for master
+ assertTrue("expected to become master", this.singletonSupportTester.isMasterNode());
- }
-
- public void testStartServiceWithRestartOff() throws Exception
- {
- singletonSupportTester.setRestartOnMerge(false);
- testStartService();
- }
+ this.singletonSupportTester.stop();
+
+ // register DRM Listener is expected to call back
+ this.singletonSupportTester.isDRMMasterReplica = false;
+ // since the only node (this one) in the partition is now removed, the replicants list should be empty
+ this.singletonSupportTester.getDelegate().partitionTopologyChanged(new ArrayList<Integer>(0), 1, false);
+
+ assertTrue("expected to have made a call to _stopOldMaster(), thus become slave", !this.singletonSupportTester.isMasterNode() );
+
+ assertEquals("method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "stopSingleton");
+
+ }
+
+ public void testStartServiceWithRestartOff() throws Exception
+ {
+ this.singletonSupportTester.setRestartOnMerge(false);
+ this.testStartService();
+ }
- public void testStopServiceWithRestartOff() throws Exception
- {
- singletonSupportTester.setRestartOnMerge(false);
- testStopService();
- }
-
- public void testBecomeMasterNodeWithRestartOff() throws Exception
- {
- singletonSupportTester.setRestartOnMerge(false);
- becomeMasterNodeTest(false);
- }
-
- public void testBecomeSlaveNodeWithAnotherMasterWithRestartOff() throws Exception
- {
- singletonSupportTester.setRestartOnMerge(false);
- becomeSlaveNodeWithAnotherMasterTest(false);
- }
-
- public void testBecomeMasterNodeDuringMerge() throws Exception
- {
- becomeMasterNodeTest(true);
- }
-
- public void testMasterRestartDuringMerge() throws Exception
- {
- // Just run the BecomeMaster test to get ourself set up as master
- becomeMasterNodeTest(false);
-
- // Drain off any un-popped events
- singletonSupportTester.__invokationStack__.clear();
-
- singletonSupportTester.partitionTopologyChanged( new ArrayList(3), 2, true);
+ public void testStopServiceWithRestartOff() throws Exception
+ {
+ this.singletonSupportTester.setRestartOnMerge(false);
+ this.testStopService();
+ }
+
+ public void testBecomeMasterNodeWithRestartOff() throws Exception
+ {
+ this.singletonSupportTester.setRestartOnMerge(false);
+ this.becomeMasterNodeTest(false);
+ }
+
+ public void testBecomeSlaveNodeWithAnotherMasterWithRestartOff() throws Exception
+ {
+ this.singletonSupportTester.setRestartOnMerge(false);
+ this.becomeSlaveNodeWithAnotherMasterTest(false);
+ }
+
+ public void testBecomeMasterNodeDuringMerge() throws Exception
+ {
+ this.becomeMasterNodeTest(true);
+ }
+
+ public void testMasterRestartDuringMerge() throws Exception
+ {
+ // Just run the BecomeMaster test to get ourself set up as master
+ this.becomeMasterNodeTest(false);
+
+ // Drain off any un-popped events
+ this.singletonSupportTester.invocationStack.clear();
+
+ this.singletonSupportTester.getDelegate().partitionTopologyChanged(new ArrayList<Integer>(3), 2, true);
+
+ // test whether it's still master
+ assertTrue("expected to remain master", this.singletonSupportTester.isMasterNode());
+
+ // test whether the election sequence was followed correctly
+ assertEquals("method not invoked as expected", "startSingleton", this.singletonSupportTester.invocationStack.pop());
+ assertEquals("method not invoked as expected", "stopSingleton", this.singletonSupportTester.invocationStack.pop());
+ assertEquals("method not invoked as expected", "restartMaster", this.singletonSupportTester.invocationStack.pop());
+ }
+
+ public void testBecomeSlaveNodeWithAnotherMasterDuringMerge() throws Exception
+ {
+ // Just run the BecomeMaster test to get ourself set up as master
+ this.becomeMasterNodeTest(false);
+
+ // Drain off any un-popped events
+ this.singletonSupportTester.invocationStack.clear();
+
+ this.singletonSupportTester.isDRMMasterReplica = false;
+
+ this.singletonSupportTester.getDelegate().partitionTopologyChanged(new ArrayList<Integer>(3), 2, true);
+
+ // now it should be slave
+ assertFalse("expected to be slave", this.singletonSupportTester.isMasterNode());
+
+ assertEquals("this node was the old master, but method not invoked as expected", this.singletonSupportTester.invocationStack.pop(), "stopSingleton");
+ }
- // test whether it's still master
- assertTrue("expected to remain master", singletonSupportTester.isMasterNode());
-
- // test whether the election sequence was followed correctly
- assertEquals("method not invoked as expected",
- "startSingleton", singletonSupportTester.__invokationStack__.pop());
- assertEquals("method not invoked as expected",
- "stopSingleton", singletonSupportTester.__invokationStack__.pop());
- assertEquals("method not invoked as expected",
- "restartMaster", singletonSupportTester.__invokationStack__.pop());
- }
-
- public void testBecomeSlaveNodeWithAnotherMasterDuringMerge() throws Exception
- {
- // Just run the BecomeMaster test to get ourself set up as master
- becomeMasterNodeTest(false);
-
- // Drain off any un-popped events
- singletonSupportTester.__invokationStack__.clear();
-
- singletonSupportTester.__isDRMMasterReplica__ = false;
-
- singletonSupportTester.partitionTopologyChanged( new ArrayList(3), 2, true);
-
- // now it should be slave
- assertFalse("expected to be slave", singletonSupportTester.isMasterNode());
-
- assertEquals("this node was the old master, but method not invoked as expected",
- singletonSupportTester.__invokationStack__.pop(), "stopSingleton");
- }
-
-
- public void testMasterRestartDuringMergeWithRestartOff() throws Exception
- {
- singletonSupportTester.setRestartOnMerge(false);
-
- // Just run the BecomeMaster test to get ourself set up as master
- testBecomeMasterNode();
-
- // Drain off any un-popped events
- singletonSupportTester.__invokationStack__.clear();
-
- singletonSupportTester.partitionTopologyChanged( new ArrayList(3), 2, true);
-
- // test whether it's still master
- assertTrue("expected to remain master", singletonSupportTester.isMasterNode());
-
- // test whether the election sequence was followed correctly
- assertEquals("method not invoked as expected",
- "isDRMMasterReplica", singletonSupportTester.__invokationStack__.pop());
- assertEquals("method not invoked as expected",
- 0, singletonSupportTester.__invokationStack__.size());
- }
-
+
+ public void testMasterRestartDuringMergeWithRestartOff() throws Exception
+ {
+ this.singletonSupportTester.setRestartOnMerge(false);
+
+ // Just run the BecomeMaster test to get ourself set up as master
+ this.testBecomeMasterNode();
+
+ // Drain off any un-popped events
+ this.singletonSupportTester.invocationStack.clear();
+
+ this.singletonSupportTester.getDelegate().partitionTopologyChanged(new ArrayList<Integer>(3), 2, true);
+
+ // test whether it's still master
+ assertTrue("expected to remain master", this.singletonSupportTester.isMasterNode());
+
+ // test whether the election sequence was followed correctly
+ assertEquals("method not invoked as expected", "isDRMMasterReplica", this.singletonSupportTester.invocationStack.pop());
+ assertEquals("method not invoked as expected", 0, this.singletonSupportTester.invocationStack.size());
+ }
}
Modified: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PreferredMasterElectionPolicyUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PreferredMasterElectionPolicyUnitTestCase.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PreferredMasterElectionPolicyUnitTestCase.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -24,14 +24,13 @@
import java.util.ArrayList;
import java.util.List;
+import junit.framework.TestCase;
+
import org.jboss.ha.framework.interfaces.ClusterNode;
import org.jboss.ha.framework.server.ClusterNodeImpl;
import org.jboss.ha.singleton.PreferredMasterElectionPolicy;
-import org.jboss.ha.singleton.PreferredMasterElectionPolicyMBean;
import org.jgroups.stack.IpAddress;
-import junit.framework.TestCase;
-
/**
* Unit tests for the preferred master election policy. The tested policy has
* been configured with position 0 which means that the first member of the
@@ -46,7 +45,7 @@
{
private final List<ClusterNode> candidates = new ArrayList<ClusterNode>(2);
- private PreferredMasterElectionPolicyMBean policy;
+ private PreferredMasterElectionPolicy policy;
@Override
protected void setUp() throws Exception
@@ -59,14 +58,7 @@
candidates.add(cn1);
candidates.add(cn2);
- policy = new PreferredMasterElectionPolicy()
- {
- @Override
- protected List<ClusterNode> getCandidates()
- {
- return candidates;
- }
- };
+ policy = new PreferredMasterElectionPolicy();
policy.setPosition(0);
}
@@ -74,13 +66,13 @@
public void testIpPort() throws Exception
{
policy.setPreferredMaster("127.0.0.1:1199");
- assertEquals(candidates.get(1), policy.elect());
+ assertEquals(candidates.get(1), policy.elect(this.candidates));
}
public void testHostPort() throws Exception
{
policy.setPreferredMaster("localhost:1199");
- assertEquals(candidates.get(1), policy.elect());
+ assertEquals(candidates.get(1), policy.elect(this.candidates));
}
public void testOnlyPort() throws Exception
@@ -88,7 +80,7 @@
policy.setPreferredMaster(":1199");
/* invalid preferred master definiton, so 1st candidate in the list
* should be chosen */
- assertEquals(candidates.get(0), policy.elect());
+ assertEquals(candidates.get(0), policy.elect(this.candidates));
}
public void testNonNumericPort() throws Exception
@@ -96,7 +88,7 @@
policy.setPreferredMaster("localhost:abcd");
/* invalid preferred master definiton, so 1st candidate in the list
* should be chosen */
- assertEquals(candidates.get(0), policy.elect());
+ assertEquals(candidates.get(0), policy.elect(this.candidates));
}
public void testUnknownHost() throws Exception
@@ -104,7 +96,7 @@
policy.setPreferredMaster("onceuponatimeinalandfarfarawaylivedamancalledgalder:1199");
/* invalid preferred master definiton, so 1st candidate in the list
* should be chosen */
- assertEquals(candidates.get(0), policy.elect());
+ assertEquals(candidates.get(0), policy.elect(this.candidates));
}
public void testEmpty() throws Exception
@@ -112,7 +104,7 @@
policy.setPreferredMaster("");
/* invalid preferred master definiton, so 1st candidate in the list
* should be chosen */
- assertEquals(candidates.get(0), policy.elect());
+ assertEquals(candidates.get(0), policy.elect(this.candidates));
}
public void testGarbage() throws Exception
@@ -120,6 +112,6 @@
policy.setPreferredMaster("%^$%&%^&$%$£");
/* invalid preferred master definiton, so 1st candidate in the list
* should be chosen */
- assertEquals(candidates.get(0), policy.elect());
+ assertEquals(candidates.get(0), policy.elect(this.candidates));
}
}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterService.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterService.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterService.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -22,17 +22,15 @@
package org.jboss.web.tomcat.service.modcluster;
-import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.management.Notification;
-
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.Server;
@@ -42,24 +40,29 @@
import org.jboss.ha.framework.interfaces.ClusterNode;
import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
import org.jboss.ha.framework.interfaces.HAPartition;
+import org.jboss.ha.framework.interfaces.HASingletonElectionPolicy;
+import org.jboss.ha.framework.server.HAServiceEvent;
+import org.jboss.ha.framework.server.HAServiceEventFactory;
+import org.jboss.ha.framework.server.HAServiceImpl;
+import org.jboss.ha.framework.server.HAServiceRpcHandler;
+import org.jboss.ha.framework.server.HASingletonImpl;
import org.jboss.ha.singleton.HASingletonElectionPolicySimple;
-import org.jboss.ha.singleton.HASingletonElector;
-import org.jboss.ha.singleton.HASingletonSupport;
import org.jboss.web.tomcat.service.modcluster.config.BalancerConfiguration;
import org.jboss.web.tomcat.service.modcluster.config.ModClusterConfig;
import org.jboss.web.tomcat.service.modcluster.config.NodeConfiguration;
-import org.jboss.web.tomcat.service.modcluster.ha.ModClusterServiceDRMEntry;
-import org.jboss.web.tomcat.service.modcluster.ha.ModClusterServiceHASingletonElectionPolicy;
import org.jboss.web.tomcat.service.modcluster.ha.ClusteredMCMPHandler;
import org.jboss.web.tomcat.service.modcluster.ha.ClusteredMCMPHandlerImpl;
import org.jboss.web.tomcat.service.modcluster.ha.HASingletonAwareResetRequestSource;
+import org.jboss.web.tomcat.service.modcluster.ha.ModClusterServiceDRMEntry;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.BooleanGroupRpcResponse;
-import org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceStateGroupRpcResponse;
+import org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.GroupRpcResponse;
-import org.jboss.web.tomcat.service.modcluster.ha.rpc.InetAddressGroupRpcResponse;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.MCMPServerDiscoveryEvent;
+import org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceRpcHandler;
+import org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceStateGroupRpcResponse;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.PeerMCMPDiscoveryStatus;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.ResetRequestGroupRpcResponse;
+import org.jboss.web.tomcat.service.modcluster.ha.rpc.ResetRequestSourceRpcHandler;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.StringGroupRpcResponse;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.ThrowableGroupRpcResponse;
import org.jboss.web.tomcat.service.modcluster.load.LoadBalanceFactorProvider;
@@ -77,31 +80,32 @@
* @author Brian Stansberry
* @version $Revision$
*/
-public class ModClusterService extends HASingletonSupport
- implements JBossWebEventHandler, ModClusterServiceMBean
+public class ModClusterService extends HASingletonImpl<HAServiceEvent>
+ implements JBossWebEventHandler, ModClusterServiceMBean, ModClusterServiceRpcHandler<List<?>, MCMPServerState>
{
+ private static final Class<?>[] STOP_OLD_MASTER_TYPES = new Class[] { String.class };
+
// ----------------------------------------------------------------- Fields
+ final MCMPHandler localHandler;
+ final ClusteredMCMPHandler clusteredHandler;
+ final HASingletonAwareResetRequestSource resetRequestSource;
+ final Map<ClusterNode, MCMPServerDiscoveryEvent> proxyChangeDigest =
+ new HashMap<ClusterNode, MCMPServerDiscoveryEvent>();
+
/**
* The string manager for this package.
*/
- private final StringManager sm = StringManager.getManager(Constants.Package);
+ final StringManager sm = StringManager.getManager(Constants.Package);
- private final HASingletonAwareResetRequestSource resetRequestSource;
- private final MCMPHandler localHandler;
- private final ClusteredMCMPHandler clusteredHandler;
private final LoadBalanceFactorProvider loadManager;
private final RpcHandler rpcHandler;
private final JBossWebEventHandler eventHandlerDelegate;
- private final ModClusterServiceHASingletonElectionPolicy electionPolicy;
private final String domain;
- private final Map<ClusterNode, MCMPServerDiscoveryEvent> proxyChangeDigest =
- new HashMap<ClusterNode, MCMPServerDiscoveryEvent>();
-
+ volatile int latestLoad;
private volatile int statusCount = 0;
private volatile int processStatusFrequency = 1;
- private volatile int latestLoad;
private ModClusterServiceDRMEntry drmEntry;
@@ -131,29 +135,29 @@
public ModClusterService(HAPartition partition,
ModClusterConfig config,
LoadBalanceFactorProvider loadFactorProvider,
- HASingletonElector singletonElector)
- {
- assert partition != null : sm.getString("modcluster.error.iae.null", "partition");
- assert loadFactorProvider != null : sm.getString("modcluster.error.iae.null", "loadFactorProvider");
- assert config != null : sm.getString("modcluster.error.iae.null", "config is null");
+ HASingletonElectionPolicy electionPolicy)
+ {
+ super(new HAServiceEventFactory());
- setHAPartition(partition);
+ assert partition != null : this.sm.getString("modcluster.error.iae.null", "partition");
+ assert loadFactorProvider != null : this.sm.getString("modcluster.error.iae.null", "loadFactorProvider");
+ assert config != null : this.sm.getString("modcluster.error.iae.null", "config is null");
+ this.setHAPartition(partition);
+
this.resetRequestSource = new HASingletonAwareResetRequestSource(config, config, partition, ClusteredMCMPHandler.HA_SERVICE_NAME);
this.localHandler = new DefaultMCMPHandler(config, this.resetRequestSource);
// this.localHandler.init();
this.clusteredHandler = new ClusteredMCMPHandlerImpl(this.localHandler, partition, ClusteredMCMPHandler.HA_SERVICE_NAME);
this.loadManager = loadFactorProvider;
- this.eventHandlerDelegate = new DefaultJBossWebEventHandler(config, config, clusteredHandler, loadFactorProvider);
- this.domain = config.getDomain();
- if (singletonElector == null)
- singletonElector = new HASingletonElectionPolicySimple();
- this.electionPolicy = new ModClusterServiceHASingletonElectionPolicy(singletonElector);
- setElectionPolicy(this.electionPolicy);
+ this.eventHandlerDelegate = new DefaultJBossWebEventHandler(config, config, this.clusteredHandler, loadFactorProvider);
+ this.domain = config.getDomain();
- this.drmEntry = new ModClusterServiceDRMEntry(partition.getClusterNode(), null);
+ this.setElectionPolicy((electionPolicy != null) ? electionPolicy : new HASingletonElectionPolicySimple());
- this.rpcHandler = new RpcHandler();
+ this.drmEntry = new ModClusterServiceDRMEntry(partition.getClusterNode(), this.domain, null);
+
+ this.rpcHandler = new RpcHandler();
}
/**
@@ -177,31 +181,30 @@
HASingletonAwareResetRequestSource resetRequestSource,
ClusteredMCMPHandler clusteredHandler,
LoadBalanceFactorProvider loadManager,
- HASingletonElector singletonElector)
+ HASingletonElectionPolicy electionPolicy)
{
- assert partition != null : sm.getString("modcluster.error.iae.null", "partition");
- assert localHandler != null : sm.getString("modcluster.error.iae.null", "localHandler");
- assert loadManager != null : sm.getString("modcluster.error.iae.null", "loadManager");
- assert resetRequestSource != null : sm.getString("modcluster.error.iae.null", "resetRequestSource");
- assert nodeConfig != null : sm.getString("modcluster.error.iae.null", "nodeConfig");
- assert balancerConfig != null : sm.getString("modcluster.error.iae.null", "balancerConfig");
- assert clusteredHandler != null : sm.getString("modcluster.error.iae.null", "clusteredHandler");
+ super(new HAServiceEventFactory());
- setHAPartition(partition);
+ assert partition != null : this.sm.getString("modcluster.error.iae.null", "partition");
+ assert localHandler != null : this.sm.getString("modcluster.error.iae.null", "localHandler");
+ assert loadManager != null : this.sm.getString("modcluster.error.iae.null", "loadManager");
+ assert resetRequestSource != null : this.sm.getString("modcluster.error.iae.null", "resetRequestSource");
+ assert nodeConfig != null : this.sm.getString("modcluster.error.iae.null", "nodeConfig");
+ assert balancerConfig != null : this.sm.getString("modcluster.error.iae.null", "balancerConfig");
+ assert clusteredHandler != null : this.sm.getString("modcluster.error.iae.null", "clusteredHandler");
+ this.setHAPartition(partition);
+
this.localHandler = localHandler;
this.resetRequestSource = resetRequestSource;
this.clusteredHandler = clusteredHandler;
this.loadManager = loadManager;
this.eventHandlerDelegate = new DefaultJBossWebEventHandler(nodeConfig, balancerConfig, clusteredHandler, loadManager);
- this.domain = nodeConfig.getDomain();
+ this.domain = nodeConfig.getDomain();
- if (singletonElector == null)
- singletonElector = new HASingletonElectionPolicySimple();
- this.electionPolicy = new ModClusterServiceHASingletonElectionPolicy(singletonElector);
- setElectionPolicy(this.electionPolicy);
+ this.setElectionPolicy((electionPolicy != null) ? electionPolicy : new HASingletonElectionPolicySimple());
- this.drmEntry = new ModClusterServiceDRMEntry(partition.getClusterNode(), null);
+ this.drmEntry = new ModClusterServiceDRMEntry(partition.getClusterNode(), this.domain, null);
this.rpcHandler = new RpcHandler();
}
@@ -235,7 +238,7 @@
public void reset()
{
this.clusteredHandler.reset();
- }
+ }
// ---------------------------------------------------- JBossWebEventHandler
@@ -250,7 +253,7 @@
public void shutdown()
{
// Use the standard logic
- this.eventHandlerDelegate.shutdown();
+ this.eventHandlerDelegate.shutdown();
}
@@ -260,76 +263,76 @@
this.resetRequestSource.setJbossWebServer(server);
// Use the standard logic
- this.eventHandlerDelegate.startServer(server);
+ this.eventHandlerDelegate.startServer(server);
}
public void stopServer(Server server)
{
// Use the standard logic
- this.eventHandlerDelegate.stopServer(server);
+ this.eventHandlerDelegate.stopServer(server);
}
public void config(Engine engine)
- {
+ {
// If needed, create automagical JVM route (address + port + engineName)
try {
Utils.establishJvmRouteAndConnectorAddress(engine, this.clusteredHandler);
} catch (Exception e) {
this.clusteredHandler.markProxiesInError();
- log.info(sm.getString("modcluster.error.addressJvmRoute"), e);
+ this.log.info(this.sm.getString("modcluster.error.addressJvmRoute"), e);
return;
}
this.drmEntry.addJvmRoute(engine.getJvmRoute());
- updateLocalDRM(drmEntry);
+ this.updateLocalDRM(this.drmEntry);
// Use the standard logic
this.eventHandlerDelegate.config(engine);
}
public void removeAll(Engine engine)
- {
+ {
// Use the standard logic
this.eventHandlerDelegate.removeAll(engine);
this.drmEntry.removeJvmRoute(engine.getJvmRoute());
- updateLocalDRM(drmEntry);
+ this.updateLocalDRM(this.drmEntry);
}
public void addContext(Context context)
{
// Use the standard logic
- this.eventHandlerDelegate.addContext(context);
+ this.eventHandlerDelegate.addContext(context);
}
public void startContext(Context context)
{
// Use the standard logic
- this.eventHandlerDelegate.startContext(context);
+ this.eventHandlerDelegate.startContext(context);
}
public void stopContext(Context context)
{
// Use the standard logic
- this.eventHandlerDelegate.stopContext(context);
+ this.eventHandlerDelegate.stopContext(context);
}
public void removeContext(Context context)
{
// Use the standard logic
- this.eventHandlerDelegate.removeContext(context);
+ this.eventHandlerDelegate.removeContext(context);
}
public void status(Engine engine)
{
- this.latestLoad = loadManager.getLoadBalanceFactor();
+ this.latestLoad = this.loadManager.getLoadBalanceFactor();
if (this.isMasterNode())
{
- statusCount = (statusCount + 1) % processStatusFrequency;
- if (statusCount == 0)
+ this.statusCount = (this.statusCount + 1) % this.processStatusFrequency;
+ if (this.statusCount == 0)
{
- updateClusterStatus();
+ this.updateClusterStatus();
}
}
}
@@ -356,12 +359,6 @@
// ------------------------------------------------------- Public Overrides
@Override
- public void _stopOldMaster()
- {
- this.stopOldMaster(this.getDomain());
- }
-
- @Override
public void startSingleton()
{
super.startSingleton();
@@ -370,7 +367,7 @@
this.resetRequestSource.setMasterNode(true);
// Ensure we do a full status on the next event
- this.statusCount = processStatusFrequency - 1;
+ this.statusCount = this.processStatusFrequency - 1;
}
@Override
@@ -378,16 +375,16 @@
{
super.stopSingleton();
- this.clusteredHandler.setMasterNode(false);
+ this.clusteredHandler.setMasterNode(false);
this.resetRequestSource.setMasterNode(false);
- }
+ }
@Override
@Inject(fromContext = FromContext.NAME)
public void setServiceHAName(String haName)
{
super.setServiceHAName(haName);
- this.clusteredHandler.setHAServiceName(getServiceHAName());
+ this.clusteredHandler.setHAServiceName(this.getServiceHAName());
}
@@ -396,83 +393,105 @@
/**
* {@inheritDoc}
*
- * We override the superclass to pass our domain as a param to the
- * "_stopOldMaster" call.
+ * @return an inner class that allows us to avoid exposing RPC methods as
+ * public methods of this class
*/
@Override
- protected void makeThisNodeMaster()
+ protected HAServiceRpcHandler<HAServiceEvent> getRpcHandler()
{
- try
- {
- // stop the old master (if there is one) before starting the new one
-
- // ovidiu 09/02/04 - temporary solution for Case 1843, use an asynchronous
- // distributed call.
- this.callAsyncMethodOnPartition("stopOldMaster", new Object[]{ getDomain() }, new Class[]{ String.class });
-
- this.startNewMaster();
- }
- catch (Exception ex)
- {
- this.log.error(sm.getString("modcluster.error.stopOldMaster"), ex);
- }
+ return this.rpcHandler;
}
/**
* {@inheritDoc}
*
- * @return an inner class that allows us to avoid exposing RPC methods as
- * public methods of this class
+ * @return a {@link ModClusterServiceDRMEntry}
*/
@Override
- protected Object getRPCHandler()
+ protected Serializable getReplicant()
{
- return rpcHandler;
- }
+ return this.drmEntry;
+ }
/**
* {@inheritDoc}
- *
- * @return a {@link ModClusterServiceDRMEntry}
+ * @return a list of cluster nodes from which to elect a new master
*/
@Override
- protected Serializable getReplicant()
+ @SuppressWarnings("unchecked")
+ protected List<ClusterNode> getElectionCandidates()
{
- return drmEntry;
+ List<ModClusterServiceDRMEntry> candidates = this.getHAPartition().getDistributedReplicantManager().lookupReplicants(this.getServiceHAName());
+
+ return this.narrowCandidateList(candidates);
}
- // ----------------------------------------------------------------- Private
-
- private void stopOldMaster(String domain)
+ /**
+ * Processes the candidate list, discarding those who don't match our domain nor the best
+ * candidate when it comes to the ability to communicate with proxies.
+ *
+ * @param candidates the universe of possible candidates.
+ * @return a list of candidates with an equivalent ability to communicate
+ * with proxies, or <code>null</code> if <code>candidates</code>
+ * is <code>null</code>.
+ */
+ List<ClusterNode> narrowCandidateList(Collection<ModClusterServiceDRMEntry> candidates)
{
- if (safeEquals(domain, this.getDomain()))
+ if (candidates == null)
{
- super._stopOldMaster();
+ return null;
}
- else
+
+ List<ClusterNode> narrowed = new ArrayList<ClusterNode>(candidates.size());
+ ModClusterServiceDRMEntry champion = null;
+
+ for (ModClusterServiceDRMEntry candidate : candidates)
{
- log.debug(sm.getString("modcluster.singleton.ignorestop", domain, this.getDomain()));
+ if (!this.domainEquals(candidate.getDomain()))
+ {
+ continue;
+ }
+
+ if (champion == null)
+ {
+ champion = candidate;
+ narrowed.add(candidate.getPeer());
+ }
+ else
+ {
+ int compFactor = candidate.compareTo(champion);
+ if (compFactor < 0)
+ {
+ // New champ
+ narrowed.clear();
+ champion = candidate;
+ narrowed.add(candidate.getPeer());
+ }
+ else if (compFactor == 0)
+ {
+ // As good as our champ
+ narrowed.add(candidate.getPeer());
+ }
+ // else candidate didn't make the cut; continue
+ }
}
+
+ return narrowed;
}
- private boolean safeEquals(Object a, Object b)
- {
- return (a == b || (a != null && a.equals(b)));
- }
-
@SuppressWarnings("unchecked")
private void updateClusterStatus()
{
this.localHandler.status();
Set<MCMPServerState> masterList = null;
Map<ClusterNode, MCMPServerDiscoveryEvent> latestEvents = null;
- synchronized (proxyChangeDigest)
+ synchronized (this.proxyChangeDigest)
{
masterList = this.localHandler.getProxyStates();
- latestEvents = new HashMap<ClusterNode, MCMPServerDiscoveryEvent>(proxyChangeDigest);
+ latestEvents = new HashMap<ClusterNode, MCMPServerDiscoveryEvent>(this.proxyChangeDigest);
}
- HAPartition partition = getHAPartition();
- List<ModClusterServiceDRMEntry> replicants = partition.getDistributedReplicantManager().lookupReplicants(getServiceHAName());
+ HAPartition partition = this.getHAPartition();
+ List<ModClusterServiceDRMEntry> replicants = partition.getDistributedReplicantManager().lookupReplicants(this.getServiceHAName());
Map<ClusterNode, ModClusterServiceDRMEntry> nonresponsive = new HashMap<ClusterNode, ModClusterServiceDRMEntry>();
for (ModClusterServiceDRMEntry replicant : replicants)
{
@@ -481,15 +500,7 @@
nonresponsive.remove(partition.getClusterNode());
// FIXME -- what about our own dropped discovery events if we just became master?
- List responses = null;
- try
- {
- responses = partition.callMethodOnCluster(getServiceHAName(), "getClusterCoordinatorState", new Object[]{ masterList }, new Class[]{ Set.class }, true);
- }
- catch (Exception e)
- {
- throw Utils.convertToUnchecked(e);
- }
+ List responses = this.getClusterCoordinatorState(masterList);
// Gather up all the reset requests in one list
// FIXME -- what about our own dropped requests if we just became master?
@@ -514,7 +525,9 @@
for (MCMPServerDiscoveryEvent toCheck : mcssgrr.getUnacknowledgedEvents())
{
if (latestEvent != null && latestEvent.getEventIndex() <= toCheck.getEventIndex())
+ {
continue; // already processed it
+ }
AddressPort ap = toCheck.getMCMPServer();
if (toCheck.isAddition())
@@ -530,11 +543,13 @@
if (!resync) // don't bother if we are going to start over
{
- statuses.put(cn, new PeerMCMPDiscoveryStatus(cn, mcssgrr.getStates(), latestEvent));
+ statuses.put(cn, new PeerMCMPDiscoveryStatus(cn, this.domain, mcssgrr.getStates(), latestEvent));
List<MCMPRequest> toAdd = mcssgrr.getResetRequests();
if (toAdd != null)
+ {
resetRequests.addAll(toAdd);
+ }
ModClusterServiceDRMEntry removed = nonresponsive.remove(cn);
if (removed != null)
@@ -552,34 +567,34 @@
ThrowableGroupRpcResponse tgrr = (ThrowableGroupRpcResponse) response;
ClusterNode cn = tgrr.getSender();
- log.warn(sm.getString("modcluster.error.rpc.known", "getClusterCoordinatorState", cn), tgrr.getValue());
+ this.log.warn(this.sm.getString("modcluster.error.rpc.known", "getClusterCoordinatorState", cn), tgrr.getValue());
- // Don't remove from nonresponsive list and we'll pass back an error
+ // Don't remove from nonresponsive list and we'll pass back an error
// status (null server list) to this peer
}
else if (response instanceof Throwable)
{
- log.warn(sm.getString("modcluster.error.rpc.unknown", "getClusterCoordinatorState"), (Throwable) response);
+ this.log.warn(this.sm.getString("modcluster.error.rpc.unknown", "getClusterCoordinatorState"), (Throwable) response);
}
else
{
- log.error(sm.getString("modcluster.error.rpc.unexpected", response, "getClusterCoordinatorState"));
+ this.log.error(this.sm.getString("modcluster.error.rpc.unexpected", response, "getClusterCoordinatorState"));
}
}
if (resync)
{
// We picked up previously unknown discovery events; start over
- updateClusterStatus();
+ this.updateClusterStatus();
return;
}
- // Add error-state objects for non-responsive peers
+ // Add error-state objects for non-responsive peers
Integer lbf = new Integer(0);
for (Map.Entry<ClusterNode, ModClusterServiceDRMEntry> entry : nonresponsive.entrySet())
{
ClusterNode cn = entry.getKey();
- statuses.put(entry.getKey(), new PeerMCMPDiscoveryStatus(cn, null, latestEvents.get(cn)));
+ statuses.put(entry.getKey(), new PeerMCMPDiscoveryStatus(cn, this.domain, null, latestEvents.get(cn)));
for (String jvmRoute : entry.getValue().getJvmRoutes())
{
@@ -601,60 +616,79 @@
this.localHandler.sendRequests(statusRequests);
// Advise the members the process is done and that they should update DRM
- notifyClusterStatusComplete(masterList, statuses);
+ this.notifyClusterStatusComplete(masterList, statuses);
}
- private void notifyClusterStatusComplete(Set<MCMPServerState> masterList,
+ private void notifyClusterStatusComplete(Set<MCMPServerState> masterList,
Map<ClusterNode, PeerMCMPDiscoveryStatus> statuses)
{
- HAPartition partition = getHAPartition();
+ HAPartition partition = this.getHAPartition();
// Determine who should update DRM first -- us or the rest of the nodes
Set<ModClusterServiceDRMEntry> allStatuses = new HashSet<ModClusterServiceDRMEntry>(statuses.values());
- ModClusterServiceDRMEntry ourCurrentStatus = (ModClusterServiceDRMEntry) partition.getDistributedReplicantManager().lookupLocalReplicant(getServiceHAName());
+ ModClusterServiceDRMEntry ourCurrentStatus = (ModClusterServiceDRMEntry) partition.getDistributedReplicantManager().lookupLocalReplicant(this.getServiceHAName());
allStatuses.add(ourCurrentStatus);
- boolean othersFirst = this.electionPolicy.narrowCandidateList(allStatuses).contains(partition.getClusterNode());
- ModClusterServiceDRMEntry ourNewStatus = new ModClusterServiceDRMEntry(partition.getClusterNode(), masterList);
+ boolean othersFirst = this.narrowCandidateList(allStatuses).contains(partition.getClusterNode());
+ ModClusterServiceDRMEntry ourNewStatus = new ModClusterServiceDRMEntry(partition.getClusterNode(), this.domain, masterList);
boolean updated = (ourNewStatus.equals(ourCurrentStatus) == false);
if (othersFirst)
{
- remoteNotifyClusterStatusComplete(statuses);
+ this.clusterStatusComplete(statuses);
if (updated)
{
- updateLocalDRM(ourNewStatus);
- }
+ this.updateLocalDRM(ourNewStatus);
+ }
}
else
{
if (updated)
{
- updateLocalDRM(ourNewStatus);
+ this.updateLocalDRM(ourNewStatus);
}
- remoteNotifyClusterStatusComplete(statuses);
+ this.clusterStatusComplete(statuses);
}
}
- private void remoteNotifyClusterStatusComplete(Map<ClusterNode, PeerMCMPDiscoveryStatus> statuses)
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceRpcHandler#clusterStatusComplete(java.util.Map)
+ */
+ public void clusterStatusComplete(Map<ClusterNode, PeerMCMPDiscoveryStatus> statuses)
{
try
{
- getHAPartition().callMethodOnCluster(getServiceHAName(), "clusterStatusComplete", new Object[]{ statuses }, new Class[]{ Map.class }, true);
+ this.callMethodOnPartition("clusterStatusComplete", new Object[] { statuses }, new Class[] { Map.class });
}
catch (Exception e)
{
- log.error(sm.getString("modcluster.error.status.complete"), e);
+ this.log.error(this.sm.getString("modcluster.error.status.complete"), e);
}
}
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceRpcHandler#getClusterCoordinatorState(java.util.Set)
+ */
+ public List<?> getClusterCoordinatorState(Set<MCMPServerState> masterList)
+ {
+ try
+ {
+ return this.callMethodOnPartition("getClusterCoordinatorState", new Object[] { masterList }, new Class[] { Set.class });
+ }
+ catch (Exception e)
+ {
+ throw Utils.convertToUnchecked(e);
+ }
+ }
+
+
private void updateLocalDRM(ModClusterServiceDRMEntry ourNewStatus) throws Error
{
try
{
- getHAPartition().getDistributedReplicantManager().add(getServiceHAName(), ourNewStatus);
+ this.getHAPartition().getDistributedReplicantManager().add(this.getServiceHAName(), ourNewStatus);
}
catch (Exception e)
{
@@ -662,47 +696,77 @@
}
}
+ /**
+ * Redirect to {@link #stopOldMaster(String)}
+ * @see org.jboss.ha.framework.server.HASingletonImpl#stopOldMaster()
+ */
+ @Override
+ public void stopOldMaster()
+ {
+ this.stopOldMaster(this.domain);
+ }
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceRpcHandler#stopOldMaster(java.lang.String)
+ */
+ public void stopOldMaster(String domain)
+ {
+ try
+ {
+ this.callAsyncMethodOnPartition("stopOldMaster", new Object[] { domain }, STOP_OLD_MASTER_TYPES);
+ }
+ catch (Exception e)
+ {
+ throw Utils.convertToUnchecked(e);
+ }
+ }
+
+ boolean domainEquals(String domain)
+ {
+ return ((this.domain != null) && (domain != null)) ? this.domain.equals(domain) : (this.domain == domain);
+ }
+
// ---------------------------------------------------------- Inner classes
/**
* This is the object that gets invoked on via reflection by HAPartition.
*/
- public class RpcHandler
+ protected class RpcHandler extends HAServiceImpl<HAServiceEvent>.RpcHandler implements ModClusterServiceRpcHandler<GroupRpcResponse, MCMPServer>, ClusteredMCMPHandlerRpcHandler, ResetRequestSourceRpcHandler<GroupRpcResponse>
{
private final ModClusterService coord = ModClusterService.this;
- private final GroupRpcResponse SUCCESS =
- new GroupRpcResponse(this.coord.getHAPartition().getClusterNode());
+ private final GroupRpcResponse SUCCESS = new GroupRpcResponse(this.coord.getHAPartition().getClusterNode());
-
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceRpcHandler#stopOldMaster(java.lang.String)
+ */
public void stopOldMaster(String domain)
{
- this.coord.stopOldMaster(domain);
+ // Ignore rpc calls from other domains
+ if (this.coord.domainEquals(domain))
+ {
+ this.coord.stopIfMaster();
+ }
}
-
- public void _receiveRemoteNotification(Notification notification)
+/*
+ public GroupRpcResponse getLocalAddress() throws IOException
{
- this.coord._receiveRemoteNotification(notification);
- }
-
- public InetAddressGroupRpcResponse getLocalAddress() throws IOException
- {
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
- return new InetAddressGroupRpcResponse(this.coord.getHAPartition().getClusterNode(),
+ return new InetAddressGroupRpcResponse(this.coord.getHAPartition().getClusterNode(),
this.coord.localHandler.getLocalAddress());
}
- else
- {
- return null;
- }
+
+ return null;
}
-
+*/
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#mcmpServerDiscoveryEvent(org.jboss.web.tomcat.service.modcluster.ha.rpc.MCMPServerDiscoveryEvent)
+ */
public GroupRpcResponse mcmpServerDiscoveryEvent(MCMPServerDiscoveryEvent event)
{
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
- synchronized (proxyChangeDigest)
+ synchronized (ModClusterService.this.proxyChangeDigest)
{
AddressPort ap = event.getMCMPServer();
if (event.isAddition())
@@ -713,19 +777,20 @@
{
this.coord.localHandler.removeProxy(ap.address, ap.port);
}
- proxyChangeDigest.put(event.getSender(), event);
- return new GroupRpcResponse(getHAPartition().getClusterNode());
- }
+ ModClusterService.this.proxyChangeDigest.put(event.getSender(), event);
+ return new GroupRpcResponse(ModClusterService.this.getHAPartition().getClusterNode());
+ }
}
- else
- {
- return null;
- }
+
+ return null;
}
- public ModClusterServiceStateGroupRpcResponse getClusterCoordinatorState(Set<MCMPServer> masterList)
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceRpcHandler#getClusterCoordinatorState(java.util.Set)
+ */
+ public GroupRpcResponse getClusterCoordinatorState(Set<MCMPServer> masterList)
{
- if (this.coord.isMasterNode() == false)
+ if (this.coord.isMasterNode() == false)
{
Set<MCMPServerState> ourStates = this.coord.clusteredHandler.updateServersFromMasterNode(masterList);
@@ -736,8 +801,8 @@
resetRequests = this.coord.resetRequestSource.getLocalResetRequests();
}
- ModClusterServiceStateGroupRpcResponse response =
- new ModClusterServiceStateGroupRpcResponse(getHAPartition().getClusterNode(),
+ GroupRpcResponse response =
+ new ModClusterServiceStateGroupRpcResponse(ModClusterService.this.getHAPartition().getClusterNode(),
this.coord.latestLoad,
ourStates,
this.coord.clusteredHandler.getPendingDiscoveryEvents(),
@@ -750,14 +815,14 @@
return response;
}
- else
- {
- // TODO is this the correct response here?
- return null;
- }
-
+
+ // TODO is this the correct response here?
+ return null;
}
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ModClusterServiceRpcHandler#clusterStatusComplete(java.util.Map)
+ */
public void clusterStatusComplete(Map<ClusterNode, PeerMCMPDiscoveryStatus> statuses)
{
HAPartition partition = this.coord.getHAPartition();
@@ -773,101 +838,110 @@
DistributedReplicantManager drm = partition.getDistributedReplicantManager();
String haName = this.coord.getServiceHAName();
- ModClusterServiceDRMEntry oldStatus =
+ ModClusterServiceDRMEntry oldStatus =
(ModClusterServiceDRMEntry) drm.lookupLocalReplicant(haName);
if (newStatus.equals(oldStatus) == false)
{
try
{
- drm.add(haName, new ModClusterServiceDRMEntry(cn, newStatus.getMCMPServerStates()));
+ drm.add(haName, new ModClusterServiceDRMEntry(cn, this.coord.getDomain(), newStatus.getMCMPServerStates()));
}
catch (Exception e)
{
- this.coord.log.error(sm.getString("modcluster.error.drm"), e);
+ this.coord.log.error(ModClusterService.this.sm.getString("modcluster.error.drm"), e);
}
}
}
}
- public StringGroupRpcResponse getProxyConfiguration()
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#getProxyConfiguration()
+ */
+ public GroupRpcResponse getProxyConfiguration()
{
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
- return new StringGroupRpcResponse(getHAPartition().getClusterNode(), this.coord.localHandler.getProxyConfiguration());
+ return new StringGroupRpcResponse(ModClusterService.this.getHAPartition().getClusterNode(), this.coord.localHandler.getProxyConfiguration());
}
- else
- {
- return null;
- }
+
+ return null;
}
- public BooleanGroupRpcResponse isProxyHealthOK()
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#isProxyHealthOK()
+ */
+ public GroupRpcResponse isProxyHealthOK()
{
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
- return new BooleanGroupRpcResponse(getHAPartition().getClusterNode(), this.coord.localHandler.isProxyHealthOK());
+ return new BooleanGroupRpcResponse(ModClusterService.this.getHAPartition().getClusterNode(), this.coord.localHandler.isProxyHealthOK());
}
- else
- {
- return null;
- }
+
+ return null;
}
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#markProxiesInError()
+ */
public GroupRpcResponse markProxiesInError()
{
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
this.coord.localHandler.markProxiesInError();
- return SUCCESS;
+ return this.SUCCESS;
}
- else
- {
- return null;
- }
+
+ return null;
}
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#reset()
+ */
public GroupRpcResponse reset()
{
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
this.coord.localHandler.reset();
- return SUCCESS;
+ return this.SUCCESS;
}
- else
- {
- return null;
- }
+
+ return null;
}
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#sendRequest(org.jboss.web.tomcat.service.modcluster.mcmp.MCMPRequest)
+ */
public GroupRpcResponse sendRequest(MCMPRequest request)
{
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
this.coord.localHandler.sendRequest(request);
- return SUCCESS;
+ return this.SUCCESS;
}
- else
- {
- return null;
- }
+
+ return null;
}
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#sendRequests(java.util.List)
+ */
public GroupRpcResponse sendRequests(List<MCMPRequest> requests)
{
- if (this.coord.isMasterNode())
+ if (this.coord.isMasterNode())
{
this.coord.localHandler.sendRequests(requests);
- return SUCCESS;
+ return this.SUCCESS;
}
- else
- {
- return null;
- }
+
+ return null;
}
- public ResetRequestGroupRpcResponse getResetRequests()
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ResetRequestSourceRpcHandler#getResetRequests()
+ */
+ public GroupRpcResponse getResetRequests()
{
- return new ResetRequestGroupRpcResponse(getHAPartition().getClusterNode(),
+ return new ResetRequestGroupRpcResponse(ModClusterService.this.getHAPartition().getClusterNode(),
this.coord.resetRequestSource.getLocalResetRequests());
}
}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterServiceMBean.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterServiceMBean.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ModClusterServiceMBean.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -22,7 +22,6 @@
package org.jboss.web.tomcat.service.modcluster;
-import org.jboss.ha.jmx.HAServiceMBean;
import org.jboss.web.tomcat.service.modcluster.mcmp.MCMPRequestType;
import org.jboss.web.tomcat.service.modcluster.mcmp.MCMPServerState;
@@ -31,7 +30,7 @@
*
* @author Brian Stansberry
*/
-public interface ModClusterServiceMBean extends HAServiceMBean
+public interface ModClusterServiceMBean
{
/**
* Add a proxy to the list of those with which this handler communicates.
@@ -79,5 +78,6 @@
* @return the configuration information from all the accessible proxies.
*/
String getProxyConfiguration();
-
+
+ String getDomain();
}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ClusteredMCMPHandlerImpl.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ClusteredMCMPHandlerImpl.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ClusteredMCMPHandlerImpl.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -37,9 +37,9 @@
import org.jboss.logging.Logger;
import org.jboss.web.tomcat.service.modcluster.Constants;
import org.jboss.web.tomcat.service.modcluster.Utils;
-import org.jboss.web.tomcat.service.modcluster.advertise.AdvertiseListener;
import org.jboss.web.tomcat.service.modcluster.config.MCMPHandlerConfiguration;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.BooleanGroupRpcResponse;
+import org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.GroupRpcResponse;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.GroupRpcResponseFilter;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.MCMPServerDiscoveryEvent;
@@ -54,19 +54,20 @@
public class ClusteredMCMPHandlerImpl implements ClusteredMCMPHandler
{
- private static final Object[] NULL_ARGS = new Object[0];
- private static final Class[] NULL_TYPES = new Class[0];
- private static final Class[] MCMPREQ_TYPES = new Class[] { MCMPRequest.class };
- private static final Class[] MCMPREQS_TYPES = new Class[] { List.class };
- private static final Class[] DISC_EVENT_TYPES = new Class[] { MCMPServerDiscoveryEvent.class };
+ static final Object[] NULL_ARGS = new Object[0];
+ static final Class<?>[] NULL_TYPES = new Class[0];
+ static final Class<?>[] MCMPREQ_TYPES = new Class[] { MCMPRequest.class };
+ static final Class<?>[] MCMPREQS_TYPES = new Class[] { List.class };
+ static final Class<?>[] DISC_EVENT_TYPES = new Class[] { MCMPServerDiscoveryEvent.class };
- private static final Logger log = Logger.getLogger(ClusteredMCMPHandlerImpl.class);
+ static final Logger log = Logger.getLogger(ClusteredMCMPHandlerImpl.class);
+ final HAPartition partition;
private final MCMPHandler localHandler;
- private final HAPartition partition;
- private String haServiceName;
- private AdvertiseListener advertiseListener;
+ private final ClusteredMCMPHandlerRpcHandler rpcStub = new RpcStub();
+// private AdvertiseListener advertiseListener;
+ private volatile String haServiceName;
private volatile boolean masterNode = false;
@GuardedBy("errorState")
@@ -80,8 +81,7 @@
/**
* The string manager for this package.
*/
- private final StringManager sm =
- StringManager.getManager(Constants.Package);
+ final StringManager sm = StringManager.getManager(Constants.Package);
public ClusteredMCMPHandlerImpl(MCMPHandler localHandler, HAPartition partition, String haServiceName)
{
@@ -102,16 +102,25 @@
this.masterNode = masterNode;
}
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.ClusteredMCMPHandler#getHAServiceName()
+ */
public String getHAServiceName()
{
return this.haServiceName;
}
- public void setHAServiceName(String haServiceName)
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.ClusteredMCMPHandler#setHAServiceName(java.lang.String)
+ */
+ public void setHAServiceName(String serviceName)
{
- this.haServiceName = haServiceName;
+ this.haServiceName = serviceName;
}
-
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.ClusteredMCMPHandler#getPartitionName()
+ */
public String getPartitionName()
{
return this.partition.getPartitionName();
@@ -119,14 +128,14 @@
public synchronized List<MCMPServerDiscoveryEvent> getPendingDiscoveryEvents()
{
- return new ArrayList<MCMPServerDiscoveryEvent>(pendingDiscoveryEvents);
+ return new ArrayList<MCMPServerDiscoveryEvent>(this.pendingDiscoveryEvents);
}
public synchronized void discoveryEventsReceived(MCMPServerDiscoveryEvent lastReceived)
{
if (lastReceived != null)
{
- for (Iterator<MCMPServerDiscoveryEvent> it = pendingDiscoveryEvents.iterator(); it.hasNext();)
+ for (Iterator<MCMPServerDiscoveryEvent> it = this.pendingDiscoveryEvents.iterator(); it.hasNext();)
{
MCMPServerDiscoveryEvent event = it.next();
if (event.getEventIndex() <= lastReceived.getEventIndex())
@@ -144,16 +153,16 @@
public synchronized Set<MCMPServerState> updateServersFromMasterNode(Set<MCMPServer> masterList)
{
for (MCMPServer server : masterList)
- {
- this.localHandler.addProxy(server.getAddress(), server.getPort(), server.isEstablished());
+ {
+ this.localHandler.addProxy(server.getAddress(), server.getPort(), server.isEstablished());
}
for (MCMPServer server : this.localHandler.getProxyStates())
{
if (!masterList.contains(server))
{
- this.localHandler.removeProxy(server.getAddress(), server.getPort());
- }
+ this.localHandler.removeProxy(server.getAddress(), server.getPort());
+ }
}
this.localHandler.status();
@@ -163,33 +172,33 @@
public boolean getNeedsResetTransmission()
{
- synchronized (errorState)
- {
- return errorState.size() > 0 && (errorState.get(errorState.size() -1).booleanValue() == false);
+ synchronized (this.errorState)
+ {
+ return this.errorState.size() > 0 && (this.errorState.get(this.errorState.size() - 1).booleanValue() == false);
}
}
public void recordResetTransmission()
{
- synchronized (errorState)
+ synchronized (this.errorState)
{
- if (errorState.size() > 0)
+ if (this.errorState.size() > 0)
{
- errorState.set(0, Boolean.TRUE);
+ this.errorState.set(0, Boolean.TRUE);
}
}
}
public void recordResetSuccess()
{
- synchronized (errorState)
+ synchronized (this.errorState)
{
- if (errorState.size() > 0 || errorState.get(errorState.size() -1).booleanValue())
+ if (this.errorState.size() > 0 || this.errorState.get(this.errorState.size() - 1).booleanValue())
{
- errorState.remove(0);
+ this.errorState.remove(0);
}
}
- }
+ }
// ------------------------------------------------------------ MCMPHandler
@@ -199,9 +208,9 @@
}
public void addProxy(String address)
- {
+ {
AddressPort ap = MCMPUtils.parseAddressPort(address);
- addProxy(ap.address, ap.port);
+ this.addProxy(ap.address, ap.port);
}
public void addProxy(String host, int port)
@@ -213,31 +222,31 @@
throw new IllegalArgumentException(e);
}
- addProxy(address, port);
+ this.addProxy(address, port);
}
public synchronized void addProxy(InetAddress address, int port)
{
- if (isMasterNode())
+ if (this.isMasterNode())
{
this.localHandler.addProxy(address, port);
}
else
{
- sendDiscoveryEventToPartition(address, port, true);
- }
+ this.sendDiscoveryEventToPartition(address, port, true);
+ }
}
public void addProxy(InetAddress address, int port, boolean established)
{
- this.localHandler.addProxy(address, port, established);
+ this.localHandler.addProxy(address, port, established);
}
/**
* Remove proxy.
*/
- public synchronized void removeProxy(String host, int port)
+ public synchronized void removeProxy(String host, int port)
{
InetAddress address = null;
try {
@@ -245,22 +254,22 @@
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
- removeProxy(address, port);
- }
+ this.removeProxy(address, port);
+ }
/**
* Remove proxy.
*/
- public synchronized void removeProxy(InetAddress address, int port)
+ public synchronized void removeProxy(InetAddress address, int port)
{
- if (isMasterNode())
+ if (this.isMasterNode())
{
this.localHandler.removeProxy(address, port);
}
else
{
- sendDiscoveryEventToPartition(address, port, false);
- }
+ this.sendDiscoveryEventToPartition(address, port, false);
+ }
}
public Set<MCMPServerState> getProxyStates()
@@ -270,160 +279,125 @@
public InetAddress getLocalAddress() throws IOException
{
- return localHandler.getLocalAddress();
+ return this.localHandler.getLocalAddress();
}
public String getProxyConfiguration()
{
- if (isMasterNode())
+ if (this.isMasterNode())
{
return this.localHandler.getProxyConfiguration();
}
- else
- {
- GroupRpcResponse result = invokeNoArgGroupRpc("getProxyConfiguration");
- if (result instanceof StringGroupRpcResponse)
- {
- return ((StringGroupRpcResponse) result).getValue();
- }
- else
- {
- throw ((ThrowableGroupRpcResponse) result).getValueAsRuntimeException();
- }
- }
+
+ GroupRpcResponse response = this.rpcStub.getProxyConfiguration();
+
+ this.validateResponse(response, false);
+
+ return ((StringGroupRpcResponse) response).getValue();
}
public void init(List<AddressPort> initialProxies)
- {
- if (isMasterNode())
+ {
+ if (this.isMasterNode())
{
this.localHandler.init(initialProxies);
}
else
{
this.localHandler.init(new ArrayList<AddressPort>());
+
if (initialProxies != null)
{
for (AddressPort proxy : initialProxies)
- {
- sendDiscoveryEventToPartition(proxy.address, proxy.port, true);
+ {
+ this.sendDiscoveryEventToPartition(proxy.address, proxy.port, true);
}
}
- }
+ }
}
public boolean isProxyHealthOK()
{
- if (isMasterNode())
+ if (this.isMasterNode())
{
return this.localHandler.isProxyHealthOK();
}
- else
- {
- GroupRpcResponse result = invokeNoArgGroupRpc("isProxyHealthOK");
- if (result instanceof BooleanGroupRpcResponse)
- {
- return ((BooleanGroupRpcResponse) result).getValue();
- }
- else
- {
- throw ((ThrowableGroupRpcResponse) result).getValueAsRuntimeException();
- }
- }
+
+ GroupRpcResponse response = this.rpcStub.isProxyHealthOK();
+
+ this.validateResponse(response, false);
+
+ return ((BooleanGroupRpcResponse) response).getValue();
}
public void markProxiesInError()
{
- recordRequestFailure();
+ this.recordRequestFailure();
- if (isMasterNode())
+ if (this.isMasterNode())
{
this.localHandler.markProxiesInError();
}
else
{
- GroupRpcResponse result = invokeNoArgGroupRpc("markProxiesInError");
- if (result instanceof ThrowableGroupRpcResponse)
- {
- throw ((ThrowableGroupRpcResponse) result).getValueAsRuntimeException();
- }
+ GroupRpcResponse response = this.rpcStub.markProxiesInError();
+
+ this.validateResponse(response, false);
}
}
public void reset()
{
- if (isMasterNode())
+ if (this.isMasterNode())
{
this.localHandler.reset();
}
else
{
- GroupRpcResponse result = invokeNoArgGroupRpc("reset");
- if (result instanceof ThrowableGroupRpcResponse)
- {
- throw ((ThrowableGroupRpcResponse) result).getValueAsRuntimeException();
- }
+ GroupRpcResponse response = this.rpcStub.reset();
+
+ this.validateResponse(response, false);
}
}
- @SuppressWarnings("unchecked")
public void sendRequest(MCMPRequest request)
{
- if (isMasterNode())
+ if (this.isMasterNode())
{
this.localHandler.sendRequest(request);
}
else
{
- GroupRpcResponse response = null;
- try
- {
- List<Object> rsps = this.partition.callMethodOnCluster(this.haServiceName, "sendRequest", new Object[] { request }, MCMPREQ_TYPES, false, new GroupRpcResponseFilter());
- response = extractGroupRpcResponse(rsps, "sendRequest");
- }
- catch (Exception e)
- {
- recordRequestFailure();
- throw Utils.convertToUnchecked(e);
- }
+ GroupRpcResponse response = this.rpcStub.sendRequest(request);
- if (response instanceof ThrowableGroupRpcResponse)
- {
- recordRequestFailure();
- throw ((ThrowableGroupRpcResponse) response).getValueAsRuntimeException();
- }
+ this.validateResponse(response, true);
}
}
- @SuppressWarnings("unchecked")
public void sendRequests(List<MCMPRequest> requests)
{
- if (isMasterNode())
+ if (this.isMasterNode())
{
this.localHandler.sendRequests(requests);
}
else
{
- GroupRpcResponse response = null;
- try
- {
- List<Object> rsps = this.partition.callMethodOnCluster(this.haServiceName, "sendRequests", new Object[] { requests }, MCMPREQS_TYPES, false, new GroupRpcResponseFilter());
- response = extractGroupRpcResponse(rsps, "sendRequests");
- }
- catch (Exception e)
- {
- recordRequestFailure();
- throw Utils.convertToUnchecked(e);
- }
+ GroupRpcResponse response = this.rpcStub.sendRequests(requests);
- if (response instanceof ThrowableGroupRpcResponse)
- {
- recordRequestFailure();
- throw ((ThrowableGroupRpcResponse) response).getValueAsRuntimeException();
- }
+ this.validateResponse(response, true);
}
}
+ private void validateResponse(GroupRpcResponse response, boolean recordFailure)
+ {
+ if (response instanceof ThrowableGroupRpcResponse)
+ {
+ if (recordFailure) this.recordRequestFailure();
+
+ throw ((ThrowableGroupRpcResponse) response).getValueAsRuntimeException();
+ }
+ }
+
public void shutdown()
{
this.localHandler.shutdown();
@@ -431,95 +405,157 @@
public void status()
{
- log.warn(sm.getString("modcluster.error.status.unsupported"));
+ log.warn(this.sm.getString("modcluster.error.status.unsupported"));
}
// ---------------------------------------------------------------- Private
- @SuppressWarnings("unchecked")
- private GroupRpcResponse invokeNoArgGroupRpc(String methodName)
+ private synchronized void sendDiscoveryEventToPartition(InetAddress address, int port, boolean addition)
{
- try
+ AddressPort ap = new AddressPort(address, port);
+ MCMPServerDiscoveryEvent event = new MCMPServerDiscoveryEvent(this.partition.getClusterNode(), ap, addition, this.discoveryEventIndex.incrementAndGet());
+ this.pendingDiscoveryEvents.add(event);
+
+ GroupRpcResponse response = this.rpcStub.mcmpServerDiscoveryEvent(event);
+
+ if (response instanceof ThrowableGroupRpcResponse)
{
- List<Object> rsps = this.partition.callMethodOnCluster(this.haServiceName, methodName, NULL_ARGS, NULL_TYPES, false, new GroupRpcResponseFilter());
- return extractGroupRpcResponse(rsps, methodName);
+ // Just log it; we'll retry later
+ String msg = addition ? "modcluster.error.discovery.add"
+ : "modcluster.error.discovery.remove";
+ log.error(this.sm.getString(msg, address.toString(), new Integer(port)), ((ThrowableGroupRpcResponse) response).getValue());
}
- catch (Exception e)
+ }
+
+ void recordRequestFailure()
+ {
+ synchronized (this.errorState)
{
- throw Utils.convertToUnchecked(e);
+ if (this.errorState.size() == 0 || this.errorState.get(this.errorState.size() -1).booleanValue())
+ {
+ this.errorState.add(Boolean.FALSE);
+ }
}
}
- private GroupRpcResponse extractGroupRpcResponse(List<Object> responses, String methodName)
+ class RpcStub implements ClusteredMCMPHandlerRpcHandler
{
- Throwable thrown = null;
- for (Object obj : responses)
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#getProxyConfiguration()
+ */
+ public GroupRpcResponse getProxyConfiguration()
{
- if (obj instanceof GroupRpcResponse)
+ return this.invokeRpc("getProxyConfiguration");
+ }
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#isProxyHealthOK()
+ */
+ public GroupRpcResponse isProxyHealthOK()
+ {
+ return this.invokeRpc("isProxyHealthOk");
+ }
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#markProxiesInError()
+ */
+ public GroupRpcResponse markProxiesInError()
+ {
+ return this.invokeRpc("markProxiesInError");
+ }
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#mcmpServerDiscoveryEvent(org.jboss.web.tomcat.service.modcluster.ha.rpc.MCMPServerDiscoveryEvent)
+ */
+ public GroupRpcResponse mcmpServerDiscoveryEvent(MCMPServerDiscoveryEvent event)
+ {
+ try
{
- return (GroupRpcResponse) obj;
+ return this.invokeRpc("mcmpServerDiscoveryEvent", new Object[] { event }, DISC_EVENT_TYPES);
}
- else if (obj instanceof Throwable)
+ catch (Exception e)
{
- if (thrown == null)
- {
- thrown = (Throwable) obj;
- }
+ return new ThrowableGroupRpcResponse(null, e);
}
- else
- {
- log.warn(sm.getString("modcluster.error.rpc.unexpected", obj, methodName));
- }
}
-
- if (thrown != null)
- throw Utils.convertToUnchecked(thrown);
-
- throw new IllegalStateException(sm.getString("modcluster.error.rpc.noresp", methodName));
- }
-
- @SuppressWarnings("unchecked")
- private synchronized void sendDiscoveryEventToPartition(InetAddress address, int port, boolean addition)
- {
- AddressPort ap = new AddressPort(address, port);
- MCMPServerDiscoveryEvent event = new MCMPServerDiscoveryEvent(this.partition.getClusterNode(), ap, addition, discoveryEventIndex.incrementAndGet());
- pendingDiscoveryEvents.add(event);
-
- GroupRpcResponse response = null;
- Throwable throwable = null;;
- try
- {
- List<Object> rsps = this.partition.callMethodOnCluster(this.haServiceName, "mcmpServerDiscoveryEvent", new Object[] { event }, DISC_EVENT_TYPES, false, new GroupRpcResponseFilter());
- response = extractGroupRpcResponse(rsps, "mcmpServerDiscoveryEvent");
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#reset()
+ */
+ public GroupRpcResponse reset()
+ {
+ return this.invokeRpc("reset");
}
- catch (Exception e)
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#sendRequest(org.jboss.web.tomcat.service.modcluster.mcmp.MCMPRequest)
+ */
+ public GroupRpcResponse sendRequest(MCMPRequest request)
{
- throwable = e;
+ return this.invokeRpc("sendRequest", new Object[] { request }, MCMPREQ_TYPES, true);
}
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ClusteredMCMPHandlerRpcHandler#sendRequests(java.util.List)
+ */
+ public GroupRpcResponse sendRequests(List<MCMPRequest> requests)
+ {
+ return this.invokeRpc("sendRequests", new Object[] { requests }, MCMPREQS_TYPES, true);
+ }
- if (response instanceof ThrowableGroupRpcResponse)
+ private GroupRpcResponse invokeRpc(String methodName)
{
- throwable = ((ThrowableGroupRpcResponse) response).getValue();
+ return this.invokeRpc(methodName, NULL_ARGS, NULL_TYPES, false);
}
- if (throwable != null)
+ private GroupRpcResponse invokeRpc(String methodName, Object[] args, Class<?>[] types, boolean recordFailure)
{
- // Just log it; we'll retry later
- String msg = addition ? "modcluster.error.discovery.add"
- : "modcluster.error.discovery.remove";
- log.error(sm.getString(msg, address.toString(), port), throwable);
+ try
+ {
+ return this.invokeRpc(methodName, args, types);
+ }
+ catch (Exception e)
+ {
+ if (recordFailure)
+ {
+ ClusteredMCMPHandlerImpl.this.recordRequestFailure();
+ }
+
+ throw Utils.convertToUnchecked(e);
+ }
+ }
+
+ private GroupRpcResponse invokeRpc(String methodName, Object[] args, Class<?>[] types) throws Exception
+ {
+ List<?> responses = ClusteredMCMPHandlerImpl.this.partition.callMethodOnCluster(ClusteredMCMPHandlerImpl.this.getHAServiceName(), methodName, args, types, false, new GroupRpcResponseFilter());
- }
- }
-
- private void recordRequestFailure()
- {
- synchronized (errorState)
- {
- if (errorState.size() == 0 || errorState.get(errorState.size() -1).booleanValue())
+ Throwable thrown = null;
+
+ for (Object obj : responses)
{
- errorState.add(Boolean.FALSE);
+ if (obj instanceof GroupRpcResponse)
+ {
+ return (GroupRpcResponse) obj;
+ }
+ else if (obj instanceof Throwable)
+ {
+ if (thrown == null)
+ {
+ thrown = (Throwable) obj;
+ }
+ }
+ else
+ {
+ log.warn(ClusteredMCMPHandlerImpl.this.sm.getString("modcluster.error.rpc.unexpected", obj, methodName));
+ }
}
+
+ if (thrown != null)
+ {
+ throw Utils.convertToUnchecked(thrown);
+ }
+
+ throw new IllegalStateException(ClusteredMCMPHandlerImpl.this.sm.getString("modcluster.error.rpc.noresp", methodName));
}
}
}
\ No newline at end of file
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/HASingletonAwareResetRequestSource.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/HASingletonAwareResetRequestSource.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/HASingletonAwareResetRequestSource.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -35,20 +35,25 @@
import org.jboss.web.tomcat.service.modcluster.config.BalancerConfiguration;
import org.jboss.web.tomcat.service.modcluster.config.NodeConfiguration;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.ResetRequestGroupRpcResponse;
+import org.jboss.web.tomcat.service.modcluster.ha.rpc.ResetRequestSourceRpcHandler;
import org.jboss.web.tomcat.service.modcluster.ha.rpc.ThrowableGroupRpcResponse;
import org.jboss.web.tomcat.service.modcluster.mcmp.MCMPRequest;
import org.jboss.web.tomcat.service.modcluster.mcmp.MCMPUtils;
import org.jboss.web.tomcat.service.modcluster.mcmp.ResetRequestSource;
/**
- * {@link ResetRequestSource} that provides different reset requests
- * depending on whether or not it believes it is running on the singleton
+ * {@link ResetRequestSource} that provides different reset requests
+ * depending on whether or not it believes it is running on the singleton
* master.
*
* @author Brian Stansberry
*/
public class HASingletonAwareResetRequestSource implements ResetRequestSource
{
+ static final String METHOD_NAME = "getResetRequests";
+ static final Object[] ARGS = new Object[0];
+ static final Class<?>[] TYPES = new Class[0];
+
private static final Logger log = Logger.getLogger(HASingletonAwareResetRequestSource.class);
/**
@@ -58,8 +63,7 @@
private final NodeConfiguration nodeConfig;
private final BalancerConfiguration balancerConfig;
- private final HAPartition partition;
- private final String haServiceName;
+ private final ResetRequestSourceRpcHandler<List<?>> rpcStub;
private volatile boolean master;
private volatile Server jbossWebServer;
@@ -67,23 +71,19 @@
{
this.nodeConfig = nodeConfig;
this.balancerConfig = balancerConfig;
- this.partition = partition;
- this.haServiceName = haServiceName;
+ this.rpcStub = new RpcStub(partition, haServiceName);
}
- @SuppressWarnings("unchecked")
- public List<MCMPRequest> getResetRequests()
+ public List<MCMPRequest> getResetRequests()
{
if (this.master)
{
- List<MCMPRequest> resets = getLocalResetRequests();
- addRemoteRequests(resets);
+ List<MCMPRequest> resets = this.getLocalResetRequests();
+ this.addRemoteRequests(resets);
return resets;
}
- else
- {
- return Collections.EMPTY_LIST;
- }
+
+ return Collections.emptyList();
}
public List<MCMPRequest> getLocalResetRequests()
@@ -113,16 +113,7 @@
private void addRemoteRequests(List<MCMPRequest> resets)
{
- List responses = null;
- try
- {
- responses = this.partition.callMethodOnCluster(this.haServiceName, "getResetRequests", new Object[]{}, new Class[]{}, true);
- }
- catch (Exception e)
- {
- //FIXME what to do?
- throw Utils.convertToUnchecked(e);
- }
+ List<?> responses = this.rpcStub.getResetRequests();
for (Object response : responses)
{
@@ -134,19 +125,45 @@
{
ThrowableGroupRpcResponse tgrr = (ThrowableGroupRpcResponse) response;
//FIXME what to do?
- log.warn(sm.getString("modcluster.error.rpc.known", "getResetRequests", tgrr.getSender()), tgrr.getValue());
+ log.warn(this.sm.getString("modcluster.error.rpc.known", METHOD_NAME, tgrr.getSender()), tgrr.getValue());
}
else if (response instanceof Throwable)
{
- log.warn(sm.getString("modcluster.error.rpc.unknown", "getResetRequests"), (Throwable) response);
+ log.warn(this.sm.getString("modcluster.error.rpc.unknown", METHOD_NAME), (Throwable) response);
}
else
{
- log.error(sm.getString("modcluster.error.rpc.unexpected", response, "getResetRequests"));
+ log.error(this.sm.getString("modcluster.error.rpc.unexpected", response, METHOD_NAME));
}
}
+ }
+
+ private class RpcStub implements ResetRequestSourceRpcHandler<List<?>>
+ {
+ private final HAPartition partition;
+ private final String haServiceName;
+ public RpcStub(HAPartition partition, String haServiceName)
+ {
+ this.partition = partition;
+ this.haServiceName = haServiceName;
+ }
+
+ /**
+ * @see org.jboss.web.tomcat.service.modcluster.ha.rpc.ResetRequestSourceRpcHandler#getResetRequests()
+ */
+ public List<?> getResetRequests()
+ {
+ try
+ {
+ return this.partition.callMethodOnCluster(this.haServiceName, METHOD_NAME, ARGS, TYPES, true);
+ }
+ catch (Exception e)
+ {
+ //FIXME what to do?
+ throw Utils.convertToUnchecked(e);
+ }
+ }
}
-
}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceDRMEntry.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceDRMEntry.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceDRMEntry.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -41,6 +41,7 @@
private static final long serialVersionUID = 8275232749243297786L;
private final ClusterNode peer;
+ private final String domain;
private final Set<MCMPServerState> mcmpServerStates;
private final Integer healthyEstablishedCount;
private final Integer establishedCount;
@@ -48,11 +49,12 @@
private final Integer knownCount;
private final Set<String> jvmRoutes = new HashSet<String>();
- public ModClusterServiceDRMEntry(ClusterNode peer, Set<MCMPServerState> mcmpServerStates)
+ public ModClusterServiceDRMEntry(ClusterNode peer, String domain, Set<MCMPServerState> mcmpServerStates)
{
assert peer != null : "peer is null";
this.peer = peer;
+ this.domain = domain;
this.mcmpServerStates = mcmpServerStates;
int healthyEstablished = 0;
@@ -92,6 +94,11 @@
return this.peer;
}
+ public String getDomain()
+ {
+ return this.domain;
+ }
+
public Set<MCMPServerState> getMCMPServerStates()
{
return this.mcmpServerStates;
@@ -99,26 +106,26 @@
public Set<String> getJvmRoutes()
{
- synchronized (jvmRoutes)
+ synchronized (this.jvmRoutes)
{
- return new HashSet<String>(jvmRoutes);
+ return new HashSet<String>(this.jvmRoutes);
}
}
public void addJvmRoute(String jvmRoute)
{
- synchronized (jvmRoutes)
+ synchronized (this.jvmRoutes)
{
- jvmRoutes.add(jvmRoute);
- }
+ this.jvmRoutes.add(jvmRoute);
+ }
}
public void removeJvmRoute(String jvmRoute)
{
- synchronized (jvmRoutes)
+ synchronized (this.jvmRoutes)
{
- jvmRoutes.remove(jvmRoute);
- }
+ this.jvmRoutes.remove(jvmRoute);
+ }
}
public int compareTo(ModClusterServiceDRMEntry other)
@@ -144,14 +151,17 @@
public boolean equals(Object obj)
{
if (this == obj)
+ {
return true;
+ }
if (obj instanceof ModClusterServiceDRMEntry)
{
ModClusterServiceDRMEntry other = (ModClusterServiceDRMEntry) obj;
- return (this.peer.equals(other.peer)
- && safeEquals(this.mcmpServerStates, other.mcmpServerStates)
- && safeEquals(this.jvmRoutes, other.jvmRoutes));
+ return (this.peer.equals(other.peer)
+ && this.safeEquals(this.domain, other.domain)
+ && this.safeEquals(this.mcmpServerStates, other.mcmpServerStates)
+ && this.safeEquals(this.jvmRoutes, other.jvmRoutes));
}
return false;
}
@@ -160,6 +170,7 @@
public int hashCode()
{
int result = 17;
+ result += 23 * (this.domain == null ? 0 : this.domain.hashCode());
result += 23 * this.peer.hashCode();
result += 23 * (this.mcmpServerStates == null ? 0 : this.mcmpServerStates.hashCode());
result += 23 * (this.jvmRoutes == null ? 0 : this.jvmRoutes.hashCode());
@@ -169,8 +180,8 @@
@Override
public String toString()
{
- return new StringBuilder(getClass().getName())
- .append("{peer=").append(peer).append("}").toString();
+ return new StringBuilder(this.getClass().getName())
+ .append("{peer=").append(this.peer).append(",domain=").append(this.domain).append("}").toString();
}
private boolean safeEquals(Object a, Object b)
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceHASingletonElectionPolicy.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceHASingletonElectionPolicy.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/ModClusterServiceHASingletonElectionPolicy.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -1,116 +0,0 @@
-/*
- * 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.web.tomcat.service.modcluster.ha;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.singleton.HASingletonElectionPolicy;
-import org.jboss.ha.singleton.HASingletonElectionPolicyBase;
-import org.jboss.ha.singleton.HASingletonElector;
-
-/**
- * {@link HASingletonElectionPolicy} that factors the ability to communicate
- * with proxy servers in its election decision.
- *
- * @author Brian Stansberry
- */
-public class ModClusterServiceHASingletonElectionPolicy extends HASingletonElectionPolicyBase
-{
- private final HASingletonElector delegate;
-
-
- public ModClusterServiceHASingletonElectionPolicy(HASingletonElector delegate)
- {
- this.delegate = delegate;
- }
-
- @Override
- protected ClusterNode elect(List<ClusterNode> candidates)
- {
- if (candidates == null)
- return null;
-
- if (candidates.size() == 1)
- return candidates.get(0);
-
- return delegate.elect(candidates);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- protected List<ClusterNode> getCandidates()
- {
- List<ModClusterServiceDRMEntry> candidates = getHAPartition().getDistributedReplicantManager().lookupReplicants(getSingletonName());
- return narrowCandidateList(candidates);
- }
-
- /**
- * Processes the candidate list, discarding those who don't match the best
- * candidate when it comes to the ability to communicate with proxies.
- *
- * @param candidates the universe of possible candidates.
- * @return a list of candidates with an equivalent ability to communicate
- * with proxies, or <code>null</code> if <code>candidates</code>
- * is <code>null</code>.
- */
- public List<ClusterNode> narrowCandidateList(Collection<ModClusterServiceDRMEntry> candidates)
- {
- if (candidates == null)
- return null;
-
- List<ClusterNode> narrowed = new ArrayList<ClusterNode>();
- ModClusterServiceDRMEntry champion = null;
-
- for (ModClusterServiceDRMEntry candidate : candidates)
- {
- if (champion == null)
- {
- champion = candidate;
- narrowed.add(candidate.getPeer());
- }
- else
- {
- int compFactor = candidate.compareTo(champion);
- if (compFactor < 0)
- {
- // New champ
- narrowed.clear();
- champion = candidate;
- narrowed.add(candidate.getPeer());
- }
- else if (compFactor == 0)
- {
- // As good as our champ
- narrowed.add(candidate.getPeer());
- }
- // else candidate didn't make the cut; continue
- }
- }
-
- return narrowed;
- }
-
-}
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ClusteredMCMPHandlerRpcHandler.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ClusteredMCMPHandlerRpcHandler.java (rev 0)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ClusteredMCMPHandlerRpcHandler.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -0,0 +1,47 @@
+/*
+ * 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.web.tomcat.service.modcluster.ha.rpc;
+
+import java.util.List;
+
+import org.jboss.web.tomcat.service.modcluster.mcmp.MCMPRequest;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public interface ClusteredMCMPHandlerRpcHandler
+{
+ GroupRpcResponse sendRequest(MCMPRequest request);
+
+ GroupRpcResponse sendRequests(List<MCMPRequest> requests);
+
+ GroupRpcResponse mcmpServerDiscoveryEvent(MCMPServerDiscoveryEvent event);
+
+ GroupRpcResponse getProxyConfiguration();
+
+ GroupRpcResponse isProxyHealthOK();
+
+ GroupRpcResponse markProxiesInError();
+
+ GroupRpcResponse reset();
+}
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ModClusterServiceRpcHandler.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ModClusterServiceRpcHandler.java (rev 0)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ModClusterServiceRpcHandler.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -0,0 +1,43 @@
+/*
+ * 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.web.tomcat.service.modcluster.ha.rpc;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.ha.framework.interfaces.ClusterNode;
+import org.jboss.ha.framework.server.HAServiceEvent;
+import org.jboss.ha.framework.server.HAServiceRpcHandler;
+import org.jboss.web.tomcat.service.modcluster.mcmp.MCMPServer;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public interface ModClusterServiceRpcHandler<T, S extends MCMPServer> extends HAServiceRpcHandler<HAServiceEvent>
+{
+ void stopOldMaster(String domain);
+
+ void clusterStatusComplete(Map<ClusterNode, PeerMCMPDiscoveryStatus> statuses);
+
+ T getClusterCoordinatorState(Set<S> masterList);
+}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/PeerMCMPDiscoveryStatus.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/PeerMCMPDiscoveryStatus.java 2008-08-05 16:13:35 UTC (rev 76669)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/PeerMCMPDiscoveryStatus.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -51,10 +51,10 @@
* not be obtained for the peer.
* @param latestDiscoveryEvent most recent discovery event received from the peer
*/
- public PeerMCMPDiscoveryStatus(ClusterNode peer, Set<MCMPServerState> mcmpServerStates,
+ public PeerMCMPDiscoveryStatus(ClusterNode peer, String domain, Set<MCMPServerState> mcmpServerStates,
MCMPServerDiscoveryEvent latestDiscoveryEvent)
{
- super(peer, mcmpServerStates);
+ super(peer, domain, mcmpServerStates);
this.latestDiscoveryEvent = latestDiscoveryEvent;
}
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ResetRequestSourceRpcHandler.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ResetRequestSourceRpcHandler.java (rev 0)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/ha/rpc/ResetRequestSourceRpcHandler.java 2008-08-05 16:17:01 UTC (rev 76670)
@@ -0,0 +1,32 @@
+/*
+ * 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.web.tomcat.service.modcluster.ha.rpc;
+
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public interface ResetRequestSourceRpcHandler<T>
+{
+ T getResetRequests();
+}
More information about the jboss-cvs-commits
mailing list