KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > tribe > gms > JGroupsMembershipService


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): ______________________.
23  */

24
25 package org.objectweb.tribe.gms;
26
27 import java.net.URL JavaDoc;
28 import java.util.Vector JavaDoc;
29
30 import org.jgroups.ChannelClosedException;
31 import org.jgroups.JChannel;
32 import org.jgroups.MembershipListener;
33 import org.jgroups.View;
34 import org.objectweb.tribe.channel.ReliableGroupChannelWithGms;
35 import org.objectweb.tribe.common.Group;
36 import org.objectweb.tribe.common.GroupIdentifier;
37 import org.objectweb.tribe.common.IpAddress;
38 import org.objectweb.tribe.common.Member;
39 import org.objectweb.tribe.exceptions.AlreadyMemberException;
40 import org.objectweb.tribe.exceptions.ChannelException;
41 import org.objectweb.tribe.exceptions.NotConnectedException;
42
43 /**
44  * This class defines a JGroupsMembershipService
45  *
46  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
47  * @version 1.0
48  */

49 public class JGroupsMembershipService extends GroupMembershipService
50     implements
51       MembershipListener
52 {
53   // The underlying JGroups channel with GMS
54
private JChannel jgroupsChannel;
55   private GroupIdentifier currentGroup;
56
57   /**
58    * Creates a new <code>JGroupsMembershipService</code> object
59    *
60    * @param jgroupsConfigFile JGroups configuration file
61    */

62   public JGroupsMembershipService(URL JavaDoc jgroupsConfigFile)
63       throws ChannelException
64   {
65     super(null, null, null);
66     try
67     {
68       jgroupsChannel = new JChannel(jgroupsConfigFile);
69     }
70     catch (org.jgroups.ChannelException e)
71     {
72       throw new ChannelException(e);
73     }
74   }
75
76   /**
77    * Gets underlying JGroups channel.
78    *
79    * @return the JGroups channel
80    */

81   public JChannel getJGroupsChannel()
82   {
83     return jgroupsChannel;
84   }
85
86   /**
87    * @see org.objectweb.tribe.gms.GroupMembershipService#join(org.objectweb.tribe.channel.ReliableGroupChannelWithGms,
88    * org.objectweb.tribe.common.GroupIdentifier)
89    */

90   public Member join(ReliableGroupChannelWithGms channel, GroupIdentifier gid)
91       throws AlreadyMemberException, NotConnectedException, ChannelException
92   {
93     Member me;
94     Group g;
95     synchronized (groupMemberships)
96     {
97       try
98       {
99         jgroupsChannel.connect(gid.getGroupName());
100         currentGroup = gid;
101       }
102       catch (ChannelClosedException e)
103       {
104         throw new NotConnectedException(e);
105       }
106       catch (org.jgroups.ChannelException e)
107       {
108         throw new ChannelException(e);
109       }
110
111       g = getGroup(currentGroup);
112       me = memberFromJGroupsAddress((org.jgroups.stack.IpAddress) jgroupsChannel
113           .getLocalAddress());
114       if (g == null)
115       { // Group does not exist, create it
116
g = new Group(currentGroup);
117         groupMemberships.put(gid, g);
118       }
119       else
120         throw new AlreadyMemberException();
121
122       // Add ourselves to the group
123
g.addMember(me);
124     }
125
126     // Notify listeners
127
synchronized (listeners)
128     {
129       int size = listeners.size();
130       for (int i = 0; i < size; i++)
131         ((GroupMembershipListener) listeners.get(i)).joinMember(me, gid);
132     }
133
134     return me;
135   }
136
137   /**
138    * @see org.objectweb.tribe.gms.GroupMembershipService#quit(org.objectweb.tribe.channel.ReliableGroupChannelWithGms,
139    * org.objectweb.tribe.common.GroupIdentifier)
140    */

141   public void quit(ReliableGroupChannelWithGms channel, GroupIdentifier gid)
142       throws ChannelException, NotConnectedException
143   {
144     super.quit(channel, gid);
145
146     jgroupsChannel.disconnect();
147   }
148
149   //
150
// JGroups MembershipListener interface implementation
151
//
152

153   /**
154    * Returns a tribe Member object from a JGroups address (supposed to be an
155    * IpAddress).
156    *
157    * @param jgroupsAddress the JGroups address
158    * @return a tribe Member corresponding to this JGroups address
159    */

160   public static Member memberFromJGroupsAddress(
161       org.jgroups.stack.IpAddress jgroupsAddress)
162   {
163     return new Member(new IpAddress(jgroupsAddress.getIpAddress(),
164         jgroupsAddress.getPort()), jgroupsAddress.getIpAddress().toString()
165         + ":" + jgroupsAddress.getPort());
166   }
167
168   /**
169    * @see org.jgroups.MembershipListener#viewAccepted(org.jgroups.View)
170    */

171   public void viewAccepted(View newView)
172   {
173     // There is an issue here that was present in Tribe v0.2.
174
// When we call toString on newView (only happened in debug mode before), it
175
// implies a call on toString for each member which is in fact a JGroups
176
// IpAddress. IdAddress.toString() has a side effect in that it calls the
177
// underlying JDK hostname resolution that changes the content of the
178
// address. If we do not force the resolution here, the local member will
179
// appear twice in the group membership once with its non-resolved and later
180
// once again with its resolved name .
181
String JavaDoc jGroupsBugWorkAroundDoNotRemoveThisStringRepresentationOfTheView = newView
182         .toString();
183     if (logger.isDebugEnabled())
184       logger.debug("JGroups reported new view: "
185           + jGroupsBugWorkAroundDoNotRemoveThisStringRepresentationOfTheView);
186
187     Vector JavaDoc members = newView.getMembers();
188     int size = members.size();
189     synchronized (groupMemberships)
190     {
191       Group g = getGroup(currentGroup);
192       for (int i = 0; i < size; i++)
193       {
194         Member m = memberFromJGroupsAddress((org.jgroups.stack.IpAddress) members
195             .get(i));
196         if (!g.hasMember(m)) // Add new member
197
joinMember(m, currentGroup);
198       }
199     }
200   }
201
202   /**
203    * @see org.jgroups.MembershipListener#suspect(org.jgroups.Address)
204    */

205   public void suspect(org.jgroups.Address suspectedMbr)
206   {
207     if (logger.isDebugEnabled())
208       logger.debug("JGroups reports suspected member:" + suspectedMbr);
209     org.jgroups.stack.IpAddress jgroupsAddress = (org.jgroups.stack.IpAddress) suspectedMbr;
210     quitMember(memberFromJGroupsAddress(jgroupsAddress), currentGroup);
211   }
212
213   /**
214    * @see org.jgroups.MembershipListener#block()
215    */

216   public void block()
217   {
218     if (logger.isDebugEnabled())
219       logger.debug("JGroups reported block()");
220   }
221
222 }
Popular Tags