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