Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 4639 invoked from network); 17 Jul 2004 03:38:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 17 Jul 2004 03:38:45 -0000 Received: (qmail 95492 invoked by uid 500); 17 Jul 2004 03:38:43 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 95478 invoked by uid 500); 17 Jul 2004 03:38:43 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: dev@geronimo.apache.org Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 95464 invoked by uid 500); 17 Jul 2004 03:38:43 -0000 Delivered-To: apmail-incubator-geronimo-cvs@apache.org Received: (qmail 95461 invoked by uid 99); 17 Jul 2004 03:38:43 -0000 X-ASF-Spam-Status: No, hits=0.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.27.1) with SMTP; Fri, 16 Jul 2004 20:38:43 -0700 Received: (qmail 4628 invoked by uid 1782); 17 Jul 2004 03:38:42 -0000 Date: 17 Jul 2004 03:38:42 -0000 Message-ID: <20040717033842.4627.qmail@minotaur.apache.org> From: gdamour@apache.org To: incubator-geronimo-cvs@apache.org Subject: cvs commit: incubator-geronimo/sandbox/messaging/src/test/org/apache/geronimo/messaging/cluster ClusterInfoEditorTest.java X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N gdamour 2004/07/16 20:38:42 Modified: sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster Cluster.java ClusterImpl.java Added: sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster ClusterInfo.java ClusterInfoEditor.java sandbox/messaging/src/test/org/apache/geronimo/messaging/cluster ClusterInfoEditorTest.java Log: o Adds the ClusterInfo notion. It wraps some meta-data (multicast group + port) specific to a given Cluster. o When a node is added or removed to a Cluster, an Exception is now raised if it is not possible to do so. Revision Changes Path 1.2 +13 -10 incubator-geronimo/sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster/Cluster.java Index: Cluster.java =================================================================== RCS file: /home/cvs/incubator-geronimo/sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster/Cluster.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Cluster.java 10 Jun 2004 23:12:25 -0000 1.1 +++ Cluster.java 17 Jul 2004 03:38:42 -0000 1.2 @@ -19,7 +19,7 @@ import java.util.Set; -import org.apache.geronimo.messaging.EndPoint; +import org.apache.geronimo.messaging.NodeException; import org.apache.geronimo.messaging.NodeInfo; /** @@ -28,16 +28,15 @@ * @version $Revision$ $Date$ */ public interface Cluster - extends EndPoint { /** - * Gets the cluster identifier. + * Gets the meta-data of this cluster. * - * @return Identifier. + * @return Cluster meta-data. */ - public Object getClusterID(); - + public ClusterInfo getClusterInfo(); + /** * Gets the Nodes of this cluster. * @@ -54,9 +53,11 @@ * When the topology has been applied, it notifies the registered * cluster event listeners of the addition. * - * @param aNode Node to be added to this cluster. + * @param aNode Node to be added to this cluster. + * @exception NodeException Indicates that the specified node can not be + * added. */ - public void addMember(NodeInfo aNode); + public void addMember(NodeInfo aNode) throws NodeException; /** * Removes a Node from this cluster. @@ -64,8 +65,10 @@ * See {@link addMember} for more details on the operations of this method. * * @param aNode + * @exception NodeException Indicates that the specified node can not be + * removed. */ - public void removeMember(NodeInfo aNode); + public void removeMember(NodeInfo aNode) throws NodeException; /** * Adds a listener to this cluster. 1.2 +80 -22 incubator-geronimo/sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster/ClusterImpl.java Index: ClusterImpl.java =================================================================== RCS file: /home/cvs/incubator-geronimo/sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster/ClusterImpl.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ClusterImpl.java 10 Jun 2004 23:12:25 -0000 1.1 +++ ClusterImpl.java 17 Jul 2004 03:38:42 -0000 1.2 @@ -21,8 +21,12 @@ import java.util.Collection; import java.util.Set; -import org.apache.geronimo.messaging.GBeanBaseEndPoint; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoFactory; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.gbean.WaitingException; import org.apache.geronimo.messaging.Node; +import org.apache.geronimo.messaging.NodeException; import org.apache.geronimo.messaging.NodeInfo; import org.apache.geronimo.messaging.NodeTopology; import org.apache.geronimo.messaging.cluster.topology.TopologyManager; @@ -30,18 +34,27 @@ /** * Cluster implementation. *
- * It is an EndPoint, which manages the nodes at the cluster level and triggers - * dynamic reconfigurations of the underlying node topology when members - * are added or removed. + * It manages the nodes at the cluster level and triggers dynamic + * reconfigurations of the underlying node topology when members are added or + * removed. * * @version $Revision$ $Date$ */ public class ClusterImpl - extends GBeanBaseEndPoint - implements Cluster + implements Cluster, GBeanLifecycle { + + /** + * Cluster meta-data. + */ + private final ClusterInfo clusterInfo; /** + * Node which is owning this cluster view. + */ + private final Node node; + + /** * To reconfigure the node topology. */ private final TopologyManager topologyManager; @@ -54,43 +67,72 @@ /** * Creates a cluster view mounted by the specified node. * + * @param aClusterInfo Cluster meta-data. * @param aNode Node which is mounting this cluster view. - * @param anID Cluster identifier. * @param aTopologyManager Use to reconfigure the node topology when * members joined or leaved the cluster. */ - public ClusterImpl(Node aNode, Object anID, + public ClusterImpl(ClusterInfo aClusterInfo, Node aNode, TopologyManager aTopologyManager) { - super(aNode, anID); - if ( null == aTopologyManager ) { + if ( null == aClusterInfo ) { + throw new IllegalArgumentException("ClusterInfo is required"); + } else if ( null == aNode ) { + throw new IllegalArgumentException("Node is required"); + } else if ( null == aTopologyManager ) { throw new IllegalArgumentException("Topology manager is required"); } - + clusterInfo = aClusterInfo; + node = aNode; topologyManager = aTopologyManager; - topologyManager.addNode(node.getNodeInfo()); listeners = new ArrayList(); } - - public Object getClusterID() { - return getID(); + + public void doStart() throws WaitingException, Exception { + topologyManager.addNode(node.getNodeInfo()); + } + + public void doStop() throws WaitingException, Exception { + topologyManager.removeNode(node.getNodeInfo()); } + public void doFail() { + topologyManager.removeNode(node.getNodeInfo()); + } + + public ClusterInfo getClusterInfo() { + return clusterInfo; + } + public Set getMembers() { return node.getTopology().getNodes(); } - public void addMember(NodeInfo aNode) { - topologyManager.addNode(aNode); - NodeTopology nodeTopology = topologyManager.factoryTopology(); + public void addMember(NodeInfo aNode) throws NodeException { + NodeTopology nodeTopology; + synchronized(topologyManager) { + Set nodes = topologyManager.getNodes(); + if ( nodes.contains(aNode) ) { + return; + } + topologyManager.addNode(aNode); + nodeTopology = topologyManager.factoryTopology(); + } node.setTopology(nodeTopology); fireClusterMemberEvent( new ClusterEvent(this, aNode, ClusterEvent.MEMBER_ADDED)); } - public void removeMember(NodeInfo aNode) { - topologyManager.removeNode(aNode); - NodeTopology nodeTopology = topologyManager.factoryTopology(); + public void removeMember(NodeInfo aNode) throws NodeException { + NodeTopology nodeTopology; + synchronized(topologyManager) { + Set nodes = topologyManager.getNodes(); + if ( !nodes.contains(aNode) ) { + return; + } + topologyManager.removeNode(aNode); + nodeTopology = topologyManager.factoryTopology(); + } node.setTopology(nodeTopology); fireClusterMemberEvent( new ClusterEvent(this, aNode, ClusterEvent.MEMBER_REMOVED)); @@ -117,6 +159,22 @@ for (int i = 0; i < tmpListeners.length;) { tmpListeners[i].fireClusterMemberEvent(anEvent); } + } + + public static final GBeanInfo GBEAN_INFO; + + static { + GBeanInfoFactory factory = new GBeanInfoFactory(ClusterImpl.class); + factory.setConstructor(new String[] {"clusterInfo", "Node", + "topologyManager"}); + factory.addInterface(Cluster.class, new String[] {"clusterInfo"}); + factory.addAttribute("topologyManager", TopologyManager.class, true); + factory.addReference("Node", Node.class); + GBEAN_INFO = factory.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; } } 1.1 incubator-geronimo/sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster/ClusterInfo.java Index: ClusterInfo.java =================================================================== /** * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.messaging.cluster; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.net.InetAddress; /** * Cluster meta-data. * * @version $Revision: 1.1 $ $Date: 2004/07/17 03:38:42 $ */ public class ClusterInfo implements Externalizable { /** * Multicast address used by this cluster for cluster-wide communications. */ private InetAddress address; /** * Multicast port. */ private int port; /** * Required for externalization */ public ClusterInfo() {} public ClusterInfo(InetAddress anAddress, int aPort) { if ( null == anAddress ) { throw new IllegalArgumentException("Address is required"); } address = anAddress; port = aPort; } public InetAddress getAddress() { return address; } public int getPort() { return port; } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { address = (InetAddress) in.readObject(); port = in.readInt(); } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(address); out.writeInt(port); } public String toString() { return " Cluster: address = {" + address + "}; port = {" + port + "}"; } } 1.1 incubator-geronimo/sandbox/messaging/src/java/org/apache/geronimo/messaging/cluster/ClusterInfoEditor.java Index: ClusterInfoEditor.java =================================================================== /** * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.messaging.cluster; import java.beans.PropertyEditorSupport; import java.net.InetAddress; import java.util.StringTokenizer; import org.apache.geronimo.common.propertyeditor.InetAddressEditor; import org.apache.geronimo.common.propertyeditor.PropertyEditorException; /** * ClusterInfo editor. * * @version $Revision: 1.1 $ $Date: 2004/07/17 03:38:42 $ */ public class ClusterInfoEditor extends PropertyEditorSupport { private ClusterInfo info; public void setAsText(String text) throws IllegalArgumentException { StringTokenizer tokenizer = new StringTokenizer(text, ","); if ( !tokenizer.hasMoreElements() ) { throw new PropertyEditorException(","); } InetAddressEditor addressEditor = new InetAddressEditor(); addressEditor.setAsText((String) tokenizer.nextElement()); InetAddress address = (InetAddress) addressEditor.getValue(); if ( !tokenizer.hasMoreElements() ) { throw new PropertyEditorException(","); } int port = Integer.parseInt((String) tokenizer.nextElement()); info = new ClusterInfo(address, port); } public Object getValue() { return info; } } 1.1 incubator-geronimo/sandbox/messaging/src/test/org/apache/geronimo/messaging/cluster/ClusterInfoEditorTest.java Index: ClusterInfoEditorTest.java =================================================================== /** * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.messaging.cluster; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import org.apache.geronimo.common.propertyeditor.PropertyEditorException; import junit.framework.TestCase; /** * * @version $Revision: 1.1 $ $Date: 2004/07/17 03:38:42 $ */ public class ClusterInfoEditorTest extends TestCase { public void testOK() throws Exception { String address = "127.0.0.1"; int port = 1234; String property = address + "," + port; PropertyEditor ed = PropertyEditorManager.findEditor(ClusterInfo.class); ed.setAsText(property); ClusterInfo info = (ClusterInfo) ed.getValue(); assertEquals(address, info.getAddress().getHostAddress()); assertEquals(port, info.getPort()); } public void testNOK() throws Exception { String address = "234.0.0.0"; String property = address; PropertyEditor ed = PropertyEditorManager.findEditor(ClusterInfo.class); try { ed.setAsText(property); fail("No port."); } catch (PropertyEditorException e) { } } }