1 karl 1.11 //%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 karl 1.11 // 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 carolann.graves 1.11.2.1 Array <CIMInstance> SubscriptionTable::reflectProviderDisable (
|
163 aruran.ms 1.8 const CIMInstance & provider)
|
164 kumpf 1.1 {
165 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
166 carolann.graves 1.11.2.1 "SubscriptionTable::reflectProviderDisable");
|
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 carolann.graves 1.11.2.1
234 _updateSubscriptionProviders (activeSubscriptionsKey,
235 tableValue.subscription, tableValue.providers);
|
236 carolann.graves 1.9 }
237 else
238 {
239 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
240 Tracer::LEVEL2,
241 "Provider (" + provider.getPath().toString() +
242 ") not found in list for Subscription (" +
|
243 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
244 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
|
245 kumpf 1.1 }
246 }
247 else
248 {
249 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
|
250 carolann.graves 1.9 Tracer::LEVEL2,
|
251 carolann.graves 1.10 "Subscription (" + activeSubscriptionsKey.toString () +
|
252 carolann.graves 1.9 ") not found in ActiveSubscriptionsTable");
253 //
254 // The subscription may have been deleted in the mean time
255 // If so, no further update is required
256 //
|
257 kumpf 1.1 }
258 }
259 }
260
261 PEG_METHOD_EXIT ();
262 return providerSubscriptions;
263 }
264
|
265 carolann.graves 1.11.2.1 Array <ActiveSubscriptionsTableEntry>
266 SubscriptionTable::reflectProviderModuleFailure
267 (const String & moduleName,
268 const String & userName,
269 Boolean authenticationEnabled)
270 {
271 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
272 "SubscriptionTable::reflectProviderModuleFailure");
273
274 Array <ActiveSubscriptionsTableEntry> providerModuleSubscriptions;
275
276 //
277 // Iterate through the subscription table to find subscriptions served by
278 // a provider in the specified module, with the specified userName as the
279 // subscription creator
280 // NOTE: updating entries (remove and insert) while iterating through the
281 // table is not allowed
282 // The SubscriptionTable first iterates through the active subscriptions
283 // table to find matching subscriptions served by a provider in the
284 // specified module, then looks up and updates each affected subscription
285 //
286 carolann.graves 1.11.2.1 {
287 //
288 // Acquire and hold the write lock during the entire
289 // lookup/remove/insert process, allowing competing threads to apply
290 // their logic over a consistent view of the data.
291 // Do not call any other methods that need
292 // _activeSubscriptionsTableLock.
293 //
294 WriteLock lock (_activeSubscriptionsTableLock);
295
296 for (ActiveSubscriptionsTable::Iterator i =
297 _activeSubscriptionsTable.start (); i; i++)
298 {
299 ActiveSubscriptionsTableEntry tableValue;
300 //
301 // Get subscription creator
302 //
303 tableValue = i.value ();
304 String creator;
305 CIMValue creatorValue = tableValue.subscription.getProperty
306 (tableValue.subscription.findProperty
307 carolann.graves 1.11.2.1 (PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue();
308 creatorValue.get (creator);
309
310 Array <ProviderClassList> failedProviderList;
311 for (Uint32 j = 0; j < tableValue.providers.size (); j++)
312 {
313 //
314 // Get provider module name
315 //
316 String providerModuleName;
317 CIMValue nameValue =
318 tableValue.providers [j].providerModule.getProperty
319 (tableValue.providers [j].providerModule.findProperty
320 (_PROPERTY_NAME)).getValue ();
321 nameValue.get (providerModuleName);
322
323 //
324 // Get module user context setting
325 //
326 Uint16 moduleContext = PEGASUS_DEFAULT_PROV_USERCTXT;
327 CIMValue contextValue =
328 carolann.graves 1.11.2.1 tableValue.providers [j].providerModule.getProperty
329 (tableValue.providers [j].providerModule.findProperty
330 (PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT)).getValue ();
331 if (!contextValue.isNull ())
332 {
333 contextValue.get (moduleContext);
334 }
335
336 //
337 // If provider module name matches,
338 // add provider to the list of failed providers
339 //
340 if (providerModuleName == moduleName)
341 {
342 //
343 // If authentication is enabled, and module was run as
344 // requestor, subscription creator must also match module
345 // user context name, to add provider to the list of
346 // failed providers
347 //
348 if ((moduleContext != PG_PROVMODULE_USERCTXT_REQUESTOR) ||
349 carolann.graves 1.11.2.1 (!authenticationEnabled) || (creator == userName))
350 {
351 //
352 // Add the provider to the list
353 //
354 failedProviderList.append
355 (tableValue.providers [j]);
356 }
357 } // if provider module name matches
358 } // for each subscription provider
359
360 //
361 // If there were any failed providers, add the subscription
362 // entry to the list of affected subscriptions
363 //
364 if (failedProviderList.size () > 0)
365 {
366 ActiveSubscriptionsTableEntry subscription;
367 subscription.subscription = tableValue.subscription;
368 subscription.providers = failedProviderList;
369 providerModuleSubscriptions.append (subscription);
370 carolann.graves 1.11.2.1 }
371 }
372
373 //
374 // Look up and update hash table entry for each affected subscription
375 //
376 for (Uint32 k = 0; k < providerModuleSubscriptions.size (); k++)
377 {
378 //
379 // Update the entry in the active subscriptions hash table
380 //
381 CIMObjectPath activeSubscriptionsKey =
382 _generateActiveSubscriptionsKey
383 (providerModuleSubscriptions [k].subscription.getPath ());
384 ActiveSubscriptionsTableEntry tableValue;
385 if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
386 tableValue))
387 {
388 Array <ProviderClassList> updatedProviderList;
389 for (Uint32 l = 0; l < tableValue.providers.size (); l++)
390 {
391 carolann.graves 1.11.2.1 String providerModuleName;
392 CIMValue nameValue =
393 tableValue.providers [l].providerModule.getProperty
394 (tableValue.providers [l].providerModule.findProperty
395 (_PROPERTY_NAME)).getValue ();
396 nameValue.get (providerModuleName);
397 if (providerModuleName != moduleName)
398 {
399 //
400 // Provider is not in the failed module
401 // Append provider to list of providers still serving
402 // the subscription
403 //
404 updatedProviderList.append (tableValue.providers [l]);
405 }
406 }
407
408 _updateSubscriptionProviders (activeSubscriptionsKey,
409 tableValue.subscription, updatedProviderList);
410 }
411 }
412 carolann.graves 1.11.2.1 }
413
414 PEG_METHOD_EXIT ();
415 return providerModuleSubscriptions;
416 }
417
|
418 carolann.graves 1.10 CIMObjectPath SubscriptionTable::_generateActiveSubscriptionsKey (
|
419 kumpf 1.1 const CIMObjectPath & subscription) const
420 {
421 //
|
422 carolann.graves 1.10 // Get filter and handler object paths from subscription Filter and Handler
423 // reference property values
|
424 kumpf 1.1 //
425 Array<CIMKeyBinding> subscriptionKB = subscription.getKeyBindings ();
|
426 carolann.graves 1.10 CIMObjectPath filterPath;
427 CIMObjectPath handlerPath;
|
428 kumpf 1.1 for (Uint32 i = 0; i < subscriptionKB.size (); i++)
429 {
430 if ((subscriptionKB [i].getName () == _PROPERTY_FILTER) &&
431 (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
432 {
|
433 carolann.graves 1.10 filterPath = subscriptionKB [i].getValue ();
|
434 kumpf 1.1 }
435 if ((subscriptionKB [i].getName () == _PROPERTY_HANDLER) &&
436 (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
437 {
|
438 carolann.graves 1.10 handlerPath = subscriptionKB [i].getValue ();
|
439 kumpf 1.1 }
440 }
441
442 //
|
443 carolann.graves 1.10 // Construct subscription object name for key
|
444 kumpf 1.1 //
|
445 carolann.graves 1.10 filterPath.setHost (String::EMPTY);
446 handlerPath.setHost (String::EMPTY);
447 Array <CIMKeyBinding> kb;
448 kb.append (CIMKeyBinding (_PROPERTY_FILTER, CIMValue (filterPath)));
449 kb.append (CIMKeyBinding (_PROPERTY_HANDLER, CIMValue (handlerPath)));
450 CIMObjectPath activeSubscriptionsKey ("", subscription.getNameSpace (),
451 subscription.getClassName (), kb);
|
452 kumpf 1.1
453 return activeSubscriptionsKey;
454 }
455
456 Boolean SubscriptionTable::_lockedLookupActiveSubscriptionsEntry (
|
457 carolann.graves 1.10 const CIMObjectPath & key,
|
458 aruran.ms 1.7 ActiveSubscriptionsTableEntry & tableEntry) const
|
459 kumpf 1.1 {
460 ReadLock lock(_activeSubscriptionsTableLock);
461
462 return (_activeSubscriptionsTable.lookup (key, tableEntry));
463 }
464
465 void SubscriptionTable::_insertActiveSubscriptionsEntry (
466 const CIMInstance & subscription,
|
467 aruran.ms 1.8 const Array <ProviderClassList> & providers)
|
468 kumpf 1.1 {
469 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
470 "SubscriptionTable::_insertActiveSubscriptionsEntry");
471
|
472 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
473 kumpf 1.1 (subscription.getPath ());
474 ActiveSubscriptionsTableEntry entry;
475 entry.subscription = subscription;
476 entry.providers = providers;
477
|
478 carolann.graves 1.10 //
479 // Insert returns true on success, false if duplicate key
480 //
481 Boolean succeeded = _activeSubscriptionsTable.insert
482 (activeSubscriptionsKey, entry);
483 PEGASUS_ASSERT (succeeded);
|
484 kumpf 1.1
485 #ifdef PEGASUS_INDICATION_HASHTRACE
486 String traceString;
487 traceString.append (activeSubscriptionsKey);
488 traceString.append (" Providers: ");
489 for (Uint32 i = 0; i < providers.size (); i++)
490 {
|
491 carolann.graves 1.9 String providerName = providers [i].provider.getProperty
492 (providers [i].provider.findProperty
|
493 kumpf 1.1 (_PROPERTY_NAME)).getValue ().toString ();
494 traceString.append (providerName);
495 traceString.append (" Classes: ");
496 for (Uint32 j = 0; j < providers[i].classList.size (); j++)
497 {
|
498 carolann.graves 1.9 traceString.append (providers[i].classList[j].getString());
|
499 kumpf 1.1 traceString.append (" ");
500 }
501 }
|
502 carolann.graves 1.9
503 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
|
504 kumpf 1.1 "INSERTED _activeSubscriptionsTable entry: " + traceString);
505 #endif
506
507 PEG_METHOD_EXIT ();
508 }
509
510 void SubscriptionTable::_removeActiveSubscriptionsEntry (
|
511 carolann.graves 1.10 const CIMObjectPath & key)
|
512 kumpf 1.1 {
513 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
514 "SubscriptionTable::_removeActiveSubscriptionsEntry");
515
|
516 carolann.graves 1.10 //
517 // Remove returns true on success, false if not found
518 //
519 Boolean succeeded = _activeSubscriptionsTable.remove (key);
520 PEGASUS_ASSERT (succeeded);
521
|
522 kumpf 1.1 #ifdef PEGASUS_INDICATION_HASHTRACE
|
523 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
524 Tracer::LEVEL3,
|
525 carolann.graves 1.10 "REMOVED _activeSubscriptionsTable entry: " +
526 key.toString ());
|
527 kumpf 1.1 #endif
528
529 PEG_METHOD_EXIT ();
530 }
531
532 String SubscriptionTable::_generateSubscriptionClassesKey (
533 const CIMName & indicationClassName,
534 const CIMNamespaceName & sourceNamespaceName) const
535 {
536 String subscriptionClassesKey;
537
538 //
539 // Append indication class name to key
540 //
541 subscriptionClassesKey.append (indicationClassName.getString ());
542
543 //
544 // Append source namespace name to key
545 //
546 subscriptionClassesKey.append (sourceNamespaceName.getString ());
547
548 kumpf 1.1 return subscriptionClassesKey;
549 }
550
551 Boolean SubscriptionTable::_lockedLookupSubscriptionClassesEntry (
552 const String & key,
|
553 aruran.ms 1.7 SubscriptionClassesTableEntry & tableEntry) const
|
554 kumpf 1.1 {
555 ReadLock lock(_subscriptionClassesTableLock);
556
557 return (_subscriptionClassesTable.lookup (key, tableEntry));
558 }
559
|
560 carolann.graves 1.9 void SubscriptionTable::_insertSubscriptionClassesEntry (
|
561 kumpf 1.1 const CIMName & indicationClassName,
562 const CIMNamespaceName & sourceNamespaceName,
563 const Array <CIMInstance> & subscriptions)
564 {
565 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
566 carolann.graves 1.9 "SubscriptionTable::_insertSubscriptionClassesEntry");
|
567 kumpf 1.1
568 String subscriptionClassesKey = _generateSubscriptionClassesKey
569 (indicationClassName, sourceNamespaceName);
570 SubscriptionClassesTableEntry entry;
571 entry.indicationClassName = indicationClassName;
572 entry.sourceNamespaceName = sourceNamespaceName;
573 entry.subscriptions = subscriptions;
|
574 carolann.graves 1.9
|
575 carolann.graves 1.10 //
576 // Insert returns true on success, false if duplicate key
577 //
578 Boolean succeeded = _subscriptionClassesTable.insert
579 (subscriptionClassesKey, entry);
580 PEGASUS_ASSERT (succeeded);
|
581 kumpf 1.1
582 #ifdef PEGASUS_INDICATION_HASHTRACE
583 String traceString;
584 traceString.append (subscriptionClassesKey);
585 traceString.append (" Subscriptions: ");
586 for (Uint32 i = 0; i < subscriptions.size (); i++)
587 {
|
588 carolann.graves 1.9 traceString.append (subscriptions [i].getPath ().toString());
|
589 kumpf 1.1 traceString.append (" ");
590 }
|
591 carolann.graves 1.9
592 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
|
593 kumpf 1.1 "INSERTED _subscriptionClassesTable entry: " + traceString);
594 #endif
595
596 PEG_METHOD_EXIT ();
597 }
598
|
599 carolann.graves 1.9 void SubscriptionTable::_removeSubscriptionClassesEntry (
|
600 kumpf 1.1 const String & key)
601 {
602 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
603 carolann.graves 1.9 "SubscriptionTable::_removeSubscriptionClassesEntry");
|
604 kumpf 1.1
|
605 carolann.graves 1.10 //
606 // Remove returns true on success, false if not found
607 //
608 Boolean succeeded = _subscriptionClassesTable.remove (key);
609 PEGASUS_ASSERT (succeeded);
|
610 kumpf 1.1
611 #ifdef PEGASUS_INDICATION_HASHTRACE
|
612 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL3,
|
613 kumpf 1.1 "REMOVED _subscriptionClassesTable entry: " + key);
614 #endif
615
616 PEG_METHOD_EXIT ();
617 }
618
|
619 carolann.graves 1.11.2.1 void SubscriptionTable::_updateSubscriptionProviders
620 (const CIMObjectPath & activeSubscriptionsKey,
621 const CIMInstance & subscription,
622 const Array <ProviderClassList> & updatedProviderList)
623 {
624 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
625 "SubscriptionTable::_updateSubscriptionProviders");
626
627 if (updatedProviderList.size () > 0)
628 {
629 //
630 // At least one provider is still serving the
631 // subscription
632 // Update entry in Active Subscriptions table
633 //
634 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
635 _insertActiveSubscriptionsEntry (subscription, updatedProviderList);
636 }
637 else
638 {
639 //
640 carolann.graves 1.11.2.1 // The disabled or failed provider(s) was (were) the only provider(s)
641 // serving the subscription
642 // Implement the subscription's On Fatal Error Policy
643 //
644 Boolean removedOrDisabled =
645 _subscriptionRepository->reconcileFatalError (subscription);
646 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
647 if (!removedOrDisabled)
648 {
649 //
650 // If subscription was not disabled or deleted
651 // Update entry in Active Subscriptions table
652 // Note that in this case the updatedProviderList is
653 // empty - no providers are serving the subscription
654 // currently
655 //
656 _insertActiveSubscriptionsEntry (subscription,
657 updatedProviderList);
658 }
659 }
660
661 carolann.graves 1.11.2.1 PEG_METHOD_EXIT ();
662 }
663
|
664 carolann.graves 1.6 void SubscriptionTable::insertSubscription (
|
665 kumpf 1.1 const CIMInstance & subscription,
666 const Array <ProviderClassList> & providers,
667 const Array <CIMName> & indicationSubclassNames,
668 const CIMNamespaceName & sourceNamespaceName)
669 {
670 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
671 "SubscriptionTable::insertSubscription");
672
673 //
|
674 carolann.graves 1.9 // Insert entry into active subscriptions table
|
675 kumpf 1.1 //
676 {
677 WriteLock lock(_activeSubscriptionsTableLock);
678
679 _insertActiveSubscriptionsEntry (subscription, providers);
680 }
681
682 //
|
683 carolann.graves 1.9 // Insert or update entries in subscription classes table
|
684 kumpf 1.1 //
685 {
|
686 carolann.graves 1.9 //
687 // Acquire and hold the write lock during the entire
688 // lookup/remove/insert process, allowing competing threads to apply
689 // their logic over a consistent view of the data.
690 // Do not call any other methods that need
691 // _subscriptionClassesTableLock.
692 //
693 WriteLock lock (_subscriptionClassesTableLock);
694 for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
|
695 kumpf 1.1 {
|
696 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
697 (indicationSubclassNames [i], sourceNamespaceName);
698 SubscriptionClassesTableEntry tableValue;
699 if (_subscriptionClassesTable.lookup (subscriptionClassesKey,
700 tableValue))
701 {
702 //
703 // If entry exists for this IndicationClassName-SourceNamespace
704 // pair, remove old entry and insert new entry
705 //
706 Array <CIMInstance> subscriptions = tableValue.subscriptions;
707 subscriptions.append (subscription);
708 _removeSubscriptionClassesEntry (subscriptionClassesKey);
709 _insertSubscriptionClassesEntry (indicationSubclassNames [i],
710 sourceNamespaceName, subscriptions);
711 }
712 else
713 {
714 //
715 // If no entry exists for this
716 // IndicationClassName-SourceNamespace pair, insert new entry
717 carolann.graves 1.9 //
718 Array <CIMInstance> subscriptions;
719 subscriptions.append (subscription);
720 _insertSubscriptionClassesEntry (indicationSubclassNames [i],
721 sourceNamespaceName, subscriptions);
722 }
|
723 kumpf 1.1 }
724 }
725
726 PEG_METHOD_EXIT ();
727 }
728
|
729 carolann.graves 1.6 void SubscriptionTable::updateProviders (
|
730 kumpf 1.1 const CIMObjectPath & subscriptionPath,
731 const ProviderClassList & provider,
732 Boolean addProvider)
733 {
734 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
735 "SubscriptionTable::updateProviders");
736
|
737 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
738 kumpf 1.1 (subscriptionPath);
739 ActiveSubscriptionsTableEntry tableValue;
740 {
|
741 carolann.graves 1.9 //
742 // Acquire and hold the write lock during the entire
743 // lookup/remove/insert process, allowing competing threads to apply
744 // their logic over a consistent view of the data.
745 // Do not call any other methods that need
746 // _activeSubscriptionsTableLock.
747 //
748 WriteLock lock (_activeSubscriptionsTableLock);
749 if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
750 tableValue))
|
751 kumpf 1.1 {
|
752 carolann.graves 1.9 Uint32 providerIndex = providerInList (provider.provider,
753 tableValue);
754 if (addProvider)
|
755 kumpf 1.1 {
|
756 carolann.graves 1.9 if (providerIndex == PEG_NOT_FOUND)
757 {
758 tableValue.providers.append (provider);
759 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
760 _insertActiveSubscriptionsEntry (tableValue.subscription,
761 tableValue.providers);
762 }
763 else
764 {
765 CIMInstance p = provider.provider;
766 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
767 Tracer::LEVEL2,
768 "Provider " +
769 IndicationService::getProviderLogString (p) +
770 " already in list for Subscription (" +
|
771 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
772 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
773 }
|
774 kumpf 1.1 }
775 else
776 {
|
777 carolann.graves 1.9 if (providerIndex != PEG_NOT_FOUND)
778 {
779 tableValue.providers.remove (providerIndex);
780 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
781 _insertActiveSubscriptionsEntry (tableValue.subscription,
782 tableValue.providers);
783 }
784 else
785 {
786 CIMInstance p = provider.provider;
787 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
788 Tracer::LEVEL2,
789 "Provider " +
790 IndicationService::getProviderLogString (p) +
791 " not found in list for Subscription (" +
|
792 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
793 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
794 }
|
795 kumpf 1.1 }
796 }
797 else
798 {
|
799 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL2,
|
800 carolann.graves 1.10 "Subscription (" + activeSubscriptionsKey.toString () +
|
801 carolann.graves 1.9 ") not found in ActiveSubscriptionsTable");
802
803 //
804 // The subscription may have been deleted in the mean time
805 // If so, no further update is required
806 //
|
807 kumpf 1.1 }
808 }
809
810 PEG_METHOD_EXIT ();
811 }
812
813 void SubscriptionTable::updateClasses (
814 const CIMObjectPath & subscriptionPath,
815 const CIMInstance & provider,
816 const CIMName & className)
817 {
818 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
819 "SubscriptionTable::updateClasses");
820
|
821 carolann.graves 1.10 CIMObjectPath activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
822 kumpf 1.1 (subscriptionPath);
823 ActiveSubscriptionsTableEntry tableValue;
824
825 {
|
826 carolann.graves 1.9 //
827 // Acquire and hold the write lock during the entire
828 // lookup/remove/insert process, allowing competing threads to apply
829 // their logic over a consistent view of the data.
830 // Do not call any other methods that need
831 // _activeSubscriptionsTableLock.
832 //
833 WriteLock lock (_activeSubscriptionsTableLock);
834 if (_activeSubscriptionsTable.lookup (activeSubscriptionsKey,
835 tableValue))
|
836 kumpf 1.1 {
|
837 carolann.graves 1.9 Uint32 providerIndex = providerInList (provider, tableValue);
838 if (providerIndex != PEG_NOT_FOUND)
|
839 kumpf 1.1 {
|
840 carolann.graves 1.9 Uint32 classIndex = classInList (className,
841 tableValue.providers [providerIndex]);
842 if (classIndex == PEG_NOT_FOUND)
843 {
844 tableValue.providers [providerIndex].classList.append
845 (className);
846 }
847 else // classIndex != PEG_NOT_FOUND
848 {
849 tableValue.providers [providerIndex].classList.remove
850 (classIndex);
851 }
852
853 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
854 _insertActiveSubscriptionsEntry (tableValue.subscription,
855 tableValue.providers);
|
856 kumpf 1.1 }
|
857 carolann.graves 1.9 else
|
858 kumpf 1.1 {
|
859 carolann.graves 1.9 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
860 Tracer::LEVEL2,
861 "Provider (" + provider.getPath ().toString () +
862 ") not found in list for Subscription (" +
|
863 carolann.graves 1.10 activeSubscriptionsKey.toString () +
|
864 carolann.graves 1.9 ") in ActiveSubscriptionsTable");
|
865 kumpf 1.1 }
866 }
867 else
868 {
|
869 carolann.graves 1.9 //
870 // Subscription not found in Active Subscriptions table
871 //
|
872 kumpf 1.1 }
873 }
874
875 PEG_METHOD_EXIT ();
876 }
877
|
878 carolann.graves 1.6 void SubscriptionTable::removeSubscription (
|
879 kumpf 1.1 const CIMInstance & subscription,
880 const Array <CIMName> & indicationSubclassNames,
881 const CIMNamespaceName & sourceNamespaceName,
882 const Array <ProviderClassList> & providers)
883 {
884 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
885 "SubscriptionTable::removeSubscription");
886
887 //
|
888 carolann.graves 1.9 // Remove entry from active subscriptions table
|
889 kumpf 1.1 //
890 {
891 WriteLock lock(_activeSubscriptionsTableLock);
892
893 _removeActiveSubscriptionsEntry (
894 _generateActiveSubscriptionsKey (subscription.getPath ()));
895 }
896
897 //
|
898 carolann.graves 1.9 // Remove or update entries in subscription classes table
|
899 kumpf 1.1 //
900 {
|
901 carolann.graves 1.9 //
902 // Acquire and hold the write lock during the entire
903 // lookup/remove/insert process, allowing competing threads to apply
904 // their logic over a consistent view of the data.
905 // Do not call any other methods that need
906 // _subscriptionClassesTableLock.
907 //
908 WriteLock lock (_subscriptionClassesTableLock);
909 for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
|
910 kumpf 1.1 {
|
911 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
912 (indicationSubclassNames [i], sourceNamespaceName);
913 SubscriptionClassesTableEntry tableValue;
914 if (_subscriptionClassesTable.lookup (subscriptionClassesKey,
915 tableValue))
916 {
917 //
918 // If entry exists for this IndicationClassName-SourceNamespace
919 // pair, remove subscription from the list
920 //
921 Array <CIMInstance> subscriptions = tableValue.subscriptions;
922 for (Uint32 j = 0; j < subscriptions.size (); j++)
923 {
924 if (subscriptions [j].getPath().identical
925 (subscription.getPath()))
926 {
927 subscriptions.remove (j);
928 }
929 }
930
931 //
932 carolann.graves 1.9 // Remove the old entry
933 //
934 _removeSubscriptionClassesEntry (subscriptionClassesKey);
935
936 //
937 // If there are still subscriptions in the list, insert the
938 // new entry
939 //
940 if (subscriptions.size () > 0)
|
941 kumpf 1.1 {
|
942 carolann.graves 1.9 _insertSubscriptionClassesEntry (
943 indicationSubclassNames [i],
944 sourceNamespaceName, subscriptions);
|
945 kumpf 1.1 }
946 }
|
947 carolann.graves 1.9 else
|
948 kumpf 1.1 {
|
949 carolann.graves 1.9 //
950 // Entry not found in Subscription Classes table
951 //
952 PEG_TRACE_STRING (TRC_INDICATION_SERVICE_INTERNAL,
953 Tracer::LEVEL2,
954 "Indication subclass and namespace (" +
955 subscriptionClassesKey +
956 ") not found in SubscriptionClassesTable");
|
957 kumpf 1.1 }
958 }
959 }
960
961 PEG_METHOD_EXIT ();
962 }
963
|
964 carolann.graves 1.9 Uint32 SubscriptionTable::providerInList
965 (const CIMInstance & provider,
|
966 kumpf 1.1 const ActiveSubscriptionsTableEntry & tableValue) const
967 {
968 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
969 "SubscriptionTable::providerInList");
970
971 //
972 // Look for the provider in the list
973 //
974 for (Uint32 i = 0; i < tableValue.providers.size (); i++)
975 {
|
976 carolann.graves 1.9 if (tableValue.providers [i].provider.getPath ().identical
|
977 kumpf 1.1 (provider.getPath ()))
978 {
|
979 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
980 kumpf 1.1 return i;
981 }
982 }
983
|
984 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
985 kumpf 1.1 return PEG_NOT_FOUND;
986 }
987
988
|
989 carolann.graves 1.9 Uint32 SubscriptionTable::classInList
990 (const CIMName & className,
|
991 kumpf 1.1 const ProviderClassList & providerClasses) const
992 {
993 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::classInList");
994
995 //
996 // Look for the class in the list
997 //
998 for (Uint32 i = 0; i < providerClasses.classList.size (); i++)
999 {
1000 if (providerClasses.classList [i].equal (className))
1001 {
|
1002 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
1003 kumpf 1.1 return i;
1004 }
1005 }
1006
|
1007 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
1008 kumpf 1.1 return PEG_NOT_FOUND;
1009 }
1010
|
1011 kumpf 1.2 void SubscriptionTable::clear ()
1012 {
1013 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::clear");
1014
1015 {
1016 WriteLock lock (_activeSubscriptionsTableLock);
1017 _activeSubscriptionsTable.clear ();
1018 }
1019 {
1020 WriteLock lock (_subscriptionClassesTableLock);
1021 _subscriptionClassesTable.clear ();
1022 }
1023
1024 PEG_METHOD_EXIT ();
1025 }
1026
|
1027 kumpf 1.1 PEGASUS_NAMESPACE_END
|