KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > protocols > FD_ICMP


1 package org.jgroups.protocols;
2
3 import org.jgroups.Event;
4 import org.jgroups.Global;
5 import org.jgroups.stack.IpAddress;
6 import org.jgroups.util.Util;
7
8 import java.lang.reflect.Method JavaDoc;
9 import java.net.InetAddress JavaDoc;
10 import java.net.NetworkInterface JavaDoc;
11 import java.net.UnknownHostException JavaDoc;
12 import java.util.Map JavaDoc;
13 import java.util.Properties JavaDoc;
14
15 /**
16  * Protocol which uses InetAddress.isReachable() to check whether a given host is up or not,
17  * taking 1 argument; the host name of the host to be pinged.
18  * <em>Note that this protocol only works with JDK 5 !</em>
19  * The implementation of this may or may not use ICMP ! An alternative is to create a TCP connection to port 7 (echo service)
20  * and see whether it works ! This is obviously done in JDK 5, so unless an echo service is configured to run, this
21  * won't work...
22  * @author Bela Ban
23  * @version $Id: FD_ICMP.java,v 1.8 2007/04/27 07:59:19 belaban Exp $
24  */

25 public class FD_ICMP extends FD {
26
27     /** network interface to be used to send the ICMP packets */
28     private NetworkInterface JavaDoc intf=null;
29
30     private InetAddress JavaDoc bind_addr;
31
32     private Method JavaDoc is_reacheable;
33
34     /** Time-to-live for InetAddress.isReachable() */
35     private int ttl=32;
36
37
38
39     public String JavaDoc getName() {
40         return "FD_ICMP";
41     }
42
43
44     public boolean setProperties(Properties JavaDoc props) {
45         boolean ignore_systemprops=Util.isBindAddressPropertyIgnored();
46         String JavaDoc str=Util.getProperty(new String JavaDoc[]{Global.BIND_ADDR, Global.BIND_ADDR_OLD}, props, "bind_addr",
47                              ignore_systemprops, null);
48         if(str != null) {
49             try {
50                 bind_addr=InetAddress.getByName(str);
51             }
52             catch(UnknownHostException JavaDoc unknown) {
53                 if(log.isFatalEnabled()) log.fatal("(bind_addr): host " + str + " not known");
54                 return false;
55             }
56             props.remove("bind_addr");
57         }
58
59         str=props.getProperty("ttl");
60         if(str != null) {
61             ttl=Integer.parseInt(str);
62             props.remove("ttl");
63         }
64
65         super.setProperties(props);
66
67         try {
68             Class JavaDoc is_reacheable_class=Util.loadClass("java.net.InetAddress", this.getClass());
69             is_reacheable=is_reacheable_class.getMethod("isReachable", new Class JavaDoc[]{NetworkInterface JavaDoc.class, int.class, int.class});
70         }
71         catch(ClassNotFoundException JavaDoc e) {
72             // log.error("failed checking for InetAddress.isReachable() method - requires JDK 5 or higher");
73
Error JavaDoc error=new NoClassDefFoundError JavaDoc("failed checking for InetAddress.isReachable() method - requires JDK 5 or higher");
74             error.initCause(e);
75             throw error;
76         }
77         catch(NoSuchMethodException JavaDoc e) {
78             // log.error("didn't find InetAddress.isReachable() method - requires JDK 5 or higher");
79
Error JavaDoc error= new NoSuchMethodError JavaDoc("didn't find InetAddress.isReachable() method - requires JDK 5 or higher");
80             error.initCause(e);
81             throw error;
82         }
83
84
85         if(!props.isEmpty()) {
86             log.error("the following properties are not recognized: " + props);
87             return false;
88         }
89         return true;
90     }
91
92
93     public void init() throws Exception JavaDoc {
94         super.init();
95         if(bind_addr != null)
96             intf=NetworkInterface.getByInetAddress(bind_addr);
97     }
98
99     public Object JavaDoc up(Event evt) {
100         switch(evt.getType()) {
101             case Event.CONFIG:
102                 if(bind_addr == null) {
103                     Map JavaDoc config=(Map JavaDoc)evt.getArg();
104                     bind_addr=(InetAddress JavaDoc)config.get("bind_addr");
105                 }
106                 break;
107         }
108         return super.up(evt);
109     }
110
111
112     protected Monitor createMonitor() {
113         return new FD_ICMP.PingMonitor();
114     }
115
116
117     /**
118      * Runs InetAddress.isReachable(). Each time the command fails, we increment num_tries. If num_tries > max_tries, we
119      * emit a SUSPECT message. If ping_dest changes, or we do receive traffic from ping_dest, we reset num_tries to 0.
120      */

121     protected class PingMonitor extends Monitor {
122         long start, stop;
123
124         public void run() {
125             if(ping_dest == null) {
126                 if(log.isWarnEnabled())
127                     log.warn("ping_dest is null: members=" + members + ", pingable_mbrs=" +
128                             pingable_mbrs + ", local_addr=" + local_addr);
129                 return;
130             }
131
132             // 1. execute ping command
133
InetAddress JavaDoc host=ping_dest instanceof IpAddress? ((IpAddress)ping_dest).getIpAddress() : null;
134             if(host == null)
135                 throw new IllegalArgumentException JavaDoc("ping_dest is not of type IpAddress - FD_ICMP only works with these");
136             try {
137                 if(log.isTraceEnabled())
138                     log.trace("pinging " + host + " (ping_dest=" + ping_dest + ") using interface " + intf);
139                 start=System.currentTimeMillis();
140                 Boolean JavaDoc rc=(Boolean JavaDoc)is_reacheable.invoke(host, new Object JavaDoc[]{intf, new Integer JavaDoc(ttl), new Integer JavaDoc((int)timeout)});
141                 stop=System.currentTimeMillis();
142                 num_heartbeats++;
143                 if(rc.booleanValue()) { // success
144
num_tries=0;
145                     if(log.isTraceEnabled())
146                         log.trace("successfully received response from " + host + " (after " + (stop-start) + "ms)");
147                 }
148                 else { // failure
149
num_tries++;
150                     if(log.isDebugEnabled())
151                         log.debug("could not ping " + ping_dest + " (tries=" + num_tries + ") after " + (stop-start) + "ms)");
152                 }
153
154                 if(num_tries >= max_tries) {
155                     if(log.isDebugEnabled())
156                         log.debug("[" + local_addr + "]: could not ping " + ping_dest + " for " + (num_tries +1) +
157                                 " times (" + ((num_tries+1) * timeout) + " milliseconds), suspecting it");
158                     // broadcast a SUSPECT message to all members - loop until
159
// unsuspect or view change is received
160
bcast_task.addSuspectedMember(ping_dest);
161                     num_tries=0;
162                     if(stats) {
163                         num_suspect_events++;
164                         suspect_history.add(ping_dest);
165                     }
166                 }
167             }
168             catch(Exception JavaDoc ex) {
169                 if(log.isErrorEnabled())
170                     log.error("failed pinging " + ping_dest, ex);
171             }
172         }
173     }
174
175
176 }
177
Popular Tags