jules 2004/01/02 17:42:56
Modified: modules/clustering/src/java/org/apache/geronimo/clustering/web
WebTier.java HttpSessionManager.java
modules/clustering/src/java/org/apache/geronimo/clustering/ejb
EJBTier.java
modules/clustering/src/java/org/apache/geronimo/clustering
LocalCluster.java Cluster.java
modules/clustering/src/deploy clustering-service.xml
modules/clustering build.sh
Added: modules/clustering/src/java/org/apache/geronimo/clustering
Tier.java Node.java
Removed: modules/clustering/src/java/org/apache/geronimo/clustering
LocalChannel.java AbstractTier.java
AbstractCluster.java
Log:
a bit of a reorg
Channel became Cluster
Cluster became Node
got rid of Abstract*
still undecided on whether Cluster should be created dynamically or via
service.xml...
Revision Changes Path
1.2 +4 -5
incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/web/WebTier.java
Index: WebTier.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/web/WebTier.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- WebTier.java 2 Jan 2004 17:52:30 -0000 1.1
+++ WebTier.java 3 Jan 2004 01:42:56 -0000 1.2
@@ -63,8 +63,7 @@
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.clustering.AbstractTier;
-import org.apache.geronimo.clustering.Cluster;
+import org.apache.geronimo.clustering.Tier;
import org.apache.geronimo.clustering.Data;
import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
@@ -79,7 +78,7 @@
*/
public class
WebTier
- extends AbstractTier
+ extends Tier
implements GeronimoMBeanTarget
{
protected Log _log=LogFactory.getLog(WebTier.class);
@@ -120,7 +119,7 @@
public static GeronimoMBeanInfo
getGeronimoMBeanInfo()
{
- GeronimoMBeanInfo mbeanInfo=AbstractTier.getGeronimoMBeanInfo();
+ GeronimoMBeanInfo mbeanInfo=Tier.getGeronimoMBeanInfo();
mbeanInfo.setTargetClass(WebTier.class);
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("WebAppCount",
true, false, "Number of WebApps deployed in this Tier"));
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("HttpSessionCount",
true, false, "Number of HttpSessions stored in this Tier"));
1.3 +5 -4
incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/web/HttpSessionManager.java
Index: HttpSessionManager.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/web/HttpSessionManager.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- HttpSessionManager.java 2 Jan 2004 17:52:30 -0000 1.2
+++ HttpSessionManager.java 3 Jan 2004 01:42:56 -0000 1.3
@@ -62,8 +62,9 @@
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.clustering.Cluster;
+import org.apache.geronimo.clustering.LocalCluster;
import org.apache.geronimo.clustering.Data;
+import org.apache.geronimo.clustering.Tier;
import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
@@ -126,13 +127,13 @@
try
{
- _tier=new
ObjectName("geronimo.clustering:role=Tier,name=web,cluster="+getClusterName()+",node="+getNodeName());
// TODO - should be a static in AbstractTier
+ _tier=Tier.makeObjectName(getClusterName(), getNodeName(), "web");
_server.invoke(_tier, "registerData", new
Object[]{getUID(),_sessions}, new
String[]{String.class.getName(),Object.class.getName()});
_log.info("sessions registered: "+getUID());
}
catch (Exception e)
{
- _log.error("could not retrieve Cluster state", e);
+ _log.error("could not retrieve Tier state", e);
}
// test stuff
1.2 +4 -5
incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/ejb/EJBTier.java
Index: EJBTier.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/ejb/EJBTier.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- EJBTier.java 2 Jan 2004 17:52:30 -0000 1.1
+++ EJBTier.java 3 Jan 2004 01:42:56 -0000 1.2
@@ -63,8 +63,7 @@
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.clustering.AbstractTier;
-import org.apache.geronimo.clustering.Cluster;
+import org.apache.geronimo.clustering.Tier;
import org.apache.geronimo.clustering.Data;
import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
@@ -79,7 +78,7 @@
*/
public class
EJBTier
- extends AbstractTier
+ extends Tier
implements GeronimoMBeanTarget
{
protected Log _log=LogFactory.getLog(EJBTier.class);
@@ -120,7 +119,7 @@
public static GeronimoMBeanInfo
getGeronimoMBeanInfo()
{
- GeronimoMBeanInfo mbeanInfo=AbstractTier.getGeronimoMBeanInfo();
+ GeronimoMBeanInfo mbeanInfo=Tier.getGeronimoMBeanInfo();
mbeanInfo.setTargetClass(EJBTier.class);
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("AppCount", true,
false, "Number of Apps deployed in this Tier"));
mbeanInfo.addAttributeInfo(new
GeronimoAttributeInfo("StatefulSessionCount", true, false, "Number of Stateful
Sessions stored in this Tier"));
1.10 +128 -73
incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/LocalCluster.java
Index: LocalCluster.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/LocalCluster.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- LocalCluster.java 2 Jan 2004 19:46:30 -0000 1.9
+++ LocalCluster.java 3 Jan 2004 01:42:56 -0000 1.10
@@ -55,128 +55,183 @@
*/
package org.apache.geronimo.clustering;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
+import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
+import org.apache.geronimo.kernel.service.GeronimoMBeanTarget;
/**
- * An initial Cluster impl, which only clusters within a single
- * VM. Thus development on Clustering can start before an inter-vm
- * transport layer has been put in place...
+ * A uniquely identifiable n->n intra-vm event-raising communications
+ * channel. A number of nodes which are part of the same cluster and
+ * reside in the same VM should share a single Cluster object.
*
* @version $Revision$ $Date$
*/
public class
LocalCluster
- extends AbstractCluster
- implements MetaDataListener, DataListener, DataDeltaListener
+ extends Cluster
{
- protected Log _log=LogFactory.getLog(LocalCluster.class);
- protected LocalChannel _channel;
-
- //----------------------------------------
- // LocalCluster
- //----------------------------------------
+ // class
+ protected static Log _log=LogFactory.getLog(LocalCluster.class);
+ protected static Map _map=new HashMap();
/**
- * Returns a List of current Cluster members.
+ * Return either an existing Cluster, or a freshly created one.
+ *
+ * @param name a <code>String</code> value
+ * @return a <code>LocalCluster</code> value
*/
- public List getMembers(){return _channel.getMembers();}
+ public static LocalCluster
+ find(String name)
+ {
+ synchronized (_map)
+ {
+ LocalCluster cluster=(LocalCluster)_map.get(name);
- //----------------------------------------
- // MetaDataListener
- //----------------------------------------
+ if (cluster==null)
+ {
+ cluster=new LocalCluster(name);
+ _map.put(name, cluster);
+
+ _log.trace("created cluster: "+name);
+ }
+ else
+ {
+ _log.trace("found cluster: "+name);
+ }
- public void
- setMetaData(List members)
- {
- _log.info("membership changed: "+members);
+ return cluster;
+ }
}
- //----------------------------------------
- // DataListener
- //----------------------------------------
+ // instance
+ protected String _name;
+ protected List _members=new Vector();
- protected Data _data;
- public Data getData() {return _data;}
+ /**
+ * Creates a new <code>LocalCluster</code> instance.
+ *
+ * @param name a <code>String</code> value
+ */
+ protected LocalCluster(String name) {_name=name;}
- public void
- setData(Data data)
- {
- String xtra="we must be the first node up";
+ public List getMembers(){synchronized (_members){return
Collections.unmodifiableList(_members);}}
- if (data!=null)
- {
- xtra="we are joining an extant cluster";
- _data=data;
- }
- else
- {
- _data=new Data();
- }
+ // MetaData
- _log.debug("initialising data - "+xtra);
+ /**
+ * Notify interested Cluster members of a change in membership,
+ * including the node which generated it.
+ *
+ * @param members a <code>List</code> value
+ */
+ protected void
+ notifyMembershipChanged(List members)
+ {
+ for (Iterator i=members.iterator(); i.hasNext();)
+ try
+ {
+ Object member=i.next();
+ if (member instanceof MetaDataListener)
+ ((MetaDataListener)member).setMetaData(members);
+ }
+ catch (Exception e)
+ {
+ _log.warn("problem notifying membership changed", e);
+ }
}
- //----------------------------------------
- // DataDeltaListener
- //----------------------------------------
-
public void
- applyDataDelta(DataDelta delta)
+ join(Object member)
{
- _log.trace("applying data delta - "+delta);
+ // first one in could turn on the lights...
+ synchronized (_members)
+ {
+ _members.add(member);
+ notifyMembershipChanged(_members);
+ }
}
- //----------------------------------------
- // GeronimoMBeanTarget
- //----------------------------------------
-
public void
- doStart()
+ leave(Object member)
{
- _log=LogFactory.getLog(getClass().getName()+"#"+getName()+"/"+getNode());
- _log.info("starting");
- _channel=LocalChannel.find(getName());
- synchronized (_channel)
+ synchronized (_members)
{
- Data data=_channel.getData();
- _log.info("state transfer - sending: "+data);
- setData(data);
- _channel.join(this);
+ _members.remove(member);
+ notifyMembershipChanged(_members);
}
- super.doStart();
+ // last one out could turn off the lights...
}
- public void
- doStop()
+ // Data
+
+ /**
+ * Get the Cluster's Data - uses an election policy (currently
+ * hardwired) to decide which node to get it from.
+ *
+ * @return a <code>Data</code> value - The data
+ */
+ public synchronized Data
+ getData()
{
- super.doStop();
+ // TODO - we need a pluggable election policy to decide who will
+ // be asked for state...
- _log.info("stopping");
- _channel.leave(this);
+ synchronized (_members)
+ {
+ if (_members.isEmpty())
+ return null;
+ else
+ {
+ for (Iterator i=_members.iterator(); i.hasNext();)
+ {
+ Object member=i.next();
+ // TODO - we need to do a deep copy of the state here -
+ // serialise and deserialise...
+ if (member instanceof DataListener)
+ return ((DataListener)member).getData();
+ }
+ return null;
+ }
+ }
}
+ /**
+ * Apply the given delta to all interested members of the cluster,
+ * excluding the member which generated it.
+ *
+ * @param l a <code>DataDeltaListener</code> value - The node that
generated the delta
+ * @param delta a <code>DataDelta</code> value - The delta
+ */
public void
- doFail()
+ notifyDataDelta(DataDeltaListener l, DataDelta delta)
{
- super.doFail();
-
- _log.info("failing");
- _channel.leave(this); // TODO - ??
+ synchronized (_members)
+ {
+ for (Iterator i=_members.iterator(); i.hasNext();)
+ {
+ Object member=i.next();
+ if (member != l && member instanceof DataDeltaListener)
+ ((DataDeltaListener)member).applyDataDelta(delta);
+ }
+ }
}
public static GeronimoMBeanInfo
getGeronimoMBeanInfo()
{
- GeronimoMBeanInfo mbeanInfo=AbstractCluster.getGeronimoMBeanInfo();
+ GeronimoMBeanInfo mbeanInfo=Cluster.getGeronimoMBeanInfo();
mbeanInfo.setTargetClass(LocalCluster.class);
- mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("Members", true,
false, "List of cluster members"));
- mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("Data", true,
false, "cluster state"));
return mbeanInfo;
}
}
1.5 +60 -4
incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/Cluster.java
Index: Cluster.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/Cluster.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Cluster.java 31 Dec 2003 14:51:44 -0000 1.4
+++ Cluster.java 3 Jan 2004 01:42:56 -0000 1.5
@@ -55,7 +55,12 @@
*/
package org.apache.geronimo.clustering;
-import org.apache.geronimo.core.service.ManagedComponent;
+import java.util.List;
+import javax.management.ObjectName;
+import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
+import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
+import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
+import org.apache.geronimo.kernel.service.GeronimoMBeanTarget;
/**
* A 'Cluster' is the in-vm representative of a Cluster of Geronimo
@@ -67,6 +72,57 @@
*
* @version $Revision$ $Date$
*/
-public interface Cluster {
- public String getName();
+public abstract class
+ Cluster
+ implements GeronimoMBeanTarget
+{
+ public static ObjectName
+ makeObjectName(String clusterName)
+ throws Exception
+ {
+ return new
ObjectName("geronimo.clustering:role=Cluster,name="+clusterName);
+ }
+
+ /**
+ * Return current Cluster members.
+ *
+ * @return a <code>List</code> value
+ */
+ public abstract List getMembers();
+
+ public abstract Data getData();
+
+ /**
+ * Add the given node to this Cluster.
+ *
+ * @param member an <code>Object</code> value
+ */
+ public abstract void join(Object member);
+
+
+ /**
+ * Remove the given node from this Cluster.
+ *
+ * @param member an <code>Object</code> value
+ */
+ public abstract void leave(Object member);
+
+ //----------------------------------------
+ // GeronimoMBeanTarget
+ //----------------------------------------
+
+ public boolean canStart(){return true;}
+ public boolean canStop(){return true;}
+ public void doStart(){}
+ public void doStop(){}
+ public void doFail(){}
+ public void setMBeanContext(GeronimoMBeanContext context){}
+
+ public static GeronimoMBeanInfo
+ getGeronimoMBeanInfo()
+ {
+ GeronimoMBeanInfo mbeanInfo=new GeronimoMBeanInfo();
+ // set target class in concrete subclasses...
+ return mbeanInfo;
+ }
}
1.1
incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/Tier.java
Index: Tier.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.clustering;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanTarget;
import org.apache.geronimo.kernel.service.GeronimoOperationInfo;
import org.apache.geronimo.kernel.service.GeronimoParameterInfo;
/**
* Tier abstracts code common to different Tier impls
* into the same abstract base.
*
*
* @version $Revision: 1.1 $ $Date: 2004/01/03 01:42:56 $
*/
public abstract class
Tier
implements GeronimoMBeanTarget
{
protected static Log _log=LogFactory.getLog(Tier.class);
protected ObjectName _objectName;
protected ObjectName _node;
protected MBeanServer _server;
protected Data _data;
protected Map _tiers;
protected Object _tier;
//----------------------------------------
// Tier
//----------------------------------------
public String getClusterName() {return
_objectName.getKeyProperty("cluster");}
public String getNodeName() {return _objectName.getKeyProperty("node");}
public String getName() {return _objectName.getKeyProperty("name");}
protected abstract Object alloc();
public abstract Object registerData(String uid, Object data);
public abstract Object deregisterData(String uid);
public static ObjectName
makeObjectName(String clusterName, String nodeName, String tierName)
throws Exception
{
return new
ObjectName("geronimo.clustering:role=Tier,name="+tierName+",node="+nodeName+",cluster="+clusterName);
}
//----------------------------------------
// GeronimoMBeanTarget
//----------------------------------------
public boolean
canStart()
{
if (_objectName.getKeyProperty("name")==null)
{
_log.warn("TierMBean name must contain a 'name' property");
return false;
}
if (_objectName.getKeyProperty("node")==null)
{
_log.warn("NodeMBean name must contain a 'node' property");
return false;
}
if (_objectName.getKeyProperty("cluster")==null)
{
_log.warn("NodeMBean name must contain a 'cluster' property");
return false;
}
return true;
}
public boolean canStop() {return true;}
public synchronized void
doStart()
{
_log.info("starting");
// find our node
try
{
_node=Node.makeObjectName(getClusterName(), getNodeName());
// register our session map with it's Data object
Data data=(Data)_server.getAttribute(_node, "Data");
_log.info("Data:"+data);
_tiers=data.getTiers(); // immutable, so doesn't need synchronisation
}
catch (Exception e)
{
_log.error("could not retrieve Node state", e);
}
_tier=null;
synchronized (_tiers)
{
_tier=_tiers.get(getName());
if (_tier==null)
{
_tier=alloc();
_tiers.put(getName(), _tier);
}
// tier storage now initialised...
}
}
public void
doStop()
{
// TODO
}
public void doFail() {}
public void
setMBeanContext(GeronimoMBeanContext context)
{
_objectName=(context==null)?null:context.getObjectName();
_server =(context==null)?null:context.getServer();
}
public static GeronimoMBeanInfo
getGeronimoMBeanInfo()
{
GeronimoMBeanInfo mbeanInfo=new GeronimoMBeanInfo();
//set target class in concrete subclass
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("Name", true,
false, "Name of this Tier"));
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("NodeName", true,
false, "Name of this Tier's Node"));
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("ClusterName", true,
false, "Name of this Tier's Node's Cluster"));
mbeanInfo.addOperationInfo(new GeronimoOperationInfo("registerData",
new
GeronimoParameterInfo[] {new GeronimoParameterInfo("uid", String.class, "uid of
webapp"),new GeronimoParameterInfo("data", Object.class, "data to be held")},
MBeanOperationInfo.ACTION,
"Register data with
Tier state manager"));
return mbeanInfo;
}
}
1.1
incubator-geronimo/modules/clustering/src/java/org/apache/geronimo/clustering/Node.java
Index: Node.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.clustering;
import java.util.List;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanTarget;
/**
*
* @version $Revision: 1.1 $ $Date: 2004/01/03 01:42:56 $
*/
public class
Node
implements GeronimoMBeanTarget, MetaDataListener, DataListener,
DataDeltaListener
{
protected static Log _log=LogFactory.getLog(Node.class);
protected ObjectName _objectName;
protected MBeanServer _server;
protected Cluster _cluster;
//----------------------------------------
// Node
//----------------------------------------
/**
* Returns the Node's Cluster's MBean's unique identifier.
*
* @return a <code>String</code> value
*/
public String getCluster() {return _objectName.getKeyProperty("cluster");}
/**
* Returns the Node's unique identifier within it's Cluster.
*
* @return a <code>String</code> value
*/
public String getName() {return _objectName.getKeyProperty("name");}
/**
* Returns the Node's Cluster's current membership.
*
* @return a <code>List</code> value
*/
public List getMembers(){return _cluster.getMembers();}
/**
* Makes an ObjectName for a NodeMBean with the given parameters.
*
* @param clusterName a <code>String</code> value
* @param nodeName a <code>String</code> value
* @return an <code>ObjectName</code> value
* @exception Exception if an error occurs
*/
public static ObjectName
makeObjectName(String clusterName, String nodeName)
throws Exception
{
return new
ObjectName("geronimo.clustering:role=Node,name="+nodeName+",cluster="+clusterName);
}
//----------------------------------------
// MetaDataListener
//----------------------------------------
public void
setMetaData(List members)
{
_log.info("membership changed: "+members);
}
//----------------------------------------
// DataListener
//----------------------------------------
protected Data _data;
public Data getData() {return _data;}
public void
setData(Data data)
{
String xtra="we must be the first node up";
if (data!=null)
{
xtra="we are joining an extant cluster";
_data=data;
}
else
{
_data=new Data();
}
_log.debug("initialising data - "+xtra);
}
//----------------------------------------
// DataDeltaListener
//----------------------------------------
public void
applyDataDelta(DataDelta delta)
{
_log.trace("applying data delta - "+delta);
}
//----------------------------------------
// GeronimoMBeanTarget
//----------------------------------------
public boolean
canStart()
{
if (_objectName.getKeyProperty("name")==null)
{
_log.warn("NodeMBean name must contain a 'name' property");
return false;
}
if (_objectName.getKeyProperty("cluster")==null)
{
_log.warn("NodeMBean name must contain a 'cluster' property");
return false;
}
return true;
}
public boolean canStop() {return true;}
public void
doStart()
{
_log=LogFactory.getLog(getClass().getName()+"#"+getCluster()+"/"+getName());
_log.info("starting");
_cluster=LocalCluster.find(getCluster()); // TODO abstract out
synchronized (_cluster)
{
Data data=_cluster.getData();
_log.info("state transfer - sending: "+data);
setData(data);
_cluster.join(this);
}
}
public void
doStop()
{
_log.info("stopping");
_cluster.leave(this);
}
public void
doFail()
{
_log.info("failing");
_cluster.leave(this); // TODO - ??
}
public void
setMBeanContext(GeronimoMBeanContext context)
{
_objectName=(context==null)?null:context.getObjectName();
_server =(context==null)?null:context.getServer();
}
public static GeronimoMBeanInfo
getGeronimoMBeanInfo()
{
GeronimoMBeanInfo mbeanInfo=new GeronimoMBeanInfo();
mbeanInfo.setTargetClass(Node.class);
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("Name", true,
false, "unique identifier for this Node (within it's Cluster)"));
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("Cluster", true,
false, "unique identifier for this Node's Cluster"));
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("Members", true,
false, "list of cluster members"));
mbeanInfo.addAttributeInfo(new GeronimoAttributeInfo("Data", true,
false, "cluster state"));
return mbeanInfo;
}
}
1.6 +24 -9
incubator-geronimo/modules/clustering/src/deploy/clustering-service.xml
Index: clustering-service.xml
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/clustering/src/deploy/clustering-service.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- clustering-service.xml 2 Jan 2004 17:52:30 -0000 1.5
+++ clustering-service.xml 3 Jan 2004 01:42:56 -0000 1.6
@@ -16,39 +16,55 @@
<!-- Start two Clusters containing 5 nodes (all Local) -->
<!-- ============================================================ -->
+<!--
<mbean
descriptor="org.apache.geronimo.clustering.LocalCluster"
- name="geronimo.clustering:role=Cluster,name=GERONIMO,node=0"
+ name="geronimo.clustering:role=Cluster,name=GERONIMO"
+ >
+ </mbean>
+-->
+ <mbean
+ descriptor="org.apache.geronimo.clustering.Node"
+ name="geronimo.clustering:role=Node,name=0,cluster=GERONIMO"
>
</mbean>
<mbean
- descriptor="org.apache.geronimo.clustering.LocalCluster"
- name="geronimo.clustering:role=Cluster,name=GERONIMO,node=1"
+ descriptor="org.apache.geronimo.clustering.Node"
+ name="geronimo.clustering:role=Node,name=1,cluster=GERONIMO"
>
</mbean>
<mbean
- descriptor="org.apache.geronimo.clustering.LocalCluster"
- name="geronimo.clustering:role=Cluster,name=GERONIMO,node=2"
+ descriptor="org.apache.geronimo.clustering.Node"
+ name="geronimo.clustering:role=Node,name=2,cluster=GERONIMO"
>
</mbean>
+<!--
<mbean
descriptor="org.apache.geronimo.clustering.LocalCluster"
- name="geronimo.clustering:role=Cluster,name=GERONIMO2,node=0"
+ name="geronimo.clustering:role=Cluster,name=GERONIMO2"
>
</mbean>
+-->
<mbean
- descriptor="org.apache.geronimo.clustering.LocalCluster"
- name="geronimo.clustering:role=Cluster,name=GERONIMO2,node=1"
+ descriptor="org.apache.geronimo.clustering.Node"
+ name="geronimo.clustering:role=Node,name=0,cluster=GERONIMO2"
+ >
+ </mbean>
+
+ <mbean
+ descriptor="org.apache.geronimo.clustering.Node"
+ name="geronimo.clustering:role=Node,name=1,cluster=GERONIMO2"
>
</mbean>
<!-- ============================================================ -->
<!-- Web Tier Manager -->
<!-- ============================================================ -->
+
<mbean
descriptor="org.apache.geronimo.clustering.web.WebTier"
name="geronimo.clustering:role=Tier,name=web,cluster=GERONIMO,node=0"
@@ -73,7 +89,6 @@
descriptor="org.apache.geronimo.clustering.web.HttpSessionManager"
name="geronimo.clustering:role=HttpSessionManager,context=/dummy,cluster=GERONIMO,node=0"
>
- <!-- I use attributes here because these Objects will be created
dynamically insinde the WebContainer -->
<attribute name="ClusterName">GERONIMO</attribute>
<attribute name="NodeName">0</attribute>
<attribute name="ContextPath">/dummy</attribute>
1.2 +3 -5 incubator-geronimo/modules/clustering/build.sh
Index: build.sh
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/clustering/build.sh,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- build.sh 2 Jan 2004 19:46:30 -0000 1.1
+++ build.sh 3 Jan 2004 01:42:56 -0000 1.2
@@ -17,8 +17,6 @@
## rebuild clustering service
## install result into dev tree
## run dev tree
-time maven --emacs clean build jar:install javadoc && \
-cp target/*.jar ../../target/geronimo-DEV/lib/ && \
-cp src/deploy/*.xml ../../target/geronimo-DEV/deploy/ && \
-cd ../../ &&
-time maven --emacs run:main
+time maven --emacs clean javadoc && \
+cd ../../ && \
+time maven --emacs -Dmodules=clustering build run:main