KickJava   Java API By Example, From Geeks To Geeks.

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


1 // $Id: PING.java,v 1.25 2005/04/26 15:22:12 belaban Exp $
2

3 package org.jgroups.protocols;
4
5 import org.jgroups.*;
6 import org.jgroups.stack.GossipClient;
7 import org.jgroups.stack.IpAddress;
8 import org.jgroups.util.List;
9 import org.jgroups.util.Util;
10
11 import java.net.InetAddress JavaDoc;
12 import java.util.Enumeration JavaDoc;
13 import java.util.Properties JavaDoc;
14 import java.util.StringTokenizer JavaDoc;
15 import java.util.Vector JavaDoc;
16
17
18 /**
19  * The PING protocol layer retrieves the initial membership (used by the GMS when started
20  * by sending event FIND_INITIAL_MBRS down the stack). We do this by mcasting PING
21  * requests to an IP MCAST address (or, if gossiping is enabled, by contacting the GossipServer).
22  * The responses should allow us to determine the coordinator whom we have to
23  * contact, e.g. in case we want to join the group. When we are a server (after having
24  * received the BECOME_SERVER event), we'll respond to PING requests with a PING
25  * response.<p> The FIND_INITIAL_MBRS event will eventually be answered with a
26  * FIND_INITIAL_MBRS_OK event up the stack.
27  * The following properties are available
28  * property: gossip_host - if you are using GOSSIP then this defines the host of the GossipServer, default is null
29  * property: gossip_port - if you are using GOSSIP then this defines the port of the GossipServer, default is null
30  */

31 public class PING extends Discovery {
32     String JavaDoc gossip_host=null;
33     int gossip_port=0;
34     long gossip_refresh=20000; // time in msecs after which the entry in GossipServer will be refreshed
35
GossipClient client;
36     int port_range=1; // number of ports to be probed for initial membership
37
List initial_hosts=null; // hosts to be contacted for the initial membership
38
public static final String JavaDoc name="PING";
39
40
41     public String JavaDoc getName() {
42         return name;
43     }
44
45
46
47     /**
48      * sets the properties of the PING protocol.
49      * The following properties are available
50      * property: timeout - the timeout (ms) to wait for the initial members, default is 3000=3 secs
51      * property: num_initial_members - the minimum number of initial members for a FIND_INITAL_MBRS, default is 2
52      * property: gossip_host - if you are using GOSSIP then this defines the host of the GossipServer, default is null
53      * property: gossip_port - if you are using GOSSIP then this defines the port of the GossipServer, default is null
54      *
55      * @param props - a property set containing only PING properties
56      * @return returns true if all properties were parsed properly
57      * returns false if there are unrecnogized properties in the property set
58      */

59     public boolean setProperties(Properties JavaDoc props) {
60         String JavaDoc str;
61
62         str=props.getProperty("gossip_host");
63         if(str != null) {
64             gossip_host=str;
65             props.remove("gossip_host");
66         }
67
68         str=props.getProperty("gossip_port");
69         if(str != null) {
70             gossip_port=Integer.parseInt(str);
71             props.remove("gossip_port");
72         }
73
74         str=props.getProperty("gossip_refresh");
75         if(str != null) {
76             gossip_refresh=Long.parseLong(str);
77             props.remove("gossip_refresh");
78         }
79
80         if(gossip_host != null && gossip_port != 0) {
81             try {
82                 client=new GossipClient(new IpAddress(InetAddress.getByName(gossip_host), gossip_port), gossip_refresh);
83             }
84             catch(Exception JavaDoc e) {
85                 if(log.isErrorEnabled()) log.error("creation of GossipClient failed, exception=" + e);
86                 return false; // will cause stack creation to abort
87
}
88         }
89
90         str=props.getProperty("port_range"); // if member cannot be contacted on base port,
91
if(str != null) { // how many times can we increment the port
92
port_range=Integer.parseInt(str);
93             if(port_range < 1) {
94                 port_range=1;
95             }
96             props.remove("port_range");
97         }
98
99         str=props.getProperty("initial_hosts");
100         if(str != null) {
101             props.remove("initial_hosts");
102             initial_hosts=createInitialHosts(str);
103         }
104
105         return super.setProperties(props);
106     }
107
108
109     public void stop() {
110         super.stop();
111         if(client != null) {
112             client.stop();
113         }
114     }
115
116
117     public void localAddressSet(Address addr) {
118         // Add own address to initial_hosts if not present: we must always be able to ping ourself !
119
if(initial_hosts != null && local_addr != null) {
120             List hlist;
121             boolean inInitialHosts=false;
122             for(Enumeration JavaDoc en=initial_hosts.elements(); en.hasMoreElements() && !inInitialHosts;) {
123                 hlist=(List)en.nextElement();
124                 if(hlist.contains(local_addr)) {
125                     inInitialHosts=true;
126                 }
127             }
128             if(!inInitialHosts) {
129                 hlist=new List();
130                 hlist.add(local_addr);
131                 initial_hosts.add(hlist);
132                 if(log.isDebugEnabled())
133                     log.debug("adding my address (" + local_addr + ") to initial_hosts; initial_hosts=" + initial_hosts);
134             }
135         }
136     }
137
138
139     public void handleConnect() {
140         if(client != null)
141             client.register(group_addr, local_addr);
142     }
143
144     public void handleDisconnect() {
145         if(client != null)
146             client.stop();
147     }
148
149
150
151     public void sendGetMembersRequest() {
152         Message msg;
153         PingHeader hdr;
154         Vector JavaDoc gossip_rsps=null;
155
156         if(client != null) {
157             gossip_rsps=client.getMembers(group_addr);
158             if(gossip_rsps != null && gossip_rsps.size() > 0) {
159                 // Set a temporary membership in the UDP layer, so that the following multicast
160
// will be sent to all of them
161
Event view_event=new Event(Event.TMP_VIEW, makeView(gossip_rsps));
162                 passDown(view_event); // needed e.g. by failure detector or UDP
163
}
164             else {
165                 passUp(new Event(Event.FIND_INITIAL_MBRS_OK, null));
166                 return;
167             }
168
169             if(gossip_rsps != null && gossip_rsps.size() > 0) {
170                 for(int i=0; i < gossip_rsps.size(); i++) {
171                     Address dest=(Address)gossip_rsps.elementAt(i);
172                     msg=new Message(dest, null, null); // mcast msg
173
msg.putHeader(getName(), new PingHeader(PingHeader.GET_MBRS_REQ, null));
174                     passDown(new Event(Event.MSG, msg));
175                 }
176             }
177
178             Util.sleep(500);
179         }
180         else {
181             if(initial_hosts != null && initial_hosts.size() > 0) {
182                 IpAddress h;
183                 List hlist;
184                 int numMemberInitialHosts;
185                 int numMembers;
186                 Address coord;
187                 msg=new Message(null, null, null);
188                 msg.putHeader(getName(), new PingHeader(PingHeader.GET_MBRS_REQ, null));
189
190                 synchronized(members) {
191                     numMembers=members.size();
192                     numMemberInitialHosts=0;
193                     coord=numMembers > 0 ? (Address)members.firstElement() : local_addr;
194                 }
195                 for(Enumeration JavaDoc en=initial_hosts.elements(); en.hasMoreElements();) {
196                     hlist=(List)en.nextElement();
197                     boolean isMember=false;
198
199 // for(Enumeration hen=hlist.elements(); hen.hasMoreElements() && !isMember && numMemberInitialHosts < numMembers;) {
200
// h=(IpAddress)hen.nextElement();
201
// if(members_set.contains(h)) {
202
// //update the initial_members list for this already connected member
203
// initial_members.add(new PingRsp(h, coord));
204
// isMember=true;
205
// numMemberInitialHosts++;
206
// if(log.isDebugEnabled())
207
// log.debug("[FIND_INITIAL_MBRS] " + h + " is already a member");
208
// }
209
// }
210
for(Enumeration JavaDoc hen=hlist.elements(); hen.hasMoreElements() && !isMember;) {
211                         h=(IpAddress)hen.nextElement();
212                         msg.setDest(h);
213                         if(log.isTraceEnabled())
214                             log.trace("[FIND_INITIAL_MBRS] sending PING request to " + msg.getDest());
215                         passDown(new Event(Event.MSG, msg.copy()));
216                     }
217                 }
218             }
219             else {
220                 // 1. Mcast GET_MBRS_REQ message
221
hdr=new PingHeader(PingHeader.GET_MBRS_REQ, null);
222                 msg=new Message(null, null, null); // mcast msg
223
msg.putHeader(getName(), hdr); // needs to be getName(), so we might get "MPING" !
224
sendMcastDiscoveryRequest(msg);
225             }
226         }
227     }
228
229     void sendMcastDiscoveryRequest(Message discovery_request) {
230         passDown(new Event(Event.MSG, discovery_request));
231     }
232
233     /* -------------------------- Private methods ---------------------------- */
234
235
236
237     /**
238      * Input is "daddy[8880],sindhu[8880],camille[5555]. Return List of IpAddresses
239      */

240     private List createInitialHosts(String JavaDoc l) {
241         List tmp=new List();
242         StringTokenizer JavaDoc tok=new StringTokenizer JavaDoc(l, ",");
243         String JavaDoc t;
244
245         while(tok.hasMoreTokens()) {
246             try {
247                 t=tok.nextToken();
248                 String JavaDoc host=t.substring(0, t.indexOf('['));
249                 int port=Integer.parseInt(t.substring(t.indexOf('[') + 1, t.indexOf(']')));
250                 List hosts=new List();
251                 for(int i=port; i < port + port_range; i++) {
252                     hosts.add(new IpAddress(host, i));
253                 }
254                 tmp.add(hosts);
255             }
256             catch(NumberFormatException JavaDoc e) {
257                 if(log.isErrorEnabled()) log.error("exeption is " + e);
258             }
259         }
260         return tmp;
261     }
262
263
264 }
265
Popular Tags