You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by gd...@apache.org on 2004/07/17 05:38:42 UTC

cvs commit: incubator-geronimo/sandbox/messaging/src/test/org/apache/geronimo/messaging/cluster ClusterInfoEditorTest.java

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.
    * <BR>
  - * 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("<InetAddress>,<port>");
          }
          InetAddressEditor addressEditor = new InetAddressEditor();
          addressEditor.setAsText((String) tokenizer.nextElement());
          InetAddress address = (InetAddress) addressEditor.getValue();
          
          if ( !tokenizer.hasMoreElements() ) {
              throw new PropertyEditorException("<InetAddress>,<port>");
          }
          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) {
          }
      }
      
  }