1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package jgroup.relacs.config;
20
21 import static jgroup.util.log.ReplicaEvent.Type.Created;
22
23 import java.io.Serializable;
24 import java.lang.reflect.UndeclaredThrowableException;
25 import java.net.InetAddress;
26 import java.net.UnknownHostException;
27 import java.rmi.AccessException;
28 import java.rmi.NotBoundException;
29 import java.rmi.Remote;
30 import java.rmi.RemoteException;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.Map;
36 import java.util.Set;
37
38 import jgroup.core.arm.ExecException;
39 import jgroup.core.arm.ExecService;
40 import jgroup.core.registry.BootstrapRegistry;
41 import jgroup.relacs.types.EndPointImpl;
42 import jgroup.util.log.Eventlogger;
43 import jgroup.util.log.ReplicaEvent;
44
45 import org.apache.log4j.Logger;
46
47
48
49
50
51
52
53
54
55 public class Host
56 extends EndPointImpl
57 implements Iterable<AppConfig>
58 {
59
60
61
62
63
64
65 private static final Logger log = Logger.getLogger(Host.class);
66
67
68
69
70
71
72 private static final long serialVersionUID = 5712317513876955415L;
73
74
75
76
77
78 private static final String EXEC_DAEMON = "ExecDaemon";
79
80
81
82
83 public enum ReplicaState { FAILED_CREATION, JOIN_PENDING, NORMAL, REMOVE_PENDING }
84
85
86
87
88
89
90
91 private String hostName;
92
93
94 private Domain domain;
95
96
97 private String fqdn;
98
99
100 private final Map<String,Object> content = new HashMap<String,Object>();
101
102
103 private final Set<AppConfig> replicas = Collections.synchronizedSet(new HashSet<AppConfig>());
104
105
106 private final Map<AppConfig,ReplicaState> appReplicaState = new HashMap<AppConfig,ReplicaState>();
107
108
109
110
111
112
113
114
115
116 public Host()
117 {
118
119 fqdn = getAddress().getCanonicalHostName();
120 }
121
122
123
124
125
126
127
128 public Host(String hostName, Domain domain, int port)
129 throws UnknownHostException
130 {
131 this(getFQDN(hostName, domain), port);
132 this.hostName = hostName;
133 this.domain = domain;
134
135
136
137
138
139 if (local)
140 domain.setLocal(true);
141 }
142
143
144
145
146
147
148 private Host(String fqdn, int port)
149 throws UnknownHostException
150 {
151 super(InetAddress.getByName(fqdn), port);
152 this.fqdn = fqdn;
153 }
154
155
156
157
158
159
160
161 private static String getFQDN(String hostName, Domain domain)
162 {
163 String fqdn = hostName;
164 String domainName = domain.getName();
165 if (!(fqdn.indexOf(".") > -1) && !domainName.equals(""))
166 fqdn += "." + domainName;
167 return fqdn;
168 }
169
170
171
172
173
174
175
176
177
178
179 public String getCanonicalHostName()
180 {
181 return fqdn;
182 }
183
184
185
186
187
188
189 public String getHostName()
190 {
191 return hostName;
192 }
193
194
195
196
197
198
199 public String getDomainName()
200 {
201 return domain.getName();
202 }
203
204
205
206
207
208
209 public Domain getDomain()
210 {
211 return domain;
212 }
213
214
215
216
217
218 public Iterator<AppConfig> iterator()
219 {
220 return replicas.iterator();
221 }
222
223 public boolean contains(AppConfig app)
224 {
225 return replicas.contains(app);
226 }
227
228 public int replicaCount()
229 {
230 return replicas.size();
231 }
232
233
234
235
236
237
238 public void assign(AppConfig app)
239 {
240 replicas.add(app);
241 }
242
243 public void remove(AppConfig app)
244 {
245 replicas.remove(app);
246 }
247
248
249
250
251
252
253
254
255
256 public Object get(String key)
257 {
258 return content.get(key);
259 }
260
261
262
263
264
265 public Object put(String key, Object value)
266 {
267 return content.put(key, value);
268 }
269
270 public Map<String,Object> getContentMap()
271 {
272 Map<String,Object> xferContent = new HashMap<String,Object>(content);
273 for (Iterator iter = xferContent.values().iterator(); iter.hasNext();) {
274 Object obj = (Object) iter.next();
275 if (!(obj instanceof Serializable))
276 iter.remove();
277 }
278 return xferContent;
279 }
280
281 public void setContentMap(Map<String,Object> c)
282 {
283 this.content.putAll(c);
284 }
285
286
287
288
289
290
291
292
293
294 public boolean isAvailable()
295 {
296 ExecService execRef = getExecDaemon();
297 content.put(EXEC_DAEMON, execRef);
298 return (execRef != null);
299 }
300
301
302
303
304 public void suspect()
305 {
306 isAvailable();
307 }
308
309
310
311
312
313 public boolean ping()
314 {
315 if (isAvailable()) {
316 ExecService execRef = getExecRef();
317 try {
318 execRef.ping();
319 return true;
320 } catch (RemoteException e) {
321 log.warn("ping failed: " + execRef, e);
322 }
323 }
324 return false;
325 }
326
327 public Remote lookup(String name)
328 throws AccessException, UnknownHostException, RemoteException, NotBoundException
329 {
330 return BootstrapRegistry.lookup(fqdn, name);
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344
345 private ExecService getExecRef()
346 {
347 ExecService execRef = (ExecService) content.get(EXEC_DAEMON);
348 if (execRef == null) {
349 execRef = getExecDaemon();
350 content.put(EXEC_DAEMON, execRef);
351 }
352 return execRef;
353 }
354
355
356
357
358
359
360
361
362
363
364
365
366 private ExecService getExecDaemon()
367 {
368
369
370 try {
371 return (ExecService) lookup(ExecService.EXEC_DAEMON_NAME);
372
373 } catch (RemoteException exception) {
374 if (log.isDebugEnabled())
375 log.debug("Host " + fqdn + " is unavailable");
376 return null;
377 } catch (NotBoundException exception) {
378 if (log.isDebugEnabled())
379 log.debug("The ExecDaemon is not running on host " + fqdn);
380 return null;
381 } catch (UnknownHostException e) {
382 if (log.isDebugEnabled())
383 log.debug("Host " + fqdn + " is unknown", e);
384 return null;
385 }
386 }
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401 public boolean createReplica(AppConfig app)
402 {
403 ExecService exec = getExecRef();
404 if (exec == null) {
405 log.warn("Execution service unavailable on " + this);
406 appReplicaState.put(app, ReplicaState.FAILED_CREATION);
407 return false;
408 }
409
410 ClassData cdata = app.getClassData();
411 boolean created = false;
412 try {
413 if (app.startInExecJVM()) {
414 created = exec.createExecReplica(cdata);
415 } else {
416 created = exec.createReplica(cdata);
417 }
418 if (created) {
419 appReplicaState.put(app, ReplicaState.JOIN_PENDING);
420 log.info(cdata.getShortName() +" replica successfully created on " + this);
421 if (Eventlogger.ENABLED)
422 Eventlogger.logEventFlush(new ReplicaEvent(Created, app.getGroupId(), this.address));
423 } else {
424 ReplicaState state = getState(app);
425 log.info(cdata.getShortName() +" replica already created on " + this + ", state: " + state);
426
427 created = true;
428 }
429 } catch (UndeclaredThrowableException e) {
430 log.warn("Failed to create replica "+ cdata.getShortName() +" on: "+ this, e);
431 } catch (RemoteException re) {
432 log.warn("Failed to create replica "+ cdata.getShortName() +" on: "+ this, re);
433 } catch (ExecException ex) {
434 if (log.isDebugEnabled()) {
435 log.debug(ex.getMessage());
436 Throwable e = ex.getCause();
437 if (e != null)
438 log.warn(e.getMessage());
439 }
440 }
441 if (!created) {
442 appReplicaState.put(app, ReplicaState.FAILED_CREATION);
443 }
444 return created;
445 }
446
447
448
449
450
451
452
453
454
455
456
457
458 public boolean removeReplica(AppConfig app)
459 {
460
461
462 ExecService exec = getExecRef();
463 if (exec == null) {
464 if (log.isDebugEnabled())
465 log.debug("Execution service unavailable on " + this);
466 return false;
467 }
468
469 ClassData cdata = app.getClassData();
470 try {
471 boolean removed = exec.removeReplica(cdata);
472 if (log.isDebugEnabled()) {
473 if (removed) {
474 log.info(cdata.getShortName() +" replica successfully removed on " + this);
475 } else {
476 log.info(cdata.getShortName() +" replica already removed on " + this);
477 }
478 }
479 } catch (UndeclaredThrowableException e) {
480 log.warn("Failed to remove replica "+ cdata.getShortName() +" on: "+ this, e);
481 return false;
482 } catch (RemoteException re) {
483 log.warn("Failed to remove replica "+ cdata.getShortName() +" on: "+ this, re);
484 return false;
485 }
486
487
488 appReplicaState.put(app, ReplicaState.REMOVE_PENDING);
489 return true;
490 }
491
492
493
494
495
496 public Set<ClassData> queryReplicas()
497 {
498 ExecService exec = getExecRef();
499 if (exec == null) {
500 if (log.isDebugEnabled())
501 log.debug("Execution service unavailable on " + this);
502 return new HashSet<ClassData>(0);
503 }
504 try {
505 return exec.queryReplicas();
506 } catch (RemoteException e) {
507 log.warn("Could not access the execution service on " + this, e);
508 return new HashSet<ClassData>(0);
509 }
510 }
511
512
513
514
515 public boolean isJoining(AppConfig app)
516 {
517 ReplicaState state = appReplicaState.get(app);
518 if (state == null)
519 return false;
520 else
521 return state.equals(ReplicaState.JOIN_PENDING);
522 }
523
524
525
526
527 public ReplicaState getState(AppConfig app)
528 {
529 return appReplicaState.get(app);
530 }
531
532
533
534
535 public void viewChange(AppConfig app)
536 {
537 appReplicaState.put(app, ReplicaState.NORMAL);
538 }
539
540
541
542
543 public void shutdown(int delay)
544 {
545 ExecService exec = getExecDaemon();
546 if (exec == null) {
547 if (log.isDebugEnabled())
548 log.debug("Execution service unavailable on " + this);
549 return;
550 }
551 try {
552 exec.shutdown(delay);
553 } catch (RemoteException e) {
554 log.warn("Could not access the execution service on " + this, e);
555 }
556 }
557
558 }