bip 01/05/04 13:48:04 Added: catalina/src/share/org/apache/catalina/cluster ClusterMemberInfo.java MulticastReceiver.java MulticastSender.java ReplicationWrapper.java StandardCluster.java Log: Basic Cluster implementation Revision Changes Path 1.1 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/ClusterMemberInfo.java Index: ClusterMemberInfo.java =================================================================== /* * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/ClusterMemberInfo.java,v 1.1 2001/05/04 20:48:00 bip Exp $ * $Revision: 1.1 $ * $Date: 2001/05/04 20:48:00 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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 acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" 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" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 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/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.catalina.cluster; /** * Class that represents a member in a Cluster, keeps information * that can be used when implementing Classes thats utilizing a Cluster. * * @author Bip Thelin * @version $Revision: 1.1 $ */ public final class ClusterMemberInfo { // ------------------------------------------------------------- Properties // --------------------------------------------------------- Public Methods } 1.1 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/MulticastReceiver.java Index: MulticastReceiver.java =================================================================== /* * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/MulticastReceiver.java,v 1.1 2001/05/04 20:48:01 bip Exp $ * $Revision: 1.1 $ * $Date: 2001/05/04 20:48:01 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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 acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" 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" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 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/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.catalina.cluster; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import java.io.InputStream; import java.io.OutputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.util.Vector; /** * This class is responsible for checking for incoming multicast * data and determine if the data belongs to us and if so push * it onto an internal stack and let it be picked up when needed. * * @author Bip Thelin * @version $Revision: 1.1 $ */ public class MulticastReceiver implements Runnable { // ----------------------------------------------------- Instance Variables /** * The unique message ID */ private static String senderId = null; /** * The MulticastSocket to use */ private MulticastSocket multicastSocket = null; /** * Our Thread name */ private String threadName = "MulticastReceiver"; /** * The stack that keeps incoming requests */ private static Vector stack = new Vector(); /** * Has this component been started? */ private boolean started = false; /** * The background thread. */ private Thread thread = null; /** * The background thread completion semaphore. */ protected boolean threadDone = false; /** * The interval for the background thread to sleep */ private int checkInterval = 5; // --------------------------------------------------------- Public Methods /** * Create a new MulticastReceiver. * * @param senderId The unique senderId * @param multicastSocket The MulticastSocket to use */ MulticastReceiver(String senderId, MulticastSocket multicastSocket, InetAddress multicastAddress, int multicastPort) { this.multicastSocket = multicastSocket; this.senderId = senderId; } /** * Receive the objects currently in our stack * * @return An array with objects */ public Object[] getObjects() { Object[] objs = stack.toArray(); stack.removeAllElements(); return (objs); } /** * Start our component */ public void start() { started = true; // Start the background reaper thread threadStart(); } /** * Stop our component */ public void stop() { started = false; // Stop the background reaper thread threadStop(); } // --------------------------------------------------------- Private Methods /** * Check our multicast socket for new data and determine if the * data matches us(senderId) and if so push it onto the stack, */ private void receive() { try { byte[] buf = new byte[5000]; DatagramPacket recv = new DatagramPacket(buf, buf.length); ByteArrayInputStream ips = null; ObjectInputStream ois = null; multicastSocket.receive(recv); ips = new ByteArrayInputStream(buf, 0, buf.length); ois = new ObjectInputStream(ips); ReplicationWrapper obj = (ReplicationWrapper)ois.readObject(); if(obj.getSenderId().equals(this.senderId)) stack.add(obj); } catch (IOException e) { System.out.println("An error occured when trying to replicate: "+ e.toString()); } catch (ClassNotFoundException e) { System.out.println("An error occured when trying to replicate: "+ e.toString()); } } // ------------------------------------------------------ Background Thread /** * The background thread. */ public void run() { // Loop until the termination semaphore is set while (!threadDone) { receive(); threadSleep(); } } /** * Sleep for the duration specified by the <code>checkInterval</code> * property. */ private void threadSleep() { try { Thread.sleep(checkInterval * 1000L); } catch (InterruptedException e) { ; } } /** * Start the background thread. */ private void threadStart() { if (thread != null) return; threadDone = false; threadName = threadName+"["+senderId+"]"; thread = new Thread(this, threadName); thread.setDaemon(true); thread.start(); } /** * Stop the background thread. */ private void threadStop() { if (thread == null) return; threadDone = true; thread.interrupt(); try { thread.join(); } catch (InterruptedException e) { ; } thread = null; } } 1.1 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/MulticastSender.java Index: MulticastSender.java =================================================================== /* * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/MulticastSender.java,v 1.1 2001/05/04 20:48:01 bip Exp $ * $Revision: 1.1 $ * $Date: 2001/05/04 20:48:01 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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 acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" 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" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 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/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.catalina.cluster; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import java.io.InputStream; import java.io.OutputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; /** * This class is responsible for sending outgoing multicast * packets to a Cluster. * * @author Bip Thelin * @version $Revision: 1.1 $ */ public class MulticastSender { // ----------------------------------------------------- Instance Variables /** * The unique message ID */ private static String senderId = null; /** * The MulticastSocket to use */ private MulticastSocket multicastSocket = null; /** * The multicastAdress this socket is bound to */ private InetAddress multicastAddress = null; /** * The multicastPort this socket is bound to */ private int multicastPort; // --------------------------------------------------------- Public Methods /** * Create a new MulticastSender, only receivers with our * senderId will receive our data. * * @param senderId The senderId * @param multicastSocket the socket to use * @param multicastAddress the address to use * @param multicastPort the port to use */ MulticastSender(String senderId, MulticastSocket multicastSocket, InetAddress multicastAddress, int multicastPort) { this.multicastAddress = multicastAddress; this.multicastPort = multicastPort; this.multicastSocket = multicastSocket; this.senderId = senderId; } /** * Send multicast data * * @param b data to be sent */ public synchronized void send(byte[] b) { ReplicationWrapper out = new ReplicationWrapper(b, senderId); ObjectOutputStream oos = null; ByteArrayOutputStream bos = null; try { bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(new BufferedOutputStream(bos)); oos.writeObject(out); oos.flush(); byte[] obs = bos.toByteArray(); int size = obs.length; System.out.println("size: "+size); DatagramPacket p = new DatagramPacket(obs, size, multicastAddress, multicastPort); multicastSocket.send(p); } catch (IOException e) { // log("An error occured when trying to replicate."); } } /** * Send multicast data * * @param p data to be sent */ public synchronized void send(DatagramPacket p) { try { multicastSocket.send(p); } catch (IOException e) { // log("An error occured when trying to replicate."); } } } 1.1 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/ReplicationWrapper.java Index: ReplicationWrapper.java =================================================================== /* * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/ReplicationWrapper.java,v 1.1 2001/05/04 20:48:02 bip Exp $ * $Revision: 1.1 $ * $Date: 2001/05/04 20:48:02 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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 acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" 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" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 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/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.catalina.cluster; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; /** * A ReplicationWrapper, used when sending and receiving multicast * data, wrapped is the data and the senderId which is used for * identification. * * @author Bip Thelin * @version $Revision: 1.1 $, $Date: 2001/05/04 20:48:02 $ */ public final class ReplicationWrapper implements Serializable { /** * Our buffer to hold the stream */ private byte[] _buf = null; /** * Our sender Id */ private String senderId = null; /** * Construct a new ReplicationWrapper * */ public ReplicationWrapper(byte[] b, String senderId) { this.senderId = senderId; _buf = b; } /** * Write our stream to the <code>OutputStream</code> provided. * * @param out the OutputStream to write this stream to * @exception IOException if an input/output error occurs */ public final void writeTo(OutputStream out) throws IOException { out.write(_buf); } /** * return our internal data as a array of bytes * * @return a our data */ public final byte[] getDataStream() { return(_buf); } /** * Set the sender id for this wrapper * * @param senderId The sender id */ public final void setSenderId(String senderId) { this.senderId = senderId; } /** * get the sender id for this wrapper * * @return The sender Id associated with this wrapper */ public final String getSenderId() { return(this.senderId); } } 1.1 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/StandardCluster.java Index: StandardCluster.java =================================================================== /* * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/cluster/StandardCluster.java,v 1.1 2001/05/04 20:48:03 bip Exp $ * $Revision: 1.1 $ * $Date: 2001/05/04 20:48:03 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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 acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" 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" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 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/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.catalina.cluster; import java.beans.PropertyChangeSupport; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.UnknownHostException; import java.io.IOException; import java.util.Collection; import org.apache.catalina.Cluster; import org.apache.catalina.Container; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; import org.apache.catalina.Logger; import org.apache.catalina.cluster.ClusterMemberInfo; import org.apache.catalina.cluster.MulticastSender; import org.apache.catalina.cluster.MulticastReceiver; import org.apache.catalina.util.LifecycleSupport; /** * A <b>Cluster</b> implementation. Responsible for setting up * a cluster and provides callers with a valid multicast receiver/sender. * * @author Bip Thelin * @version $Revision: 1.1 $ */ public final class StandardCluster implements Cluster, Lifecycle, Runnable { // ----------------------------------------------------- Instance Variables /** * Descriptive information about this component implementation. */ private static final String info = "StandardCluster/1.0"; /** * Name to register for the background thread. */ private String threadName = "StandardCluster"; /** * Name for logging purpose */ private String clusterImpName = "StandardCluster"; /** * The background thread. */ private Thread thread = null; /** * The background thread completion semaphore. */ private boolean threadDone = false; /** * The cluster name to join */ private String clusterName = null; /** * The Container associated with this Cluster. */ private Container container = null; /** * The MulticastPort to use with this cluster */ private int multicastPort; /** * The MulticastAdress to use with this cluster */ private InetAddress multicastAddress = null; /** * Our MulticastSocket */ private MulticastSocket multicastSocket = null; /** * The lifecycle event support for this component. */ private LifecycleSupport lifecycle = new LifecycleSupport(this); /** * Has this component been started? */ private boolean started = false; /** * The property change support for this component. */ private PropertyChangeSupport support = new PropertyChangeSupport(this); /** * The debug level for this Container */ private int debug = 99; /** * The interval for the background thread to sleep */ private int checkInterval = 60; // ------------------------------------------------------------- Properties /** * Return descriptive information about this Cluster implementation and * the corresponding version number, in the format * <code><description>/<version></code>. */ public String getInfo() { return(this.info); } /** * Return a <code>String</code> containing the name of this * Cluster implementation, used for logging * * @return The Cluster implementation */ protected String getName() { return(this.clusterImpName); } /** * Return the name of the cluster that this Server is currently * configured to operate within. * * @return The name of the cluster associated with this server */ public String getClusterName() { return(this.clusterName); } /** * Set the name of the cluster to join, if no cluster with * this name is present create one. * * @param clusterName The clustername to join */ public void setClusterName(String clusterName) { String oldClusterName = this.clusterName; this.clusterName = clusterName; support.firePropertyChange("clusterName", oldClusterName, this.clusterName); } /** * Set the Container associated with our Cluster * * @param container The Container to use */ public void setContainer(Container container) { Container oldContainer = this.container; this.container = container; support.firePropertyChange("container", oldContainer, this.container); } /** * Get the Port associated with our Cluster * * @return The Port associated with our Cluster */ public int getMulticastPort() { return(this.multicastPort); } /** * Set the Port associated with our Cluster * * @param port The Port to use */ public void setMulticastPort(int multicastPort) { int oldMulticastPort = this.multicastPort; this.multicastPort = multicastPort; support.firePropertyChange("multicastPort", oldMulticastPort, this.multicastPort); } /** * Get the Groupaddress associated with our Cluster * * @return The Groupaddress associated with our Cluster */ public InetAddress getMulticastAddress() { return(this.multicastAddress); } /** * Set the Groupaddress associated with our Cluster * * @param port The Groupaddress to use */ public void setMulticastAddress(String multicastAddress) { try { InetAddress oldMulticastAddress = this.multicastAddress; this.multicastAddress = InetAddress.getByName(multicastAddress); support.firePropertyChange("multicastAddress", oldMulticastAddress, this.multicastAddress); } catch (UnknownHostException e) { log("Invalid multicastAddress: "+multicastAddress); } } /** * Get the Container associated with our Cluster * * @return The Container associated with our Cluster */ public Container getContainer() { return(this.container); } // --------------------------------------------------------- Public Methods /** * Returns a collection containing <code>ClusterMemberInfo</code> * on the remote members of this Cluster. This method does * not include the local host, to retrieve * <code>ClusterMemberInfo</code> on the local host * use <code>getLocalClusterInfo()</code> instead. * * @return Collection with all members in the Cluster */ public Collection getRemoteClusterMembers() { return(null); } /** * Return cluster information about the local host * * @return Cluster information */ public ClusterMemberInfo getLocalClusterInfo() { return(null); } /** * Returns a <code>MulticastSender</code> which is the interface * to use when communicating in the Cluster. * * @return The MulticastSender to use */ public MulticastSender getMulticastSender(String senderId) { MulticastSender send = new MulticastSender(senderId, multicastSocket, multicastAddress, multicastPort); return(send); } /** * Returns a <code>MulticastReceiver</code> which is the interface * to use when communicating in the Cluster. * * @return The MulticastSender to use */ public MulticastReceiver getMulticastReceiver(String senderId) { MulticastReceiver recv = new MulticastReceiver(senderId, multicastSocket, multicastAddress, multicastPort); recv.start(); return(recv); } /** * Log a message on the Logger associated with our Container (if any). * * @param message Message to be logged */ protected void log(String message) { Logger logger = null; if (container != null) logger = container.getLogger(); if (logger != null) { logger.log(getName() + "[" + container.getName() + "]: " + message); } else { String containerName = null; if (container != null) containerName = container.getName(); System.out.println(getName() + "[" + containerName + "]: " + message); } } // ------------------------------------------------------ Lifecycle Methods /** * Add a lifecycle event listener to this component. * * @param listener The listener to add */ public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } /** * Remove a lifecycle event listener from this component. * * @param listener The listener to remove */ public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); } /** * Prepare for the beginning of active use of the public methods of this * component. This method should be called after <code>configure()</code>, * and before any of the public methods of the component are utilized. * * @exception IllegalStateException if this component has already been * started * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException { if (debug > 1) log("Started"); try { multicastSocket = new MulticastSocket(multicastPort); if(multicastSocket != null && multicastAddress != null) { multicastSocket.joinGroup(multicastAddress); if (debug > 1) log("Joining group: "+multicastAddress); } else { log("multicastSocket || multicastAddress can't be null"); } } catch (IOException e) { log("An error occured when trying to join group"); } // Validate and update our current component state if (started) ; lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Start the background reaper thread threadStart(); } /** * Gracefully terminate the active use of the public methods of this * component. This method should be the last one called on a given * instance of this component. * * @exception IllegalStateException if this component has not been started * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public void stop() throws LifecycleException { if (debug > 1) log("Stopping"); try { multicastSocket.leaveGroup(multicastAddress); multicastSocket = null; } catch (IOException e) { ; } if (debug > 1) log("Leaving group: "+multicastAddress); // Validate and update our current component state if (!started) ; lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; // Stop the background reaper thread threadStop(); } // ------------------------------------------------------ Background Thread /** * The background thread. */ public void run() { // Loop until the termination semaphore is set while (!threadDone) { threadSleep(); } } /** * Sleep for the duration specified by the <code>checkInterval</code> * property. */ private void threadSleep() { try { Thread.sleep(checkInterval * 1000L); } catch (InterruptedException e) { ; } } /** * Start the background thread. */ private void threadStart() { if (thread != null) return; threadDone = false; threadName = "StandardCluster[" + getClusterName() + "]"; thread = new Thread(this, threadName); thread.setDaemon(true); thread.start(); } /** * Stop the background thread. */ private void threadStop() { if (thread == null) return; threadDone = true; thread.interrupt(); try { thread.join(); } catch (InterruptedException e) { ; } thread = null; } }