1 a.dunfey 1.10.8.1 //%2006////////////////////////////////////////////////////////////////////////
|
2 kumpf 1.1 //
|
3 karl 1.3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 kumpf 1.1 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.3 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.5 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 a.dunfey 1.10.8.1 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 kumpf 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Carol Ann Krug Graves, Hewlett-Packard Company
33 // (carolann_graves@hp.com)
34 kumpf 1.1 //
35 // Modified By:
|
36 gs.keenan 1.4 // Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)
|
37 aruran.ms 1.7 // Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3603
|
38 kumpf 1.1 //
39 //%/////////////////////////////////////////////////////////////////////////////
40
41 #include <Pegasus/Common/Config.h>
42 #include <Pegasus/Common/Constants.h>
43 #include <Pegasus/Common/Tracer.h>
44
45 #include "IndicationConstants.h"
46 #include "IndicationService.h"
47 #include "SubscriptionTable.h"
48
49 PEGASUS_USING_STD;
50
51 PEGASUS_NAMESPACE_BEGIN
52
53 SubscriptionTable::SubscriptionTable (
54 SubscriptionRepository * subscriptionRepository)
55 : _subscriptionRepository (subscriptionRepository)
56 {
57 }
58
59 kumpf 1.1 SubscriptionTable::~SubscriptionTable ()
60 {
61 }
62
63 Boolean SubscriptionTable::getSubscriptionEntry (
64 const CIMObjectPath & subscriptionPath,
|
65 carolann.graves 1.9 ActiveSubscriptionsTableEntry & tableValue) const
|
66 kumpf 1.1 {
67 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
68 "SubscriptionTable::getSubscriptionEntry");
69
70 Boolean succeeded = false;
|
71 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
72 kumpf 1.1 (subscriptionPath);
|
73 carolann.graves 1.9 if (_lockedLookupActiveSubscriptionsEntry
|
74 kumpf 1.1 (activeSubscriptionsKey, tableValue))
75 {
76 succeeded = true;
77 }
78 else
79 {
80 //
81 // Subscription not found in Active Subscriptions table
82 //
83 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL2,
|
84 carolann.graves 1.10 "Subscription (" + activeSubscriptionsKey.toString () +
|
85 kumpf 1.1 ") not found in ActiveSubscriptionsTable");
86 }
87
88 PEG_METHOD_EXIT ();
89 return succeeded;
90 }
91
92 Array <CIMInstance> SubscriptionTable::getMatchingSubscriptions (
93 const CIMName & supportedClass,
94 const Array <CIMNamespaceName> nameSpaces,
95 const Boolean checkProvider,
|
96 aruran.ms 1.7 const CIMInstance & provider) const
|
97 kumpf 1.1 {
98 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
99 "SubscriptionTable::getMatchingSubscriptions");
100
101 Array <CIMInstance> matchingSubscriptions;
102 Array <CIMInstance> subscriptions;
103
104 for (Uint32 i = 0; i < nameSpaces.size (); i++)
105 {
106 //
|
107 carolann.graves 1.9 // Look up the indicationClass-sourceNamespace pair in the
|
108 kumpf 1.1 // Subscription Classes table
109 //
|
110 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
|
111 kumpf 1.1 (supportedClass, nameSpaces [i]);
112 SubscriptionClassesTableEntry tableValue;
|
113 carolann.graves 1.9 if (_lockedLookupSubscriptionClassesEntry (subscriptionClassesKey,
|
114 kumpf 1.1 tableValue))
115 {
116 subscriptions = tableValue.subscriptions;
117 for (Uint32 j = 0; j < subscriptions.size (); j++)
118 {
119 Boolean match = true;
120
121 if (checkProvider)
122 {
123 //
|
124 carolann.graves 1.9 // Check if the provider who generated this indication
|
125 kumpf 1.1 // accepted this subscription
126 //
|
127 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey =
|
128 kumpf 1.1 _generateActiveSubscriptionsKey
|
129 carolann.graves 1.10 (subscriptions [j].getPath ());
|
130 kumpf 1.1 ActiveSubscriptionsTableEntry tableValue;
|
131 carolann.graves 1.9 if (_lockedLookupActiveSubscriptionsEntry
|
132 kumpf 1.1 (activeSubscriptionsKey, tableValue))
133 {
134 //
135 // If provider is not in list, it did not accept the
136 // subscription
137 //
|
138 carolann.graves 1.9 if ((providerInList (provider, tableValue)) ==
|
139 kumpf 1.1 PEG_NOT_FOUND)
140 {
141 match = false;
142 break;
143 }
144 }
145 }
146
147 if (match)
148 {
149 //
150 // Add current subscription to list
151 //
152 matchingSubscriptions.append (subscriptions [j]);
153 }
154 }
155 }
156 }
157
158 PEG_METHOD_EXIT ();
159 return matchingSubscriptions;
160 kumpf 1.1 }
161
|
162 aruran.ms 1.8 Array <CIMInstance> SubscriptionTable::getAndUpdateProviderSubscriptions (
163 const CIMInstance & provider)
|
164 kumpf 1.1 {
165 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
166 aruran.ms 1.8 "SubscriptionTable::getAndUpdateProviderSubscriptions");
|
167 kumpf 1.1
168 Array <CIMInstance> providerSubscriptions;
169
170 //
171 // Iterate through the subscription table to find subscriptions served by
172 // the provider
|
173 carolann.graves 1.9 // NOTE: updating entries (remove and insert) while iterating through the
|
174 kumpf 1.1 // table does not work reliably, and it is not clear if that is supposed to
|
175 carolann.graves 1.9 // work; for now, the SubscriptionTable first iterates through the
176 // active subscriptions table to find subscriptions served by the
177 // provider, then looks up and updates each affected subscription
|
178 kumpf 1.1 //
179 {
180 //
|
181 carolann.graves 1.9 // Acquire and hold the write lock during the entire
182 // lookup/remove/insert process, allowing competing threads to apply
183 // their logic over a consistent view of the data.
184 // Do not call any other methods that need
185 // _activeSubscriptionsTableLock.
|
186 kumpf 1.1 //
|
187 carolann.graves 1.9 WriteLock lock (_activeSubscriptionsTableLock);
|
188 kumpf 1.1
189 for (ActiveSubscriptionsTable::Iterator i =
190 _activeSubscriptionsTable.start (); i; i++)
191 {
192 //
193 // If provider matches, append subscription to the list
194 //
195 ActiveSubscriptionsTableEntry tableValue = i.value ();
196 for (Uint32 j = 0; j < tableValue.providers.size (); j++)
197 {
|
198 carolann.graves 1.9 if (tableValue.providers [j].provider.getPath ().identical
|
199 kumpf 1.1 (provider.getPath ()))
200 {
201 //
202 // Add the subscription to the list
203 //
204 providerSubscriptions.append (tableValue.subscription);
205 break;
206 }
207 }
208 }
209
210 //
|
211 carolann.graves 1.9 // Look up and update hash table entry for each affected subscription
|
212 kumpf 1.1 //
|
213 carolann.graves 1.9 for (Uint32 k = 0; k < providerSubscriptions.size (); k++)
|
214 kumpf 1.1 {
215 //
|
216 carolann.graves 1.9 // Update the entry in the active subscriptions hash table
|
217 kumpf 1.1 //
|
218 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey =
219 _generateActiveSubscriptionsKey
220 (providerSubscriptions [k].getPath ());
|
221 carolann.graves 1.9 ActiveSubscriptionsTableEntry tableValue;
222 if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
223 tableValue))
|
224 kumpf 1.1 {
|
225 carolann.graves 1.9 //
226 // Remove the provider from the list of providers serving the
227 // subscription
228 //
229 Uint32 providerIndex = providerInList (provider, tableValue);
230 if (providerIndex != PEG_NOT_FOUND)
|
231 kumpf 1.1 {
|
232 carolann.graves 1.9 tableValue.providers.remove (providerIndex);
233 if (tableValue.providers.size () > 0)
|
234 kumpf 1.1 {
235 //
|
236 carolann.graves 1.9 // At least one provider is still serving the
237 // subscription
|
238 kumpf 1.1 // Update entry in Active Subscriptions table
239 //
|
240 carolann.graves 1.9 _removeActiveSubscriptionsEntry
|
241 kumpf 1.1 (activeSubscriptionsKey);
|
242 carolann.graves 1.9 _insertActiveSubscriptionsEntry
|
243 kumpf 1.1 (tableValue.subscription, tableValue.providers);
244 }
|
245 carolann.graves 1.9 else
246 {
247 //
248 // If the terminated provider was the only provider
249 // serving the subscription, implement the
250 // subscription's On Fatal Error Policy
251 //
252 Boolean removedOrDisabled =
253 _subscriptionRepository->reconcileFatalError
254 (tableValue.subscription);
255 _removeActiveSubscriptionsEntry
256 (activeSubscriptionsKey);
257 if (!removedOrDisabled)
258 {
259 //
260 // If subscription was not disabled or deleted
261 // Update entry in Active Subscriptions table
262 //
263 _insertActiveSubscriptionsEntry
264 (tableValue.subscription, tableValue.providers);
265 }
266 carolann.graves 1.9 }
267 }
268 else
269 {
270 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
271 Tracer::LEVEL2,
272 "Provider (" + provider.getPath().toString() +
273 ") not found in list for Subscription (" +
|
274 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
275 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
|
276 kumpf 1.1 }
277 }
278 else
279 {
280 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
|
281 carolann.graves 1.9 Tracer::LEVEL2,
|
282 carolann.graves 1.10 "Subscription (" + activeSubscriptionsKey.toString () +
|
283 carolann.graves 1.9 ") not found in ActiveSubscriptionsTable");
284 //
285 // The subscription may have been deleted in the mean time
286 // If so, no further update is required
287 //
|
288 kumpf 1.1 }
289 }
290 }
291
292 PEG_METHOD_EXIT ();
293 return providerSubscriptions;
294 }
295
|
296 carolann.graves 1.10 CIMObjectPath SubscriptionTable::_generateActiveSubscriptionsKey (
|
297 kumpf 1.1 const CIMObjectPath & subscription) const
298 {
299 //
|
300 carolann.graves 1.10 // Get filter and handler object paths from subscription Filter and Handler
301 // reference property values
|
302 kumpf 1.1 //
303 Array<CIMKeyBinding> subscriptionKB = subscription.getKeyBindings ();
|
304 carolann.graves 1.10 CIMObjectPath filterPath;
305 CIMObjectPath handlerPath;
|
306 kumpf 1.1 for (Uint32 i = 0; i < subscriptionKB.size (); i++)
307 {
308 if ((subscriptionKB [i].getName () == _PROPERTY_FILTER) &&
309 (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
310 {
|
311 carolann.graves 1.10 filterPath = subscriptionKB [i].getValue ();
|
312 kumpf 1.1 }
313 if ((subscriptionKB [i].getName () == _PROPERTY_HANDLER) &&
314 (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
315 {
|
316 carolann.graves 1.10 handlerPath = subscriptionKB [i].getValue ();
|
317 kumpf 1.1 }
318 }
319
320 //
|
321 carolann.graves 1.10 // Construct subscription object name for key
|
322 kumpf 1.1 //
|
323 carolann.graves 1.10 filterPath.setHost (String::EMPTY);
324 handlerPath.setHost (String::EMPTY);
325 Array <CIMKeyBinding> kb;
326 kb.append (CIMKeyBinding (_PROPERTY_FILTER, CIMValue (filterPath)));
327 kb.append (CIMKeyBinding (_PROPERTY_HANDLER, CIMValue (handlerPath)));
328 CIMObjectPath activeSubscriptionsKey ("", subscription.getNameSpace (),
329 subscription.getClassName (), kb);
|
330 kumpf 1.1
331 return activeSubscriptionsKey;
332 }
333
334 Boolean SubscriptionTable::_lockedLookupActiveSubscriptionsEntry (
|
335 carolann.graves 1.10 const CIMObjectPath & key,
|
336 aruran.ms 1.7 ActiveSubscriptionsTableEntry & tableEntry) const
|
337 kumpf 1.1 {
338 ReadLock lock(_activeSubscriptionsTableLock);
339
340 return (_activeSubscriptionsTable.lookup (key, tableEntry));
341 }
342
343 void SubscriptionTable::_insertActiveSubscriptionsEntry (
344 const CIMInstance & subscription,
|
345 aruran.ms 1.8 const Array <ProviderClassList> & providers)
|
346 kumpf 1.1 {
347 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
348 "SubscriptionTable::_insertActiveSubscriptionsEntry");
349
|
350 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
351 kumpf 1.1 (subscription.getPath ());
352 ActiveSubscriptionsTableEntry entry;
353 entry.subscription = subscription;
354 entry.providers = providers;
355
|
356 carolann.graves 1.10 //
357 // Insert returns true on success, false if duplicate key
358 //
359 Boolean succeeded = _activeSubscriptionsTable.insert
360 (activeSubscriptionsKey, entry);
361 PEGASUS_ASSERT (succeeded);
|
362 kumpf 1.1
363 #ifdef PEGASUS_INDICATION_HASHTRACE
364 String traceString;
365 traceString.append (activeSubscriptionsKey);
366 traceString.append (" Providers: ");
367 for (Uint32 i = 0; i < providers.size (); i++)
368 {
|
369 carolann.graves 1.9 String providerName = providers [i].provider.getProperty
370 (providers [i].provider.findProperty
|
371 kumpf 1.1 (_PROPERTY_NAME)).getValue ().toString ();
372 traceString.append (providerName);
373 traceString.append (" Classes: ");
374 for (Uint32 j = 0; j < providers[i].classList.size (); j++)
375 {
|
376 carolann.graves 1.9 traceString.append (providers[i].classList[j].getString());
|
377 kumpf 1.1 traceString.append (" ");
378 }
379 }
|
380 carolann.graves 1.9
381 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
|
382 kumpf 1.1 "INSERTED _activeSubscriptionsTable entry: " + traceString);
383 #endif
384
385 PEG_METHOD_EXIT ();
386 }
387
388 void SubscriptionTable::_removeActiveSubscriptionsEntry (
|
389 carolann.graves 1.10 const CIMObjectPath & key)
|
390 kumpf 1.1 {
391 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
392 "SubscriptionTable::_removeActiveSubscriptionsEntry");
393
|
394 carolann.graves 1.10 //
395 // Remove returns true on success, false if not found
396 //
397 Boolean succeeded = _activeSubscriptionsTable.remove (key);
398 PEGASUS_ASSERT (succeeded);
399
|
400 kumpf 1.1 #ifdef PEGASUS_INDICATION_HASHTRACE
|
401 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
402 Tracer::LEVEL3,
|
403 carolann.graves 1.10 "REMOVED _activeSubscriptionsTable entry: " +
404 key.toString ());
|
405 kumpf 1.1 #endif
406
407 PEG_METHOD_EXIT ();
408 }
409
410 String SubscriptionTable::_generateSubscriptionClassesKey (
411 const CIMName & indicationClassName,
412 const CIMNamespaceName & sourceNamespaceName) const
413 {
414 String subscriptionClassesKey;
415
416 //
417 // Append indication class name to key
418 //
419 subscriptionClassesKey.append (indicationClassName.getString ());
420
421 //
422 // Append source namespace name to key
423 //
424 subscriptionClassesKey.append (sourceNamespaceName.getString ());
425
426 kumpf 1.1 return subscriptionClassesKey;
427 }
428
429 Boolean SubscriptionTable::_lockedLookupSubscriptionClassesEntry (
430 const String & key,
|
431 aruran.ms 1.7 SubscriptionClassesTableEntry & tableEntry) const
|
432 kumpf 1.1 {
433 ReadLock lock(_subscriptionClassesTableLock);
434
435 return (_subscriptionClassesTable.lookup (key, tableEntry));
436 }
437
|
438 carolann.graves 1.9 void SubscriptionTable::_insertSubscriptionClassesEntry (
|
439 kumpf 1.1 const CIMName & indicationClassName,
440 const CIMNamespaceName & sourceNamespaceName,
441 const Array <CIMInstance> & subscriptions)
442 {
443 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
444 carolann.graves 1.9 "SubscriptionTable::_insertSubscriptionClassesEntry");
|
445 kumpf 1.1
446 String subscriptionClassesKey = _generateSubscriptionClassesKey
447 (indicationClassName, sourceNamespaceName);
448 SubscriptionClassesTableEntry entry;
449 entry.indicationClassName = indicationClassName;
450 entry.sourceNamespaceName = sourceNamespaceName;
451 entry.subscriptions = subscriptions;
|
452 carolann.graves 1.9
|
453 carolann.graves 1.10 //
454 // Insert returns true on success, false if duplicate key
455 //
456 Boolean succeeded = _subscriptionClassesTable.insert
457 (subscriptionClassesKey, entry);
458 PEGASUS_ASSERT (succeeded);
|
459 kumpf 1.1
460 #ifdef PEGASUS_INDICATION_HASHTRACE
461 String traceString;
462 traceString.append (subscriptionClassesKey);
463 traceString.append (" Subscriptions: ");
464 for (Uint32 i = 0; i < subscriptions.size (); i++)
465 {
|
466 carolann.graves 1.9 traceString.append (subscriptions [i].getPath ().toString());
|
467 kumpf 1.1 traceString.append (" ");
468 }
|
469 carolann.graves 1.9
470 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
|
471 kumpf 1.1 "INSERTED _subscriptionClassesTable entry: " + traceString);
472 #endif
473
474 PEG_METHOD_EXIT ();
475 }
476
|
477 carolann.graves 1.9 void SubscriptionTable::_removeSubscriptionClassesEntry (
|
478 kumpf 1.1 const String & key)
479 {
480 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
481 carolann.graves 1.9 "SubscriptionTable::_removeSubscriptionClassesEntry");
|
482 kumpf 1.1
|
483 carolann.graves 1.10 //
484 // Remove returns true on success, false if not found
485 //
486 Boolean succeeded = _subscriptionClassesTable.remove (key);
487 PEGASUS_ASSERT (succeeded);
|
488 kumpf 1.1
489 #ifdef PEGASUS_INDICATION_HASHTRACE
|
490 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
|
491 kumpf 1.1 "REMOVED _subscriptionClassesTable entry: " + key);
492 #endif
493
494 PEG_METHOD_EXIT ();
495 }
496
|
497 carolann.graves 1.6 void SubscriptionTable::insertSubscription (
|
498 kumpf 1.1 const CIMInstance & subscription,
499 const Array <ProviderClassList> & providers,
500 const Array <CIMName> & indicationSubclassNames,
501 const CIMNamespaceName & sourceNamespaceName)
502 {
503 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
504 "SubscriptionTable::insertSubscription");
505
506 //
|
507 carolann.graves 1.9 // Insert entry into active subscriptions table
|
508 kumpf 1.1 //
509 {
510 WriteLock lock(_activeSubscriptionsTableLock);
511
512 _insertActiveSubscriptionsEntry (subscription, providers);
513 }
514
515 //
|
516 carolann.graves 1.9 // Insert or update entries in subscription classes table
|
517 kumpf 1.1 //
518 {
|
519 carolann.graves 1.9 //
520 // Acquire and hold the write lock during the entire
521 // lookup/remove/insert process, allowing competing threads to apply
522 // their logic over a consistent view of the data.
523 // Do not call any other methods that need
524 // _subscriptionClassesTableLock.
525 //
526 WriteLock lock (_subscriptionClassesTableLock);
527 for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
|
528 kumpf 1.1 {
|
529 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
530 (indicationSubclassNames [i], sourceNamespaceName);
531 SubscriptionClassesTableEntry tableValue;
532 if (_subscriptionClassesTable.lookup (subscriptionClassesKey,
533 tableValue))
534 {
535 //
536 // If entry exists for this IndicationClassName-SourceNamespace
537 // pair, remove old entry and insert new entry
538 //
539 Array <CIMInstance> subscriptions = tableValue.subscriptions;
540 subscriptions.append (subscription);
541 _removeSubscriptionClassesEntry (subscriptionClassesKey);
542 _insertSubscriptionClassesEntry (indicationSubclassNames [i],
543 sourceNamespaceName, subscriptions);
544 }
545 else
546 {
547 //
548 // If no entry exists for this
549 // IndicationClassName-SourceNamespace pair, insert new entry
550 carolann.graves 1.9 //
551 Array <CIMInstance> subscriptions;
552 subscriptions.append (subscription);
553 _insertSubscriptionClassesEntry (indicationSubclassNames [i],
554 sourceNamespaceName, subscriptions);
555 }
|
556 kumpf 1.1 }
557 }
558
559 PEG_METHOD_EXIT ();
560 }
561
|
562 carolann.graves 1.6 void SubscriptionTable::updateProviders (
|
563 kumpf 1.1 const CIMObjectPath & subscriptionPath,
564 const ProviderClassList & provider,
565 Boolean addProvider)
566 {
567 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
568 "SubscriptionTable::updateProviders");
569
|
570 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
571 kumpf 1.1 (subscriptionPath);
572 ActiveSubscriptionsTableEntry tableValue;
573 {
|
574 carolann.graves 1.9 //
575 // Acquire and hold the write lock during the entire
576 // lookup/remove/insert process, allowing competing threads to apply
577 // their logic over a consistent view of the data.
578 // Do not call any other methods that need
579 // _activeSubscriptionsTableLock.
580 //
581 WriteLock lock (_activeSubscriptionsTableLock);
582 if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
583 tableValue))
|
584 kumpf 1.1 {
|
585 carolann.graves 1.9 Uint32 providerIndex = providerInList (provider.provider,
586 tableValue);
587 if (addProvider)
|
588 kumpf 1.1 {
|
589 carolann.graves 1.9 if (providerIndex == PEG_NOT_FOUND)
590 {
591 tableValue.providers.append (provider);
592 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
593 _insertActiveSubscriptionsEntry (tableValue.subscription,
594 tableValue.providers);
595 }
596 else
597 {
598 CIMInstance p = provider.provider;
599 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
600 Tracer::LEVEL2,
601 "Provider " +
602 IndicationService::getProviderLogString (p) +
603 " already in list for Subscription (" +
|
604 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
605 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
606 }
|
607 kumpf 1.1 }
608 else
609 {
|
610 carolann.graves 1.9 if (providerIndex != PEG_NOT_FOUND)
611 {
612 tableValue.providers.remove (providerIndex);
613 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
614 _insertActiveSubscriptionsEntry (tableValue.subscription,
615 tableValue.providers);
616 }
617 else
618 {
619 CIMInstance p = provider.provider;
620 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
621 Tracer::LEVEL2,
622 "Provider " +
623 IndicationService::getProviderLogString (p) +
624 " not found in list for Subscription (" +
|
625 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
626 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
627 }
|
628 kumpf 1.1 }
629 }
630 else
631 {
|
632 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL2,
|
633 carolann.graves 1.10 "Subscription (" + activeSubscriptionsKey.toString () +
|
634 carolann.graves 1.9 ") not found in ActiveSubscriptionsTable");
635
636 //
637 // The subscription may have been deleted in the mean time
638 // If so, no further update is required
639 //
|
640 kumpf 1.1 }
641 }
642
643 PEG_METHOD_EXIT ();
644 }
645
646 void SubscriptionTable::updateClasses (
647 const CIMObjectPath & subscriptionPath,
648 const CIMInstance & provider,
649 const CIMName & className)
650 {
651 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
652 "SubscriptionTable::updateClasses");
653
|
654 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
655 kumpf 1.1 (subscriptionPath);
656 ActiveSubscriptionsTableEntry tableValue;
657
658 {
|
659 carolann.graves 1.9 //
660 // Acquire and hold the write lock during the entire
661 // lookup/remove/insert process, allowing competing threads to apply
662 // their logic over a consistent view of the data.
663 // Do not call any other methods that need
664 // _activeSubscriptionsTableLock.
665 //
666 WriteLock lock (_activeSubscriptionsTableLock);
667 if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
668 tableValue))
|
669 kumpf 1.1 {
|
670 carolann.graves 1.9 Uint32 providerIndex = providerInList (provider, tableValue);
671 if (providerIndex != PEG_NOT_FOUND)
|
672 kumpf 1.1 {
|
673 carolann.graves 1.9 Uint32 classIndex = classInList (className,
674 tableValue.providers [providerIndex]);
675 if (classIndex == PEG_NOT_FOUND)
676 {
677 tableValue.providers [providerIndex].classList.append
678 (className);
679 }
680 else // classIndex != PEG_NOT_FOUND
681 {
682 tableValue.providers [providerIndex].classList.remove
683 (classIndex);
684 }
685
686 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
687 _insertActiveSubscriptionsEntry (tableValue.subscription,
688 tableValue.providers);
|
689 kumpf 1.1 }
|
690 carolann.graves 1.9 else
|
691 kumpf 1.1 {
|
692 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
693 Tracer::LEVEL2,
694 "Provider (" + provider.getPath ().toString () +
695 ") not found in list for Subscription (" +
|
696 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
697 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
|
698 kumpf 1.1 }
699 }
700 else
701 {
|
702 carolann.graves 1.9 //
703 // Subscription not found in Active Subscriptions table
704 //
|
705 kumpf 1.1 }
706 }
707
708 PEG_METHOD_EXIT ();
709 }
710
|
711 carolann.graves 1.6 void SubscriptionTable::removeSubscription (
|
712 kumpf 1.1 const CIMInstance & subscription,
713 const Array <CIMName> & indicationSubclassNames,
714 const CIMNamespaceName & sourceNamespaceName,
715 const Array <ProviderClassList> & providers)
716 {
717 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
718 "SubscriptionTable::removeSubscription");
719
720 //
|
721 carolann.graves 1.9 // Remove entry from active subscriptions table
|
722 kumpf 1.1 //
723 {
724 WriteLock lock(_activeSubscriptionsTableLock);
725
726 _removeActiveSubscriptionsEntry (
727 _generateActiveSubscriptionsKey (subscription.getPath ()));
728 }
729
730 //
|
731 carolann.graves 1.9 // Remove or update entries in subscription classes table
|
732 kumpf 1.1 //
733 {
|
734 carolann.graves 1.9 //
735 // Acquire and hold the write lock during the entire
736 // lookup/remove/insert process, allowing competing threads to apply
737 // their logic over a consistent view of the data.
738 // Do not call any other methods that need
739 // _subscriptionClassesTableLock.
740 //
741 WriteLock lock (_subscriptionClassesTableLock);
742 for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
|
743 kumpf 1.1 {
|
744 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
745 (indicationSubclassNames [i], sourceNamespaceName);
746 SubscriptionClassesTableEntry tableValue;
747 if (_subscriptionClassesTable.lookup (subscriptionClassesKey,
748 tableValue))
749 {
750 //
751 // If entry exists for this IndicationClassName-SourceNamespace
752 // pair, remove subscription from the list
753 //
754 Array <CIMInstance> subscriptions = tableValue.subscriptions;
755 for (Uint32 j = 0; j < subscriptions.size (); j++)
756 {
757 if (subscriptions [j].getPath().identical
758 (subscription.getPath()))
759 {
760 subscriptions.remove (j);
761 }
762 }
763
764 //
765 carolann.graves 1.9 // Remove the old entry
766 //
767 _removeSubscriptionClassesEntry (subscriptionClassesKey);
768
769 //
770 // If there are still subscriptions in the list, insert the
771 // new entry
772 //
773 if (subscriptions.size () > 0)
|
774 kumpf 1.1 {
|
775 carolann.graves 1.9 _insertSubscriptionClassesEntry (
776 indicationSubclassNames [i],
777 sourceNamespaceName, subscriptions);
|
778 kumpf 1.1 }
779 }
|
780 carolann.graves 1.9 else
|
781 kumpf 1.1 {
|
782 carolann.graves 1.9 //
783 // Entry not found in Subscription Classes table
784 //
785 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
786 Tracer::LEVEL2,
787 "Indication subclass and namespace (" +
788 subscriptionClassesKey +
789 ") not found in SubscriptionClassesTable");
|
790 kumpf 1.1 }
791 }
792 }
793
794 PEG_METHOD_EXIT ();
795 }
796
|
797 carolann.graves 1.9 Uint32 SubscriptionTable::providerInList
798 (const CIMInstance & provider,
|
799 kumpf 1.1 const ActiveSubscriptionsTableEntry & tableValue) const
800 {
801 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
802 "SubscriptionTable::providerInList");
803
804 //
805 // Look for the provider in the list
806 //
807 for (Uint32 i = 0; i < tableValue.providers.size (); i++)
808 {
|
809 carolann.graves 1.9 if (tableValue.providers [i].provider.getPath ().identical
|
810 kumpf 1.1 (provider.getPath ()))
811 {
|
812 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
813 kumpf 1.1 return i;
814 }
815 }
816
|
817 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
818 kumpf 1.1 return PEG_NOT_FOUND;
819 }
820
821
|
822 carolann.graves 1.9 Uint32 SubscriptionTable::classInList
823 (const CIMName & className,
|
824 kumpf 1.1 const ProviderClassList & providerClasses) const
825 {
826 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::classInList");
827
828 //
829 // Look for the class in the list
830 //
831 for (Uint32 i = 0; i < providerClasses.classList.size (); i++)
832 {
833 if (providerClasses.classList [i].equal (className))
834 {
|
835 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
836 kumpf 1.1 return i;
837 }
838 }
839
|
840 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
841 kumpf 1.1 return PEG_NOT_FOUND;
842 }
843
|
844 kumpf 1.2 void SubscriptionTable::clear ()
845 {
846 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::clear");
847
848 {
849 WriteLock lock (_activeSubscriptionsTableLock);
850 _activeSubscriptionsTable.clear ();
851 }
852 {
853 WriteLock lock (_subscriptionClassesTableLock);
854 _subscriptionClassesTable.clear ();
855 }
856
857 PEG_METHOD_EXIT ();
858 }
859
|
860 kumpf 1.1 PEGASUS_NAMESPACE_END
|