1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.metricshub.wbem.sblim.cimclient.discovery;
25
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Locale;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.logging.Level;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 import javax.security.auth.Subject;
57 import org.metricshub.wbem.javax.wbem.client.WBEMClient;
58 import org.metricshub.wbem.sblim.cimclient.internal.logging.LogAndTraceBroker;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class AdvertisementCatalog {
74
75
76
77
78
79
80
81 public static interface EventListener {
82
83
84
85
86
87
88
89
90
91
92
93
94 public void advertisementEvent(int pEvent, WBEMServiceAdvertisement pAdvertisment);
95 }
96
97
98
99
100
101
102
103
104 private static class AdvertisementDecorator implements WBEMServiceAdvertisement {
105 private WBEMServiceAdvertisement iAdvertisement;
106
107 private boolean iRefresh = false;
108
109
110
111
112
113
114
115 protected AdvertisementDecorator(WBEMServiceAdvertisement pAdvertisement) {
116 if (pAdvertisement == null) throw new IllegalArgumentException("Advertisement is null");
117 this.iAdvertisement = pAdvertisement;
118 }
119
120
121
122
123
124
125 protected WBEMServiceAdvertisement getAdvertisementXXX() {
126 return this.iAdvertisement;
127 }
128
129
130
131
132
133
134 protected boolean isRefresh() {
135 return this.iRefresh;
136 }
137
138
139
140
141
142
143
144 protected void setAdvertisement(WBEMServiceAdvertisement pAdvertisement) {
145 this.iAdvertisement = pAdvertisement;
146 }
147
148
149
150
151
152
153
154 protected void setRefresh(boolean pRefresh) {
155 this.iRefresh = pRefresh;
156 }
157
158
159
160
161
162
163 @Override
164 public boolean equals(Object pObj) {
165 return this.iAdvertisement.equals(pObj);
166 }
167
168
169
170
171
172
173 @Override
174 public int hashCode() {
175 return this.iAdvertisement.hashCode();
176 }
177
178
179
180
181 public WBEMClient createClient(Subject pSubject, Locale[] pLocales) throws Exception {
182 return this.iAdvertisement.createClient(pSubject, pLocales);
183 }
184
185
186
187
188 public String getAttribute(String pAttributeName) {
189 return this.iAdvertisement.getAttribute(pAttributeName);
190 }
191
192
193
194
195 public Set<Map.Entry<String, String>> getAttributes() {
196 return this.iAdvertisement.getAttributes();
197 }
198
199
200
201
202 public String getConcreteServiceType() {
203 return this.iAdvertisement.getConcreteServiceType();
204 }
205
206
207
208
209 public String getDirectory() {
210 return this.iAdvertisement.getDirectory();
211 }
212
213
214
215
216 public String[] getInteropNamespaces() {
217 return this.iAdvertisement.getInteropNamespaces();
218 }
219
220
221
222
223 public String getServiceId() {
224 return this.iAdvertisement.getServiceId();
225 }
226
227
228
229
230 public String getServiceUrl() {
231 return this.iAdvertisement.getServiceUrl();
232 }
233
234
235
236
237 public boolean isExpired() {
238 return this.iAdvertisement.isExpired();
239 }
240
241
242
243
244 public void setExpired(boolean pExpired) {
245 this.iAdvertisement.setExpired(pExpired);
246 }
247 }
248
249
250
251
252 public static int EVENT_ADD = 1;
253
254
255
256
257 public static int EVENT_REMOVE = 2;
258
259
260
261
262 public static int EVENT_EXPIRE = 4;
263
264
265
266
267 public static int EVENT_RENEW = 8;
268
269 private List<EventListener> iListeners = new LinkedList<EventListener>();
270
271 private HashMap<String, List<AdvertisementDecorator>> iCatalogByDirectory = new HashMap<String, List<AdvertisementDecorator>>();
272
273 private Map<String, Map<WBEMProtocol, WBEMServiceAdvertisement>> iCatalogById = new HashMap<String, Map<WBEMProtocol, WBEMServiceAdvertisement>>();
274
275
276
277
278 public AdvertisementCatalog() {
279
280 }
281
282
283
284
285
286
287
288
289 public void addEventListener(EventListener pListener) {
290 this.iListeners.add(pListener);
291 }
292
293
294
295
296
297
298
299
300 public void addAdvertisements(WBEMServiceAdvertisement[] pAdvertisements) {
301 for (int i = 0; i < pAdvertisements.length; ++i) {
302 String url = "";
303 try {
304 WBEMServiceAdvertisement advertisement = pAdvertisements[i];
305 url = advertisement.getServiceUrl();
306 WBEMProtocol protocol = makeProtocol(advertisement);
307 String serviceId = advertisement.getAttribute(WBEMServiceAdvertisement.SERVICE_ID);
308 {
309 List<AdvertisementDecorator> innerList = this.iCatalogByDirectory.get(advertisement.getDirectory());
310 if (innerList == null) {
311 innerList = new ArrayList<AdvertisementDecorator>();
312 this.iCatalogByDirectory.put(advertisement.getDirectory(), innerList);
313 }
314 AdvertisementDecorator entry = findAdvertisement(innerList, advertisement);
315 if (entry != null) {
316 boolean wasExpired = entry.isExpired();
317 entry.setAdvertisement(advertisement);
318 entry.setRefresh(false);
319 entry.setExpired(false);
320 if (wasExpired) {
321 notifyEventListeners(EVENT_RENEW, advertisement);
322 }
323 } else {
324 innerList.add(new AdvertisementDecorator(advertisement));
325 notifyEventListeners(EVENT_ADD, advertisement);
326 }
327 }
328 {
329 Map<WBEMProtocol, WBEMServiceAdvertisement> innerMap = this.iCatalogById.get(serviceId);
330 if (innerMap == null) {
331 innerMap = new HashMap<WBEMProtocol, WBEMServiceAdvertisement>();
332 this.iCatalogById.put(serviceId, innerMap);
333 }
334 innerMap.put(protocol, advertisement);
335 }
336 } catch (Exception e) {
337 LogAndTraceBroker.getBroker().trace(Level.FINE, "Incomplete advertisement for" + url, e);
338 }
339 }
340 }
341
342
343
344
345
346
347
348
349
350
351
352
353
354 public WBEMServiceAdvertisement getAdvertisement(final String pId, final WBEMProtocol[] pProtocols) {
355 Map<WBEMProtocol, WBEMServiceAdvertisement> innerMap = this.iCatalogById.get(pId);
356 if (innerMap == null) {
357 return null;
358 }
359 for (int i = 0; i < pProtocols.length; ++i) {
360 WBEMServiceAdvertisement advertisement = innerMap.get(pProtocols[i]);
361 if (advertisement != null) {
362 return advertisement;
363 }
364 }
365 return null;
366 }
367
368
369
370
371
372
373
374
375
376 public WBEMServiceAdvertisement[] getAdvertisementsByDirectory(String pDirectory) {
377 List<AdvertisementDecorator> result = this.iCatalogByDirectory.get(pDirectory);
378 return (
379 result != null
380 ? (WBEMServiceAdvertisement[]) result.toArray(new WBEMServiceAdvertisement[result.size()])
381 : new WBEMServiceAdvertisement[] {}
382 );
383 }
384
385
386
387
388
389
390
391
392 public WBEMServiceAdvertisement[] getAdvertisementsById(String pId) {
393 Map<WBEMProtocol, WBEMServiceAdvertisement> innerMap = this.iCatalogById.get(pId);
394 if (innerMap == null) {
395 return null;
396 }
397 Collection<WBEMServiceAdvertisement> advertisements = innerMap.values();
398 return advertisements.toArray(new WBEMServiceAdvertisement[advertisements.size()]);
399 }
400
401
402
403
404
405
406 public String[] getKnownIds() {
407 Set<String> ids = this.iCatalogById.keySet();
408 return ids.toArray(new String[ids.size()]);
409 }
410
411
412
413
414
415
416
417
418
419
420
421 public void refreshAdvertisements(final String[] pDirectory, WBEMServiceAdvertisement[] pAdvertisements) {
422 for (int i = 0; i < pDirectory.length; ++i) {
423 markRefresh(pDirectory[i]);
424 }
425 addAdvertisements(pAdvertisements);
426 for (int i = 0; i < pDirectory.length; ++i) {
427 expire(pDirectory[i]);
428 }
429 }
430
431
432
433
434
435
436
437 public void removeEventListener(EventListener pListener) {
438 this.iListeners.remove(pListener);
439 }
440
441
442
443
444
445
446
447
448
449 public void removeExpired(String pDirectory) {
450 if (pDirectory == null) {
451 Iterator<String> iter = this.iCatalogByDirectory.keySet().iterator();
452 while (iter.hasNext()) {
453 removeExpired(iter.next());
454 }
455 return;
456 }
457
458 List<AdvertisementDecorator> advertisementList = this.iCatalogByDirectory.get(pDirectory);
459 Iterator<AdvertisementDecorator> iter = advertisementList.iterator();
460 while (iter.hasNext()) {
461 AdvertisementDecorator decorator = iter.next();
462 if (decorator.isExpired()) {
463 iter.remove();
464 notifyEventListeners(EVENT_REMOVE, decorator);
465 Map<WBEMProtocol, WBEMServiceAdvertisement> innerMap = this.iCatalogById.get(decorator.getServiceId());
466 innerMap.remove(makeProtocol(decorator));
467 }
468 }
469 }
470
471
472
473
474
475
476 @Override
477 public String toString() {
478 StringBuffer result = new StringBuffer();
479 result.append("AdvertisementCatalog:");
480 Iterator<Map.Entry<String, Map<WBEMProtocol, WBEMServiceAdvertisement>>> outer =
481 this.iCatalogById.entrySet().iterator();
482 while (outer.hasNext()) {
483 Map.Entry<String, Map<WBEMProtocol, WBEMServiceAdvertisement>> entry = outer.next();
484 if (entry.getValue() == null) {
485 continue;
486 }
487 result.append("[service-id:\"");
488 result.append(entry.getKey());
489 result.append("\"");
490 Map<WBEMProtocol, WBEMServiceAdvertisement> innerMap = entry.getValue();
491 Iterator<Map.Entry<WBEMProtocol, WBEMServiceAdvertisement>> inner = innerMap.entrySet().iterator();
492 while (inner.hasNext()) {
493 Map.Entry<WBEMProtocol, WBEMServiceAdvertisement> innerEntry = inner.next();
494 result.append("[");
495 result.append(innerEntry.getKey().toString());
496 result.append("]");
497 }
498 result.append("]");
499 }
500 return result.toString();
501 }
502
503 private void expire(String pDirectory) {
504 List<AdvertisementDecorator> advertisementList = this.iCatalogByDirectory.get(pDirectory);
505 if (advertisementList == null) {
506 return;
507 }
508 Iterator<AdvertisementDecorator> iter = advertisementList.iterator();
509 while (iter.hasNext()) {
510 AdvertisementDecorator advertisement = iter.next();
511 if (advertisement.isRefresh()) {
512 advertisement.setRefresh(false);
513 advertisement.setExpired(true);
514 notifyEventListeners(EVENT_EXPIRE, advertisement);
515 }
516 }
517 }
518
519 private AdvertisementDecorator findAdvertisement(
520 List<AdvertisementDecorator> pList,
521 WBEMServiceAdvertisement pAdvertisement
522 ) {
523 Iterator<AdvertisementDecorator> iter = pList.iterator();
524 while (iter.hasNext()) {
525 AdvertisementDecorator entry = iter.next();
526 if (entry.getServiceUrl().equals(pAdvertisement.getServiceUrl())) {
527 return entry;
528 }
529 }
530 return null;
531 }
532
533 private WBEMProtocol makeProtocol(WBEMServiceAdvertisement advertisement) {
534 String presentation = advertisement.getAttribute(WBEMServiceAdvertisement.COMM_MECHANISM);
535 if ("OTHER".equalsIgnoreCase(presentation)) {
536 presentation = advertisement.getAttribute(WBEMServiceAdvertisement.OTHER_COMM_MECHN_DESC);
537 }
538 String transport = advertisement.getServiceUrl().split(":", 2)[0];
539 WBEMProtocol protocol = new WBEMProtocol(transport, presentation);
540 return protocol;
541 }
542
543 private void markRefresh(String pDirectory) {
544 List<AdvertisementDecorator> advertisementList = this.iCatalogByDirectory.get(pDirectory);
545 if (advertisementList == null) {
546 return;
547 }
548 Iterator<AdvertisementDecorator> iter = advertisementList.iterator();
549 while (iter.hasNext()) {
550 AdvertisementDecorator advertisement = iter.next();
551 advertisement.setRefresh(true);
552 }
553 }
554
555 private void notifyEventListeners(int pEvent, WBEMServiceAdvertisement pAdvertisement) {
556 Iterator<EventListener> iter = this.iListeners.iterator();
557 while (iter.hasNext()) {
558 iter.next().advertisementEvent(pEvent, pAdvertisement);
559 }
560 }
561 }