Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » tribes » membership » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.catalina.tribes.membership;
   19   
   20   import java.util.Properties;
   21   
   22   import org.apache.catalina.tribes.Member;
   23   import org.apache.catalina.tribes.MembershipListener;
   24   import org.apache.catalina.tribes.MembershipService;
   25   import org.apache.catalina.tribes.util.StringManager;
   26   import org.apache.catalina.tribes.util.UUIDGenerator;
   27   import java.io.IOException;
   28   
   29   /**
   30    * A <b>membership</b> implementation using simple multicast.
   31    * This is the representation of a multicast membership service.
   32    * This class is responsible for maintaining a list of active cluster nodes in the cluster.
   33    * If a node fails to send out a heartbeat, the node will be dismissed.
   34    *
   35    * @author Filip Hanik
   36    * @version $Revision: 567472 $, $Date: 2007-08-19 23:12:31 +0200 (dim., 19 août 2007) $
   37    */
   38   
   39   
   40   public class McastService implements MembershipService,MembershipListener {
   41   
   42       private static org.apache.juli.logging.Log log =
   43           org.apache.juli.logging.LogFactory.getLog( McastService.class );
   44   
   45       /**
   46        * The string manager for this package.
   47        */
   48       protected StringManager sm = StringManager.getManager(Constants.Package);
   49   
   50       /**
   51        * The descriptive information about this implementation.
   52        */
   53       private static final String info = "McastService/2.1";
   54   
   55       /**
   56        * The implementation specific properties
   57        */
   58       protected Properties properties = new Properties();
   59       /**
   60        * A handle to the actual low level implementation
   61        */
   62       protected McastServiceImpl impl;
   63       /**
   64        * A membership listener delegate (should be the cluster :)
   65        */
   66       protected MembershipListener listener;
   67       /**
   68        * The local member
   69        */
   70       protected MemberImpl localMember ;
   71       private int mcastSoTimeout;
   72       private int mcastTTL;
   73       
   74       protected byte[] payload;
   75       
   76       protected byte[] domain;
   77   
   78       /**
   79        * Create a membership service.
   80        */
   81       public McastService() {
   82           //default values
   83           properties.setProperty("mcastPort","45564");
   84           properties.setProperty("mcastAddress","228.0.0.4");
   85           properties.setProperty("memberDropTime","3000");
   86           properties.setProperty("mcastFrequency","500");
   87   
   88       }
   89   
   90       /**
   91        * Return descriptive information about this implementation and the
   92        * corresponding version number, in the format
   93        * <code>&lt;description&gt;/&lt;version&gt;</code>.
   94        */
   95       public String getInfo() {
   96           return (info);
   97       }
   98       
   99       /**
  100        *
  101        * @param properties
  102        * <BR/>All are required<BR />
  103        * 1. mcastPort - the port to listen to<BR>
  104        * 2. mcastAddress - the mcast group address<BR>
  105        * 4. bindAddress - the bind address if any - only one that can be null<BR>
  106        * 5. memberDropTime - the time a member is gone before it is considered gone.<BR>
  107        * 6. mcastFrequency - the frequency of sending messages<BR>
  108        * 7. tcpListenPort - the port this member listens to<BR>
  109        * 8. tcpListenHost - the bind address of this member<BR>
  110        * @exception java.lang.IllegalArgumentException if a property is missing.
  111        */
  112       public void setProperties(Properties properties) {
  113           hasProperty(properties,"mcastPort");
  114           hasProperty(properties,"mcastAddress");
  115           hasProperty(properties,"memberDropTime");
  116           hasProperty(properties,"mcastFrequency");
  117           hasProperty(properties,"tcpListenPort");
  118           hasProperty(properties,"tcpListenHost");
  119           this.properties = properties;
  120       }
  121   
  122       /**
  123        * Return the properties, see setProperties
  124        */
  125       public Properties getProperties() {
  126           return properties;
  127       }
  128   
  129       /**
  130        * Return the local member name
  131        */
  132       public String getLocalMemberName() {
  133           return localMember.toString() ;
  134       }
  135    
  136       /**
  137        * Return the local member
  138        */
  139       public Member getLocalMember(boolean alive) {
  140           if ( alive && localMember != null && impl != null) localMember.setMemberAliveTime(System.currentTimeMillis()-impl.getServiceStartTime());
  141           return localMember;
  142       }
  143       
  144       /**
  145        * Sets the local member properties for broadcasting
  146        */
  147       public void setLocalMemberProperties(String listenHost, int listenPort) {
  148           properties.setProperty("tcpListenHost",listenHost);
  149           properties.setProperty("tcpListenPort",String.valueOf(listenPort));
  150           try {
  151               if (localMember != null) {
  152                   localMember.setHostname(listenHost);
  153                   localMember.setPort(listenPort);
  154               } else {
  155                   localMember = new MemberImpl(listenHost, listenPort, 0);
  156                   localMember.setUniqueId(UUIDGenerator.randomUUID(true));
  157                   localMember.setPayload(getPayload());
  158                   localMember.setDomain(getDomain());
  159               }
  160               localMember.getData(true, true);
  161           }catch ( IOException x ) {
  162               throw new IllegalArgumentException(x);
  163           }
  164       }
  165       
  166       public void setAddress(String addr) {
  167           properties.setProperty("mcastAddress", addr);
  168       }
  169       
  170       /**
  171        * @deprecated use setAddress
  172        * @param addr String
  173        */
  174       public void setMcastAddr(String addr) {
  175           setAddress(addr);
  176       }
  177       
  178       public String getAddress() {
  179           return properties.getProperty("mcastAddress");
  180       }
  181       
  182       /**
  183        * @deprecated use getAddress
  184        * @return String
  185        */
  186       public String getMcastAddr() {
  187           return getAddress();
  188       }
  189   
  190       public void setMcastBindAddress(String bindaddr) {
  191           setBind(bindaddr);
  192       }
  193       
  194       public void setBind(String bindaddr) {
  195           properties.setProperty("mcastBindAddress", bindaddr);
  196       }
  197       /**
  198        * @deprecated use getBind
  199        * @return String
  200        */
  201       public String getMcastBindAddress() {
  202           return getBind();
  203       }
  204   
  205       public String getBind() {
  206           return properties.getProperty("mcastBindAddress");
  207       }
  208   
  209       /**
  210        * @deprecated use setPort
  211        * @param port int
  212        */
  213       public void setMcastPort(int port) {
  214           setPort(port);
  215       }
  216   
  217       public void setPort(int port) {
  218           properties.setProperty("mcastPort", String.valueOf(port));
  219       }
  220       
  221       public void setRecoveryCounter(int recoveryCounter) {
  222           properties.setProperty("recoveryCounter", String.valueOf(recoveryCounter));
  223       }
  224   
  225       public void setRecoveryEnabled(boolean recoveryEnabled) {
  226           properties.setProperty("recoveryEnabled", String.valueOf(recoveryEnabled));
  227       }
  228   
  229       public void setRecoverySleepTime(long recoverySleepTime) {
  230           properties.setProperty("recoverySleepTime", String.valueOf(recoverySleepTime));
  231       }
  232   
  233   
  234       /**
  235        * @deprecated use getPort()
  236        * @return int
  237        */
  238       public int getMcastPort() {
  239           return getPort();
  240       }
  241       public int getPort() {
  242           String p = properties.getProperty("mcastPort");
  243           return new Integer(p).intValue();
  244       }
  245       
  246       /**
  247        * @deprecated use setFrequency
  248        * @param time long
  249        */
  250       public void setMcastFrequency(long time) {
  251           setFrequency(time);
  252       }
  253       
  254       public void setFrequency(long time) {
  255           properties.setProperty("mcastFrequency", String.valueOf(time));
  256       }
  257   
  258       /**
  259        * @deprecated use getFrequency
  260        * @return long
  261        */
  262       public long getMcastFrequency() {
  263           return getFrequency();
  264       }
  265   
  266       public long getFrequency() {
  267           String p = properties.getProperty("mcastFrequency");
  268           return new Long(p).longValue();
  269       }
  270   
  271       public void setMcastDropTime(long time) {
  272           setDropTime(time);
  273       }
  274       public void setDropTime(long time) {
  275           properties.setProperty("memberDropTime", String.valueOf(time));
  276       }
  277       
  278       /**
  279        * @deprecated use getDropTime
  280        * @return long
  281        */
  282       public long getMcastDropTime() {
  283           return getDropTime();
  284       }
  285   
  286       public long getDropTime() {
  287           String p = properties.getProperty("memberDropTime");
  288           return new Long(p).longValue();
  289       }
  290   
  291       /**
  292        * Check if a required property is available.
  293        * @param properties The set of properties
  294        * @param name The property to check for
  295        */
  296       protected void hasProperty(Properties properties, String name){
  297           if ( properties.getProperty(name)==null) throw new IllegalArgumentException("McastService:Required property \""+name+"\" is missing.");
  298       }
  299   
  300       /**
  301        * Start broadcasting and listening to membership pings
  302        * @throws java.lang.Exception if a IO error occurs
  303        */
  304       public void start() throws java.lang.Exception {
  305           start(MembershipService.MBR_RX);
  306           start(MembershipService.MBR_TX);
  307       }
  308       
  309       public void start(int level) throws java.lang.Exception {
  310           hasProperty(properties,"mcastPort");
  311           hasProperty(properties,"mcastAddress");
  312           hasProperty(properties,"memberDropTime");
  313           hasProperty(properties,"mcastFrequency");
  314           hasProperty(properties,"tcpListenPort");
  315           hasProperty(properties,"tcpListenHost");
  316   
  317           if ( impl != null ) {
  318               impl.start(level);
  319               return;
  320           }
  321           String host = getProperties().getProperty("tcpListenHost");
  322           int port = Integer.parseInt(getProperties().getProperty("tcpListenPort"));
  323           
  324           if ( localMember == null ) {
  325               localMember = new MemberImpl(host, port, 100);
  326               localMember.setUniqueId(UUIDGenerator.randomUUID(true));
  327           } else {
  328               localMember.setHostname(host);
  329               localMember.setPort(port);
  330               localMember.setMemberAliveTime(100);
  331           }
  332           if ( this.payload != null ) localMember.setPayload(payload);
  333           if ( this.domain != null ) localMember.setDomain(domain);
  334           localMember.setServiceStartTime(System.currentTimeMillis());
  335           java.net.InetAddress bind = null;
  336           if ( properties.getProperty("mcastBindAddress")!= null ) {
  337               bind = java.net.InetAddress.getByName(properties.getProperty("mcastBindAddress"));
  338           }
  339           int ttl = -1;
  340           int soTimeout = -1;
  341           if ( properties.getProperty("mcastTTL") != null ) {
  342               try {
  343                   ttl = Integer.parseInt(properties.getProperty("mcastTTL"));
  344               } catch ( Exception x ) {
  345                   log.error("Unable to parse mcastTTL="+properties.getProperty("mcastTTL"),x);
  346               }
  347           }
  348           if ( properties.getProperty("mcastSoTimeout") != null ) {
  349               try {
  350                   soTimeout = Integer.parseInt(properties.getProperty("mcastSoTimeout"));
  351               } catch ( Exception x ) {
  352                   log.error("Unable to parse mcastSoTimeout="+properties.getProperty("mcastSoTimeout"),x);
  353               }
  354           }
  355   
  356           impl = new McastServiceImpl((MemberImpl)localMember,Long.parseLong(properties.getProperty("mcastFrequency")),
  357                                       Long.parseLong(properties.getProperty("memberDropTime")),
  358                                       Integer.parseInt(properties.getProperty("mcastPort")),
  359                                       bind,
  360                                       java.net.InetAddress.getByName(properties.getProperty("mcastAddress")),
  361                                       ttl,
  362                                       soTimeout,
  363                                       this);
  364           String value = properties.getProperty("recoveryEnabled","true");
  365           boolean recEnabled = Boolean.valueOf(value).booleanValue() ;
  366           impl.setRecoveryEnabled(recEnabled);        
  367           int recCnt = Integer.parseInt(properties.getProperty("recoveryCounter","10"));
  368           impl.setRecoveryCounter(recCnt);
  369           long recSlpTime = Long.parseLong(properties.getProperty("recoverySleepTime","5000"));
  370           impl.setRecoverySleepTime(recSlpTime);
  371           
  372           
  373           impl.start(level);
  374   		
  375   
  376       }
  377   
  378    
  379       /**
  380        * Stop broadcasting and listening to membership pings
  381        */
  382       public void stop(int svc) {
  383           try  {
  384               if ( impl != null && impl.stop(svc) ) impl = null;
  385           } catch ( Exception x)  {
  386               log.error("Unable to stop the mcast service, level:"+svc+".",x);
  387           }
  388       }
  389   
  390   
  391       /**
  392        * Return all the members by name
  393        */
  394       public String[] getMembersByName() {
  395           Member[] currentMembers = getMembers();
  396           String [] membernames ;
  397           if(currentMembers != null) {
  398               membernames = new String[currentMembers.length];
  399               for (int i = 0; i < currentMembers.length; i++) {
  400                   membernames[i] = currentMembers[i].toString() ;
  401               }
  402           } else
  403               membernames = new String[0] ;
  404           return membernames ;
  405       }
  406    
  407       /**
  408        * Return the member by name
  409        */
  410       public Member findMemberByName(String name) {
  411           Member[] currentMembers = getMembers();
  412           for (int i = 0; i < currentMembers.length; i++) {
  413               if (name.equals(currentMembers[i].toString()))
  414                   return currentMembers[i];
  415           }
  416           return null;
  417       }
  418   
  419       /**
  420        * has members?
  421        */
  422       public boolean hasMembers() {
  423          if ( impl == null || impl.membership == null ) return false;
  424          return impl.membership.hasMembers();
  425       }
  426       
  427       public Member getMember(Member mbr) {
  428           if ( impl == null || impl.membership == null ) return null;
  429           return impl.membership.getMember(mbr);
  430       }
  431   
  432       /**
  433        * Return all the members
  434        */
  435       protected static final Member[]EMPTY_MEMBERS = new Member[0];
  436       public Member[] getMembers() {
  437           if ( impl == null || impl.membership == null ) return EMPTY_MEMBERS;
  438           return impl.membership.getMembers();
  439       }
  440       /**
  441        * Add a membership listener, this version only supports one listener per service,
  442        * so calling this method twice will result in only the second listener being active.
  443        * @param listener The listener
  444        */
  445       public void setMembershipListener(MembershipListener listener) {
  446           this.listener = listener;
  447       }
  448       /**
  449        * Remove the membership listener
  450        */
  451       public void removeMembershipListener(){
  452           listener = null;
  453       }
  454   
  455       public void memberAdded(Member member) {
  456           if ( listener!=null ) listener.memberAdded(member);
  457       }
  458   
  459       /**
  460        * Callback from the impl when a new member has been received
  461        * @param member The member
  462        */
  463       public void memberDisappeared(Member member)
  464       {
  465           if ( listener!=null ) listener.memberDisappeared(member);
  466       }
  467   
  468       /**
  469        * @deprecated use getSoTimeout
  470        * @return int
  471        */
  472       public int getMcastSoTimeout() {
  473           return getSoTimeout();
  474       }
  475       
  476       public int getSoTimeout() {
  477           return mcastSoTimeout;
  478       }
  479       
  480       /**
  481        * @deprecated use setSoTimeout
  482        * @param mcastSoTimeout int
  483        */
  484       public void setMcastSoTimeout(int mcastSoTimeout) {
  485           setSoTimeout(mcastSoTimeout);
  486       }
  487       
  488       public void setSoTimeout(int mcastSoTimeout) {
  489           this.mcastSoTimeout = mcastSoTimeout;
  490           properties.setProperty("mcastSoTimeout", String.valueOf(mcastSoTimeout));
  491       }
  492       
  493       /**
  494        * @deprecated use getTtl
  495        * @return int
  496        */
  497       public int getMcastTTL() {
  498           return getTtl();
  499       }
  500       
  501       public int getTtl() {
  502           return mcastTTL;
  503       }
  504   
  505       public byte[] getPayload() {
  506           return payload;
  507       }
  508       
  509       public byte[] getDomain() {
  510           return domain;
  511       }
  512       
  513       /**
  514        * @deprecated use setTtl
  515        * @param mcastTTL int
  516        */
  517       public void setMcastTTL(int mcastTTL) {
  518           setTtl(mcastTTL);
  519       }
  520   
  521       public void setTtl(int mcastTTL) {
  522           this.mcastTTL = mcastTTL;
  523           properties.setProperty("mcastTTL", String.valueOf(mcastTTL));
  524       }
  525   
  526       public void setPayload(byte[] payload) {
  527           this.payload = payload;
  528           if ( localMember != null ) {
  529               localMember.setPayload(payload);
  530               localMember.getData(true,true);
  531               try {
  532                   if (impl != null) impl.send(false);
  533               }catch ( Exception x ) {
  534                   log.error("Unable to send payload update.",x);
  535               }
  536           }
  537       }
  538       
  539       public void setDomain(byte[] domain) {
  540           this.domain = domain;
  541           if ( localMember != null ) {
  542               localMember.setDomain(domain);
  543               localMember.getData(true,true);
  544               try {
  545                   if (impl != null) impl.send(false);
  546               }catch ( Exception x ) {
  547                   log.error("Unable to send domain update.",x);
  548               }
  549           }
  550       }
  551   
  552       /**
  553        * Simple test program
  554        * @param args Command-line arguments
  555        * @throws Exception If an error occurs
  556        */
  557       public static void main(String args[]) throws Exception {
  558   		if(log.isInfoEnabled())
  559               log.info("Usage McastService hostname tcpport");
  560           McastService service = new McastService();
  561           java.util.Properties p = new java.util.Properties();
  562           p.setProperty("mcastPort","5555");
  563           p.setProperty("mcastAddress","224.10.10.10");
  564           p.setProperty("mcastClusterDomain","catalina");
  565           p.setProperty("bindAddress","localhost");
  566           p.setProperty("memberDropTime","3000");
  567           p.setProperty("mcastFrequency","500");
  568           p.setProperty("tcpListenPort","4000");
  569           p.setProperty("tcpListenHost","127.0.0.1");
  570           service.setProperties(p);
  571           service.start();
  572           Thread.sleep(60*1000*60);
  573       }
  574   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » tribes » membership » [javadoc | source]