1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package jgroup.relacs.registry;
20
21 import java.rmi.NotBoundException;
22 import java.rmi.RemoteException;
23
24 import jgroup.core.ExternalGMIListener;
25 import jgroup.core.ExternalGMIService;
26 import jgroup.core.IID;
27 import jgroup.core.JgroupException;
28 import jgroup.core.MembershipListener;
29 import jgroup.core.MembershipService;
30 import jgroup.core.View;
31 import jgroup.core.registry.DependableRegistry;
32 import jgroup.core.registry.RegistryFactory;
33 import jgroup.core.registry.RegistryService;
34 import jgroup.relacs.config.AppConfig;
35
36 import org.apache.log4j.Logger;
37
38
39
40
41
42
43
44
45
46
47
48 public class RegistryLayer
49 implements RegistryService, MembershipListener
50 {
51
52
53
54
55
56
57 private static final Logger log = Logger.getLogger(RegistryLayer.class);
58
59
60
61
62
63
64
65 private ExternalGMIService egmis;
66
67
68 private IID iid = null;
69
70
71 private Object server = null;
72
73
74 private AppConfig thisApp;
75
76
77 private long leaseTime = -1;
78
79
80 private Thread shutdownHook = null;
81
82
83
84
85
86
87 private RegistryLayer(ExternalGMIService egmis)
88 {
89 this.egmis = egmis;
90 }
91
92 public static RegistryLayer getLayer(ExternalGMIService egmis, MembershipService pgms)
93 {
94 return new RegistryLayer(egmis);
95 }
96
97
98
99
100
101
102
103
104
105
106 public void addListener(Object listener)
107 {
108 if (listener == null)
109 throw new NullPointerException("No replica specified for the registry layer.");
110 this.server = listener;
111
112 thisApp = AppConfig.getApplication(server);
113 if (thisApp.hasService("LeaseRefresh")) {
114 leaseTime = thisApp.getIntParam("LeaseRefresh.leaseTime", DEFAULT_LEASE_TIME);
115 }
116
117
118
119
120
121
122
123 if (!thisApp.hasService("LeaseRefresh") && !thisApp.hasService("NotifyRefresh")) {
124
125
126
127
128
129 shutdownHook = new Thread("RegistryLayer-ShutdownHook") {
130 public void run() {
131 doUnbind();
132 }};
133 }
134 }
135
136
137
138
139
140
141 public IID bind()
142 throws RemoteException, JgroupException
143 {
144 return bind(server);
145 }
146
147 public IID bind(Object server)
148 throws RemoteException, JgroupException
149 {
150 String name = AppConfig.getApplication(server).getRegistryName();
151 return bind(name, server);
152 }
153
154 public IID bind(String name, Object server)
155 throws RemoteException, JgroupException
156 {
157 DependableRegistry registry = RegistryFactory.getRegistry();
158 return bind(name, server, registry);
159 }
160
161 public IID bind(String name, Object server, DependableRegistry registry)
162 throws RemoteException, JgroupException
163 {
164 if (server == null)
165 throw new NullPointerException("Server is null; cannot bind");
166 Class serverClass = server.getClass();
167 if (!ExternalGMIListener.class.isAssignableFrom(serverClass))
168 throw new JgroupException("Cannot bind server since it does not implement an external GMI interface");
169 return registry.bind(name, egmis.getRegistryEntry(name), serverClass, leaseTime);
170 }
171
172 public void unbind()
173 throws RemoteException, NotBoundException, JgroupException
174 {
175 if (iid == null)
176 throw new NullPointerException("Cannot unbind(null)");
177 unbind(iid);
178 }
179
180 public void unbind(IID bid)
181 throws RemoteException, NotBoundException, JgroupException
182 {
183 DependableRegistry registry = RegistryFactory.getRegistry();
184 unbind(bid, registry);
185 }
186
187 public void unbind(IID bid, DependableRegistry registry)
188 throws RemoteException, NotBoundException
189 {
190 if (shutdownHook != null) {
191
192 Runtime.getRuntime().removeShutdownHook(shutdownHook);
193 }
194 registry.unbind(bid);
195 }
196
197 public void refreshLease()
198 throws RemoteException, JgroupException
199 {
200 DependableRegistry registry = RegistryFactory.getRegistry();
201 try {
202 registry.refresh(iid);
203 } catch (NotBoundException nbe) {
204 log.warn(nbe.getMessage());
205 }
206 }
207
208 public IID getIID()
209 throws NullPointerException
210 {
211 if (iid == null)
212 throw new NullPointerException("iid is null; Replica not yet bound to the dependable registry.");
213 return iid;
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 public void viewChange(View view)
233 {
234 if (iid == null &&
235 thisApp.getBooleanParam("Registry.auto") &&
236 view.size() == thisApp.getInitialRedundancy()) {
237
238
239
240
241 new Thread("BindThread-" + thisApp.getGroupId()) {
242 public void run() {
243 try {
244 if (log.isDebugEnabled())
245 log.debug("Group is fully replicated; auto binding with registry");
246 iid = bind();
247 if (log.isDebugEnabled())
248 log.debug("Successfully bound: " + thisApp.getRegistryName());
249 if (shutdownHook != null) {
250
251
252
253
254 Runtime.getRuntime().addShutdownHook(shutdownHook);
255 }
256 } catch (Exception e) {
257 log.error("Unable to bind " + thisApp.getRegistryName() + " to the dependable registry", e);
258 }
259 }
260 }.start();
261 }
262 }
263
264
265
266
267 public void prepareChange() {}
268
269
270
271
272 public void hasLeft()
273 {
274 doUnbind();
275 }
276
277
278
279
280 private void doUnbind()
281 {
282
283 if (iid == null)
284 return;
285 try {
286
287 unbind(iid);
288 if (log.isDebugEnabled())
289 log.debug("Replica was unbound from registry: " + iid);
290 } catch (Exception e) {
291 log.warn("Failed to unbind replica from registry", e);
292 }
293 }
294
295 }