001: // $Id: TCPPING.java,v 1.28.2.1 2007/04/27 08:03:52 belaban Exp $
002:
003: package org.jgroups.protocols;
004:
005: import org.jgroups.Address;
006: import org.jgroups.Event;
007: import org.jgroups.Message;
008: import org.jgroups.Global;
009: import org.jgroups.util.Util;
010: import org.jgroups.stack.IpAddress;
011:
012: import java.util.*;
013: import java.net.UnknownHostException;
014:
015: /**
016: * The TCPPING protocol layer retrieves the initial membership in answer to the GMS's
017: * FIND_INITIAL_MBRS event. The initial membership is retrieved by directly contacting other group
018: * members, sending point-to-point mebership requests. The responses should allow us to determine
019: * the coordinator whom we have to contact in case we want to join the group. When we are a server
020: * (after having received the BECOME_SERVER event), we'll respond to TCPPING requests with a TCPPING
021: * response.
022: * <p>
023: * The FIND_INITIAL_MBRS event will eventually be answered with a FIND_INITIAL_MBRS_OK event up
024: * the stack.
025: * <p>
026: * The TCPPING protocol requires a static conifiguration, which assumes that you to know in advance
027: * where to find other members of your group. For dynamic discovery, use the PING protocol, which
028: * uses multicast discovery, or the TCPGOSSIP protocol, which contacts a Gossip Router to acquire
029: * the initial membership.
030: *
031: * @author Bela Ban
032: */
033: public class TCPPING extends Discovery {
034: int port_range = 1; // number of ports to be probed for initial membership
035:
036: /** List<IpAddress> */
037: ArrayList initial_hosts = null; // hosts to be contacted for the initial membership
038: final static String name = "TCPPING";
039:
040: public String getName() {
041: return name;
042: }
043:
044: public boolean setProperties(Properties props) {
045: String str;
046: this .props.putAll(props); // redundant
047:
048: str = props.getProperty("port_range"); // if member cannot be contacted on base port,
049: if (str != null) { // how many times can we increment the port
050: port_range = Integer.parseInt(str);
051: if (port_range < 1) {
052: port_range = 1;
053: }
054: props.remove("port_range");
055: }
056:
057: str = Util.getProperty(
058: new String[] { Global.TCPPING_INITIAL_HOSTS }, props,
059: "initial_hosts", false, null);
060: if (str != null) {
061: props.remove("initial_hosts");
062: try {
063: initial_hosts = createInitialHosts(str);
064: } catch (UnknownHostException e) {
065: log.error("failed creating initial list of hosts", e);
066: return false;
067: }
068: }
069:
070: return super .setProperties(props);
071: }
072:
073: public void localAddressSet(Address addr) {
074: // Add own address to initial_hosts if not present: we must always be able to ping ourself !
075: if (initial_hosts != null && addr != null) {
076: if (initial_hosts.contains(addr)) {
077: initial_hosts.remove(addr);
078: if (log.isDebugEnabled())
079: log
080: .debug("[SET_LOCAL_ADDRESS]: removing my own address ("
081: + addr
082: + ") from initial_hosts; initial_hosts="
083: + initial_hosts);
084: }
085: }
086: }
087:
088: public void sendGetMembersRequest() {
089: Message msg;
090:
091: for (Iterator it = initial_hosts.iterator(); it.hasNext();) {
092: Address addr = (Address) it.next();
093: // if(tmpMbrs.contains(addr)) {
094: // ; // continue; // changed as suggested by Mark Kopec
095: // }
096: msg = new Message(addr, null, null);
097: msg.putHeader(name, new PingHeader(PingHeader.GET_MBRS_REQ,
098: null));
099:
100: if (log.isTraceEnabled())
101: log
102: .trace("[FIND_INITIAL_MBRS] sending PING request to "
103: + msg.getDest());
104: passDown(new Event(Event.MSG, msg));
105: }
106: }
107:
108: /* -------------------------- Private methods ---------------------------- */
109:
110: /**
111: * Input is "daddy[8880],sindhu[8880],camille[5555]. Return List of IpAddresses
112: */
113: private ArrayList createInitialHosts(String l)
114: throws UnknownHostException {
115: StringTokenizer tok = new StringTokenizer(l, ",");
116: String t;
117: IpAddress addr;
118: ArrayList retval = new ArrayList();
119:
120: while (tok.hasMoreTokens()) {
121: try {
122: t = tok.nextToken().trim();
123: String host = t.substring(0, t.indexOf('['));
124: host = host.trim();
125: int port = Integer.parseInt(t.substring(
126: t.indexOf('[') + 1, t.indexOf(']')));
127: for (int i = port; i < port + port_range; i++) {
128: addr = new IpAddress(host, i);
129: retval.add(addr);
130: }
131: } catch (NumberFormatException e) {
132: if (log.isErrorEnabled())
133: log.error("exeption is " + e);
134: }
135: }
136:
137: return retval;
138: }
139:
140: }
|