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 r.kieninger 1.15 //
|
21 kumpf 1.1 // 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 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <Pegasus/Common/Config.h>
35 #include <Pegasus/Common/Constants.h>
36 #include <Pegasus/Common/Tracer.h>
37
38 #include "IndicationConstants.h"
39 #include "IndicationService.h"
40 #include "SubscriptionTable.h"
41
|
42 yi.zhou 1.17 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
43 # include "ProviderIndicationCountTable.h"
44 #endif
45
|
46 kumpf 1.1 PEGASUS_USING_STD;
47
48 PEGASUS_NAMESPACE_BEGIN
49
50 SubscriptionTable::SubscriptionTable (
51 SubscriptionRepository * subscriptionRepository)
52 : _subscriptionRepository (subscriptionRepository)
53 {
54 }
55
56 SubscriptionTable::~SubscriptionTable ()
57 {
58 }
59
60 Boolean SubscriptionTable::getSubscriptionEntry (
61 const CIMObjectPath & subscriptionPath,
|
62 carolann.graves 1.9 ActiveSubscriptionsTableEntry & tableValue) const
|
63 kumpf 1.1 {
64 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
65 "SubscriptionTable::getSubscriptionEntry");
66
67 Boolean succeeded = false;
|
68 r.kieninger 1.15 String activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
69 kumpf 1.1 (subscriptionPath);
|
70 carolann.graves 1.9 if (_lockedLookupActiveSubscriptionsEntry
|
71 kumpf 1.1 (activeSubscriptionsKey, tableValue))
72 {
73 succeeded = true;
74 }
75 else
76 {
77 //
78 // Subscription not found in Active Subscriptions table
79 //
|
80 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL1,
81 "Subscription (%s) not found in ActiveSubscriptionsTable",
82 (const char*)activeSubscriptionsKey.getCString()));
|
83 kumpf 1.1 }
84
85 PEG_METHOD_EXIT ();
86 return succeeded;
87 }
88
89 Array <CIMInstance> SubscriptionTable::getMatchingSubscriptions (
90 const CIMName & supportedClass,
91 const Array <CIMNamespaceName> nameSpaces,
92 const Boolean checkProvider,
|
93 aruran.ms 1.7 const CIMInstance & provider) const
|
94 kumpf 1.1 {
95 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
96 "SubscriptionTable::getMatchingSubscriptions");
97
98 Array <CIMInstance> matchingSubscriptions;
99 Array <CIMInstance> subscriptions;
100
101 for (Uint32 i = 0; i < nameSpaces.size (); i++)
102 {
103 //
|
104 carolann.graves 1.9 // Look up the indicationClass-sourceNamespace pair in the
|
105 kumpf 1.1 // Subscription Classes table
106 //
|
107 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
|
108 kumpf 1.1 (supportedClass, nameSpaces [i]);
|
109 kumpf 1.22 SubscriptionClassesTableEntry scTableValue;
110 if (_lockedLookupSubscriptionClassesEntry(
111 subscriptionClassesKey, scTableValue))
|
112 kumpf 1.1 {
|
113 kumpf 1.22 subscriptions = scTableValue.subscriptions;
|
114 kumpf 1.1 for (Uint32 j = 0; j < subscriptions.size (); j++)
115 {
116 Boolean match = true;
117
118 if (checkProvider)
119 {
120 //
|
121 carolann.graves 1.9 // Check if the provider who generated this indication
|
122 kumpf 1.1 // accepted this subscription
123 //
|
124 r.kieninger 1.15 String activeSubscriptionsKey =
|
125 kumpf 1.1 _generateActiveSubscriptionsKey
|
126 carolann.graves 1.10 (subscriptions [j].getPath ());
|
127 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
128 if (_lockedLookupActiveSubscriptionsEntry(
129 activeSubscriptionsKey, asTableValue))
|
130 kumpf 1.1 {
131 //
132 // If provider is not in list, it did not accept the
133 // subscription
134 //
|
135 kumpf 1.22 if ((providerInList(provider, asTableValue)) ==
136 PEG_NOT_FOUND)
|
137 kumpf 1.1 {
138 match = false;
139 break;
140 }
141 }
142 }
143
144 if (match)
145 {
146 //
147 // Add current subscription to list
148 //
149 matchingSubscriptions.append (subscriptions [j]);
150 }
151 }
152 }
153 }
154
155 PEG_METHOD_EXIT ();
156 return matchingSubscriptions;
157 }
158 kumpf 1.1
|
159 carolann.graves 1.12 Array <CIMInstance> SubscriptionTable::reflectProviderDisable (
|
160 aruran.ms 1.8 const CIMInstance & provider)
|
161 kumpf 1.1 {
162 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
163 carolann.graves 1.12 "SubscriptionTable::reflectProviderDisable");
|
164 kumpf 1.1
165 Array <CIMInstance> providerSubscriptions;
166
167 //
168 // Iterate through the subscription table to find subscriptions served by
169 // the provider
|
170 carolann.graves 1.9 // NOTE: updating entries (remove and insert) while iterating through the
|
171 kumpf 1.1 // table does not work reliably, and it is not clear if that is supposed to
|
172 carolann.graves 1.9 // work; for now, the SubscriptionTable first iterates through the
173 // active subscriptions table to find subscriptions served by the
174 // provider, then looks up and updates each affected subscription
|
175 kumpf 1.1 //
176 {
177 //
|
178 carolann.graves 1.9 // Acquire and hold the write lock during the entire
179 // lookup/remove/insert process, allowing competing threads to apply
180 // their logic over a consistent view of the data.
|
181 kumpf 1.14 // Do not call any other methods that need
|
182 carolann.graves 1.9 // _activeSubscriptionsTableLock.
|
183 kumpf 1.1 //
|
184 carolann.graves 1.9 WriteLock lock (_activeSubscriptionsTableLock);
|
185 kumpf 1.1
186 for (ActiveSubscriptionsTable::Iterator i =
187 _activeSubscriptionsTable.start (); i; i++)
188 {
189 //
190 // If provider matches, append subscription to the list
191 //
|
192 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue = i.value();
193 for (Uint32 j = 0; j < asTableValue.providers.size(); j++)
|
194 kumpf 1.1 {
|
195 kumpf 1.22 if (asTableValue.providers[j].provider.getPath().identical(
196 provider.getPath()))
|
197 kumpf 1.1 {
198 //
199 // Add the subscription to the list
200 //
|
201 kumpf 1.22 providerSubscriptions.append(asTableValue.subscription);
|
202 kumpf 1.1 break;
203 }
204 }
205 }
206
207 //
|
208 carolann.graves 1.9 // Look up and update hash table entry for each affected subscription
|
209 kumpf 1.1 //
|
210 carolann.graves 1.9 for (Uint32 k = 0; k < providerSubscriptions.size (); k++)
|
211 kumpf 1.1 {
212 //
|
213 carolann.graves 1.9 // Update the entry in the active subscriptions hash table
|
214 kumpf 1.1 //
|
215 r.kieninger 1.15 String activeSubscriptionsKey =
|
216 carolann.graves 1.10 _generateActiveSubscriptionsKey
217 (providerSubscriptions [k].getPath ());
|
218 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
219 if (_activeSubscriptionsTable.lookup(
220 activeSubscriptionsKey, asTableValue))
|
221 kumpf 1.1 {
|
222 carolann.graves 1.9 //
223 // Remove the provider from the list of providers serving the
224 // subscription
225 //
|
226 kumpf 1.22 Uint32 providerIndex = providerInList(provider, asTableValue);
|
227 carolann.graves 1.9 if (providerIndex != PEG_NOT_FOUND)
|
228 kumpf 1.1 {
|
229 kumpf 1.22 asTableValue.providers.remove(providerIndex);
|
230 carolann.graves 1.12
|
231 kumpf 1.22 _updateSubscriptionProviders(
232 activeSubscriptionsKey,
233 asTableValue.subscription,
234 asTableValue.providers);
|
235 carolann.graves 1.9 }
236 else
237 {
|
238 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL,Tracer::LEVEL2,
239 "Provider (%s) not found in list for Subscription (%s)"
240 " in ActiveSubscriptionsTable",
241 (const char*)provider.getPath().toString().getCString(),
242 (const char*)activeSubscriptionsKey.getCString()));
|
243 kumpf 1.1 }
244 }
245 else
246 {
|
247 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL,Tracer::LEVEL2,
248 "Subscription (%s) not found in ActiveSubscriptionsTable",
249 (const char*)activeSubscriptionsKey.getCString()));
|
250 carolann.graves 1.9 //
251 // The subscription may have been deleted in the mean time
252 // If so, no further update is required
253 //
|
254 kumpf 1.1 }
255 }
256 }
257
258 PEG_METHOD_EXIT ();
259 return providerSubscriptions;
260 }
261
|
262 carolann.graves 1.12 Array <ActiveSubscriptionsTableEntry>
263 SubscriptionTable::reflectProviderModuleFailure
264 (const String & moduleName,
265 const String & userName,
266 Boolean authenticationEnabled)
267 {
268 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
269 "SubscriptionTable::reflectProviderModuleFailure");
270
271 Array <ActiveSubscriptionsTableEntry> providerModuleSubscriptions;
272
273 //
274 // Iterate through the subscription table to find subscriptions served by
275 // a provider in the specified module, with the specified userName as the
276 // subscription creator
277 // NOTE: updating entries (remove and insert) while iterating through the
278 // table is not allowed
279 // The SubscriptionTable first iterates through the active subscriptions
280 // table to find matching subscriptions served by a provider in the
281 // specified module, then looks up and updates each affected subscription
282 //
283 carolann.graves 1.12 {
284 //
285 // Acquire and hold the write lock during the entire
286 // lookup/remove/insert process, allowing competing threads to apply
287 // their logic over a consistent view of the data.
|
288 kumpf 1.14 // Do not call any other methods that need
|
289 carolann.graves 1.12 // _activeSubscriptionsTableLock.
290 //
291 WriteLock lock (_activeSubscriptionsTableLock);
292
293 for (ActiveSubscriptionsTable::Iterator i =
294 _activeSubscriptionsTable.start (); i; i++)
295 {
|
296 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
|
297 carolann.graves 1.12 //
298 // Get subscription creator
299 //
|
300 kumpf 1.22 asTableValue = i.value();
|
301 carolann.graves 1.12 String creator;
|
302 kumpf 1.22 CIMValue creatorValue = asTableValue.subscription.getProperty(
303 asTableValue.subscription.findProperty(
304 PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue();
|
305 carolann.graves 1.12 creatorValue.get (creator);
306
307 Array <ProviderClassList> failedProviderList;
|
308 kumpf 1.22 for (Uint32 j = 0; j < asTableValue.providers.size(); j++)
|
309 carolann.graves 1.12 {
310 //
311 // Get provider module name
312 //
313 String providerModuleName;
314 CIMValue nameValue =
|
315 kumpf 1.22 asTableValue.providers[j].providerModule.getProperty(
316 asTableValue.providers[j].providerModule.findProperty(
317 PEGASUS_PROPERTYNAME_NAME)).getValue();
|
318 carolann.graves 1.12 nameValue.get (providerModuleName);
319
320 //
321 // Get module user context setting
322 //
323 Uint16 moduleContext = PEGASUS_DEFAULT_PROV_USERCTXT;
|
324 kumpf 1.14 CIMValue contextValue =
|
325 kumpf 1.22 asTableValue.providers[j].providerModule.getProperty(
326 asTableValue.providers [j].providerModule.findProperty(
327 PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT)).
328 getValue();
|
329 carolann.graves 1.12 if (!contextValue.isNull ())
330 {
331 contextValue.get (moduleContext);
332 }
333
334 //
|
335 kumpf 1.14 // If provider module name matches,
|
336 carolann.graves 1.12 // add provider to the list of failed providers
337 //
338 if (providerModuleName == moduleName)
339 {
340 //
341 // If authentication is enabled, and module was run as
342 // requestor, subscription creator must also match module
343 // user context name, to add provider to the list of
344 // failed providers
345 //
346 if ((moduleContext != PG_PROVMODULE_USERCTXT_REQUESTOR) ||
347 (!authenticationEnabled) || (creator == userName))
348 {
349 //
350 // Add the provider to the list
351 //
|
352 kumpf 1.22 failedProviderList.append(asTableValue.providers[j]);
|
353 carolann.graves 1.12 }
354 } // if provider module name matches
355 } // for each subscription provider
356
357 //
358 // If there were any failed providers, add the subscription
359 // entry to the list of affected subscriptions
360 //
361 if (failedProviderList.size () > 0)
362 {
363 ActiveSubscriptionsTableEntry subscription;
|
364 kumpf 1.22 subscription.subscription = asTableValue.subscription;
|
365 carolann.graves 1.12 subscription.providers = failedProviderList;
366 providerModuleSubscriptions.append (subscription);
367 }
368 }
369
370 //
371 // Look up and update hash table entry for each affected subscription
372 //
373 for (Uint32 k = 0; k < providerModuleSubscriptions.size (); k++)
374 {
375 //
376 // Update the entry in the active subscriptions hash table
377 //
|
378 r.kieninger 1.15 String activeSubscriptionsKey =
|
379 carolann.graves 1.12 _generateActiveSubscriptionsKey
380 (providerModuleSubscriptions [k].subscription.getPath ());
|
381 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
382 if (_activeSubscriptionsTable.lookup(
383 activeSubscriptionsKey, asTableValue))
|
384 carolann.graves 1.12 {
|
385 kumpf 1.14 Array <ProviderClassList> updatedProviderList;
|
386 kumpf 1.22 for (Uint32 l = 0; l < asTableValue.providers.size(); l++)
|
387 carolann.graves 1.12 {
388 String providerModuleName;
389 CIMValue nameValue =
|
390 kumpf 1.22 asTableValue.providers[l].providerModule.getProperty(
391 asTableValue.providers[l].providerModule.
392 findProperty(PEGASUS_PROPERTYNAME_NAME)).getValue();
|
393 carolann.graves 1.12 nameValue.get (providerModuleName);
394 if (providerModuleName != moduleName)
395 {
396 //
397 // Provider is not in the failed module
398 // Append provider to list of providers still serving
399 // the subscription
400 //
|
401 kumpf 1.22 updatedProviderList.append(asTableValue.providers[l]);
|
402 carolann.graves 1.12 }
403 }
404
|
405 kumpf 1.22 _updateSubscriptionProviders(
406 activeSubscriptionsKey,
407 asTableValue.subscription,
408 updatedProviderList);
|
409 carolann.graves 1.12 }
410 }
411 }
412
413 PEG_METHOD_EXIT ();
414 return providerModuleSubscriptions;
415 }
416
|
417 r.kieninger 1.15 String SubscriptionTable::_generateActiveSubscriptionsKey (
|
418 kumpf 1.1 const CIMObjectPath & subscription) const
419 {
420 //
|
421 carolann.graves 1.10 // Get filter and handler object paths from subscription Filter and Handler
422 // reference property values
|
423 kumpf 1.1 //
424 Array<CIMKeyBinding> subscriptionKB = subscription.getKeyBindings ();
|
425 r.kieninger 1.15 String filterPath;
426 String handlerPath;
|
427 kumpf 1.1 for (Uint32 i = 0; i < subscriptionKB.size (); i++)
428 {
|
429 w.otsuka 1.13 if ((subscriptionKB [i].getName () == PEGASUS_PROPERTYNAME_FILTER) &&
|
430 kumpf 1.1 (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
431 {
|
432 carolann.graves 1.10 filterPath = subscriptionKB [i].getValue ();
|
433 kumpf 1.1 }
|
434 r.kieninger 1.15 else
|
435 w.otsuka 1.13 if ((subscriptionKB [i].getName () == PEGASUS_PROPERTYNAME_HANDLER) &&
|
436 kumpf 1.1 (subscriptionKB [i].getType () == CIMKeyBinding::REFERENCE))
437 {
|
438 carolann.graves 1.10 handlerPath = subscriptionKB [i].getValue ();
|
439 kumpf 1.1 }
440 }
441
442 //
|
443 r.kieninger 1.15 // Construct subscription key from handler and filter.
444 // To avoid ambiguity, the hostname part is removed, since the
445 // hostname can only point to the local machine anyway.
|
446 kumpf 1.1 //
|
447 r.kieninger 1.15 const Char16 slash = '/';
448 if ((filterPath[0]==slash) && (filterPath[1]==slash))
449 {
450 Uint32 index = filterPath.find(2,slash);
451 filterPath = filterPath.subString(index+1);
452 }
453
454 if ((handlerPath[0]==slash) && (handlerPath[1]==slash))
455 {
456 Uint32 index = handlerPath.find(2,slash);
457 handlerPath = handlerPath.subString(index+1);
458 }
459
460 //
461 // Assuming that most subscriptions will differ in the filter and handler
|
462 yi.zhou 1.18 // names, the namespace and classname of the subscription are added at the
|
463 r.kieninger 1.15 // end of the key.
464 //
465 String activeSubscriptionsKey(filterPath);
466 activeSubscriptionsKey.append(handlerPath);
467 activeSubscriptionsKey.append(slash);
468 activeSubscriptionsKey.append(subscription.getNameSpace().getString());
469 activeSubscriptionsKey.append(slash);
470 activeSubscriptionsKey.append(subscription.getClassName().getString());
|
471 kumpf 1.1
472 return activeSubscriptionsKey;
473 }
474
475 Boolean SubscriptionTable::_lockedLookupActiveSubscriptionsEntry (
|
476 r.kieninger 1.15 const String & key,
|
477 aruran.ms 1.7 ActiveSubscriptionsTableEntry & tableEntry) const
|
478 kumpf 1.1 {
479 ReadLock lock(_activeSubscriptionsTableLock);
480
481 return (_activeSubscriptionsTable.lookup (key, tableEntry));
482 }
483
484 void SubscriptionTable::_insertActiveSubscriptionsEntry (
485 const CIMInstance & subscription,
|
486 aruran.ms 1.8 const Array <ProviderClassList> & providers)
|
487 kumpf 1.1 {
488 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
489 "SubscriptionTable::_insertActiveSubscriptionsEntry");
490
|
491 r.kieninger 1.15 String activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
492 kumpf 1.1 (subscription.getPath ());
493 ActiveSubscriptionsTableEntry entry;
494 entry.subscription = subscription;
495 entry.providers = providers;
496
|
497 carolann.graves 1.10 //
498 // Insert returns true on success, false if duplicate key
499 //
500 Boolean succeeded = _activeSubscriptionsTable.insert
501 (activeSubscriptionsKey, entry);
502 PEGASUS_ASSERT (succeeded);
|
503 kumpf 1.1
504 #ifdef PEGASUS_INDICATION_HASHTRACE
505 String traceString;
506 traceString.append (activeSubscriptionsKey);
507 traceString.append (" Providers: ");
508 for (Uint32 i = 0; i < providers.size (); i++)
509 {
|
510 carolann.graves 1.9 String providerName = providers [i].provider.getProperty
511 (providers [i].provider.findProperty
|
512 w.otsuka 1.13 (PEGASUS_PROPERTYNAME_NAME)).getValue ().toString ();
|
513 kumpf 1.1 traceString.append (providerName);
514 traceString.append (" Classes: ");
515 for (Uint32 j = 0; j < providers[i].classList.size (); j++)
516 {
|
517 carolann.graves 1.9 traceString.append (providers[i].classList[j].getString());
|
518 kumpf 1.1 traceString.append (" ");
519 }
520 }
|
521 carolann.graves 1.9
|
522 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL4,
523 "INSERTED _activeSubscriptionsTable entry: %s",
524 (const char*)traceString.getCString()));
|
525 kumpf 1.1 #endif
526
527 PEG_METHOD_EXIT ();
528 }
529
530 void SubscriptionTable::_removeActiveSubscriptionsEntry (
|
531 r.kieninger 1.15 const String & key)
|
532 kumpf 1.1 {
533 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
534 "SubscriptionTable::_removeActiveSubscriptionsEntry");
535
|
536 carolann.graves 1.10 //
537 // Remove returns true on success, false if not found
538 //
539 Boolean succeeded = _activeSubscriptionsTable.remove (key);
540 PEGASUS_ASSERT (succeeded);
541
|
542 kumpf 1.1 #ifdef PEGASUS_INDICATION_HASHTRACE
|
543 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL,Tracer::LEVEL4,
544 "REMOVED _activeSubscriptionsTable entry: %s",
545 (const char*)key.getCString()));
|
546 kumpf 1.1 #endif
547
548 PEG_METHOD_EXIT ();
549 }
550
551 String SubscriptionTable::_generateSubscriptionClassesKey (
552 const CIMName & indicationClassName,
553 const CIMNamespaceName & sourceNamespaceName) const
554 {
555 String subscriptionClassesKey;
556
557 //
558 // Append indication class name to key
559 //
560 subscriptionClassesKey.append (indicationClassName.getString ());
561
562 //
563 // Append source namespace name to key
564 //
565 subscriptionClassesKey.append (sourceNamespaceName.getString ());
566
567 kumpf 1.1 return subscriptionClassesKey;
568 }
569
570 Boolean SubscriptionTable::_lockedLookupSubscriptionClassesEntry (
571 const String & key,
|
572 aruran.ms 1.7 SubscriptionClassesTableEntry & tableEntry) const
|
573 kumpf 1.1 {
574 ReadLock lock(_subscriptionClassesTableLock);
575
576 return (_subscriptionClassesTable.lookup (key, tableEntry));
577 }
578
|
579 carolann.graves 1.9 void SubscriptionTable::_insertSubscriptionClassesEntry (
|
580 kumpf 1.1 const CIMName & indicationClassName,
581 const CIMNamespaceName & sourceNamespaceName,
582 const Array <CIMInstance> & subscriptions)
583 {
584 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
585 carolann.graves 1.9 "SubscriptionTable::_insertSubscriptionClassesEntry");
|
586 kumpf 1.1
587 String subscriptionClassesKey = _generateSubscriptionClassesKey
588 (indicationClassName, sourceNamespaceName);
589 SubscriptionClassesTableEntry entry;
590 entry.indicationClassName = indicationClassName;
591 entry.sourceNamespaceName = sourceNamespaceName;
592 entry.subscriptions = subscriptions;
|
593 carolann.graves 1.9
|
594 carolann.graves 1.10 //
595 // Insert returns true on success, false if duplicate key
596 //
597 Boolean succeeded = _subscriptionClassesTable.insert
598 (subscriptionClassesKey, entry);
599 PEGASUS_ASSERT (succeeded);
|
600 kumpf 1.1
601 #ifdef PEGASUS_INDICATION_HASHTRACE
602 String traceString;
603 traceString.append (subscriptionClassesKey);
604 traceString.append (" Subscriptions: ");
605 for (Uint32 i = 0; i < subscriptions.size (); i++)
606 {
|
607 carolann.graves 1.9 traceString.append (subscriptions [i].getPath ().toString());
|
608 kumpf 1.1 traceString.append (" ");
609 }
|
610 carolann.graves 1.9
|
611 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL4,
612 "INSERTED _subscriptionClassesTable entry: %s",
613 (const char*)traceString.getCString()));
|
614 kumpf 1.1 #endif
615
616 PEG_METHOD_EXIT ();
617 }
618
|
619 carolann.graves 1.9 void SubscriptionTable::_removeSubscriptionClassesEntry (
|
620 kumpf 1.1 const String & key)
621 {
622 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
|
623 carolann.graves 1.9 "SubscriptionTable::_removeSubscriptionClassesEntry");
|
624 kumpf 1.1
|
625 carolann.graves 1.10 //
626 // Remove returns true on success, false if not found
627 //
628 Boolean succeeded = _subscriptionClassesTable.remove (key);
629 PEGASUS_ASSERT (succeeded);
|
630 kumpf 1.1
631 #ifdef PEGASUS_INDICATION_HASHTRACE
|
632 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL4,
633 "REMOVED _subscriptionClassesTable entry: %s",
634 (const char*)key.getCString()));
|
635 kumpf 1.1 #endif
636
637 PEG_METHOD_EXIT ();
638 }
639
|
640 carolann.graves 1.12 void SubscriptionTable::_updateSubscriptionProviders
|
641 r.kieninger 1.15 (const String & activeSubscriptionsKey,
|
642 carolann.graves 1.12 const CIMInstance & subscription,
643 const Array <ProviderClassList> & updatedProviderList)
644 {
645 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
646 "SubscriptionTable::_updateSubscriptionProviders");
647
648 if (updatedProviderList.size () > 0)
649 {
650 //
651 // At least one provider is still serving the
652 // subscription
653 // Update entry in Active Subscriptions table
654 //
655 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
656 _insertActiveSubscriptionsEntry (subscription, updatedProviderList);
657 }
658 else
659 {
660 //
661 // The disabled or failed provider(s) was (were) the only provider(s)
662 // serving the subscription
663 carolann.graves 1.12 // Implement the subscription's On Fatal Error Policy
664 //
665 Boolean removedOrDisabled =
666 _subscriptionRepository->reconcileFatalError (subscription);
667 _removeActiveSubscriptionsEntry (activeSubscriptionsKey);
668 if (!removedOrDisabled)
669 {
670 //
671 // If subscription was not disabled or deleted
672 // Update entry in Active Subscriptions table
673 // Note that in this case the updatedProviderList is
674 // empty - no providers are serving the subscription
675 // currently
676 //
677 _insertActiveSubscriptionsEntry (subscription,
678 updatedProviderList);
679 }
|
680 s.kodali 1.19 else
681 {
682 // Delete subscription entries from SubscriptionClassesTable.
683 WriteLock lock(_subscriptionClassesTableLock);
|
684 kumpf 1.22 Array<SubscriptionClassesTableEntry> scTableValues;
|
685 s.kodali 1.19 for (SubscriptionClassesTable::Iterator i =
686 _subscriptionClassesTable.start(); i; i++)
687 {
688 SubscriptionClassesTableEntry value = i.value();
689 for (Uint32 j = 0, n = value.subscriptions.size(); j < n; ++j)
690 {
691 if (value.subscriptions[j].getPath().identical(
692 subscription.getPath()))
693 {
694 value.subscriptions.remove(j);
|
695 kumpf 1.22 scTableValues.append(value);
|
696 s.kodali 1.19 break;
697 }
698 }
699 }
|
700 kumpf 1.22 for (Uint32 i = 0, n = scTableValues.size(); i < n; ++i)
|
701 s.kodali 1.19 {
702 String subscriptionClassesKey = _generateSubscriptionClassesKey(
|
703 kumpf 1.22 scTableValues[i].indicationClassName,
704 scTableValues[i].sourceNamespaceName);
|
705 s.kodali 1.19 // If this is the only subscription for this class-namespace
706 // pair delete the entry else update the subscription list
707 // for this class-namespace pair.
|
708 kumpf 1.22 if (scTableValues[i].subscriptions.size())
|
709 s.kodali 1.19 {
710 SubscriptionClassesTableEntry *entry = 0;
711 _subscriptionClassesTable.lookupReference(
712 subscriptionClassesKey,
713 entry);
714 PEGASUS_ASSERT(entry);
|
715 kumpf 1.22 entry->subscriptions = scTableValues[i].subscriptions;
|
716 s.kodali 1.19 }
717 else
718 {
719 _removeSubscriptionClassesEntry(subscriptionClassesKey);
720 }
721 }
722 }
|
723 carolann.graves 1.12 }
724
725 PEG_METHOD_EXIT ();
726 }
727
|
728 carolann.graves 1.6 void SubscriptionTable::insertSubscription (
|
729 kumpf 1.1 const CIMInstance & subscription,
730 const Array <ProviderClassList> & providers,
731 const Array <CIMName> & indicationSubclassNames,
732 const CIMNamespaceName & sourceNamespaceName)
733 {
734 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
735 "SubscriptionTable::insertSubscription");
736
737 //
|
738 carolann.graves 1.9 // Insert entry into active subscriptions table
|
739 kumpf 1.1 //
740 {
741 WriteLock lock(_activeSubscriptionsTableLock);
742
|
743 yi.zhou 1.17 _insertActiveSubscriptionsEntry(subscription, providers);
|
744 kumpf 1.1 }
745
746 //
|
747 carolann.graves 1.9 // Insert or update entries in subscription classes table
|
748 kumpf 1.1 //
749 {
|
750 carolann.graves 1.9 //
751 // Acquire and hold the write lock during the entire
752 // lookup/remove/insert process, allowing competing threads to apply
753 // their logic over a consistent view of the data.
|
754 kumpf 1.14 // Do not call any other methods that need
|
755 carolann.graves 1.9 // _subscriptionClassesTableLock.
756 //
757 WriteLock lock (_subscriptionClassesTableLock);
758 for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
|
759 kumpf 1.1 {
|
760 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
761 (indicationSubclassNames [i], sourceNamespaceName);
|
762 kumpf 1.22 SubscriptionClassesTableEntry scTableValue;
763 if (_subscriptionClassesTable.lookup(
764 subscriptionClassesKey, scTableValue))
|
765 carolann.graves 1.9 {
766 //
767 // If entry exists for this IndicationClassName-SourceNamespace
768 // pair, remove old entry and insert new entry
769 //
|
770 kumpf 1.22 Array<CIMInstance> subscriptions = scTableValue.subscriptions;
|
771 carolann.graves 1.9 subscriptions.append (subscription);
772 _removeSubscriptionClassesEntry (subscriptionClassesKey);
773 _insertSubscriptionClassesEntry (indicationSubclassNames [i],
774 sourceNamespaceName, subscriptions);
775 }
776 else
777 {
778 //
779 // If no entry exists for this
780 // IndicationClassName-SourceNamespace pair, insert new entry
781 //
782 Array <CIMInstance> subscriptions;
783 subscriptions.append (subscription);
784 _insertSubscriptionClassesEntry (indicationSubclassNames [i],
785 sourceNamespaceName, subscriptions);
786 }
|
787 kumpf 1.1 }
788 }
789
790 PEG_METHOD_EXIT ();
791 }
792
|
793 carolann.graves 1.6 void SubscriptionTable::updateProviders (
|
794 kumpf 1.1 const CIMObjectPath & subscriptionPath,
795 const ProviderClassList & provider,
796 Boolean addProvider)
797 {
798 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
799 "SubscriptionTable::updateProviders");
800
|
801 r.kieninger 1.15 String activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
802 kumpf 1.1 (subscriptionPath);
|
803 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
|
804 kumpf 1.1 {
|
805 carolann.graves 1.9 //
806 // Acquire and hold the write lock during the entire
807 // lookup/remove/insert process, allowing competing threads to apply
808 // their logic over a consistent view of the data.
|
809 kumpf 1.14 // Do not call any other methods that need
|
810 carolann.graves 1.9 // _activeSubscriptionsTableLock.
811 //
812 WriteLock lock (_activeSubscriptionsTableLock);
|
813 kumpf 1.22 if (_activeSubscriptionsTable.lookup(
814 activeSubscriptionsKey, asTableValue))
|
815 kumpf 1.1 {
|
816 kumpf 1.22 Uint32 providerIndex =
817 providerInList(provider.provider, asTableValue);
|
818 carolann.graves 1.9 if (addProvider)
|
819 kumpf 1.1 {
|
820 carolann.graves 1.9 if (providerIndex == PEG_NOT_FOUND)
821 {
|
822 kumpf 1.22 asTableValue.providers.append(provider);
823 _removeActiveSubscriptionsEntry(activeSubscriptionsKey);
824 _insertActiveSubscriptionsEntry(
825 asTableValue.subscription,
826 asTableValue.providers);
|
827 carolann.graves 1.9 }
828 else
829 {
830 CIMInstance p = provider.provider;
|
831 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL,Tracer::LEVEL2,
832 "Provider %s already in list for Subscription (%s) "
833 "in ActiveSubscriptionsTable",
834 (const char*)IndicationService::getProviderLogString(p)
835 .getCString(),
836 (const char*)activeSubscriptionsKey.getCString()));
|
837 carolann.graves 1.9 }
|
838 kumpf 1.1 }
839 else
840 {
|
841 carolann.graves 1.9 if (providerIndex != PEG_NOT_FOUND)
842 {
|
843 kumpf 1.22 asTableValue.providers.remove(providerIndex);
844 _removeActiveSubscriptionsEntry(activeSubscriptionsKey);
845 _insertActiveSubscriptionsEntry(
846 asTableValue.subscription,
847 asTableValue.providers);
|
848 carolann.graves 1.9 }
849 else
850 {
851 CIMInstance p = provider.provider;
|
852 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL,Tracer::LEVEL2,
853 "Provider %s not found in list for Subscription (%s) "
854 "in ActiveSubscriptionsTable",
855 (const char*)IndicationService::getProviderLogString(p)
856 .getCString(),
857 (const char*)activeSubscriptionsKey.getCString()));
|
858 carolann.graves 1.9 }
|
859 kumpf 1.1 }
860 }
861 else
862 {
|
863 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL2,
864 "Subscription (%s) not found in ActiveSubscriptionsTable",
865 (const char*)activeSubscriptionsKey.getCString()));
|
866 kumpf 1.14
|
867 carolann.graves 1.9 //
868 // The subscription may have been deleted in the mean time
869 // If so, no further update is required
870 //
|
871 kumpf 1.1 }
872 }
873
874 PEG_METHOD_EXIT ();
875 }
876
877 void SubscriptionTable::updateClasses (
878 const CIMObjectPath & subscriptionPath,
879 const CIMInstance & provider,
880 const CIMName & className)
881 {
882 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
883 "SubscriptionTable::updateClasses");
884
|
885 r.kieninger 1.15 String activeSubscriptionsKey = _generateActiveSubscriptionsKey
|
886 kumpf 1.1 (subscriptionPath);
|
887 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
|
888 kumpf 1.1
889 {
|
890 carolann.graves 1.9 //
891 // Acquire and hold the write lock during the entire
892 // lookup/remove/insert process, allowing competing threads to apply
893 // their logic over a consistent view of the data.
|
894 kumpf 1.14 // Do not call any other methods that need
|
895 carolann.graves 1.9 // _activeSubscriptionsTableLock.
896 //
897 WriteLock lock (_activeSubscriptionsTableLock);
|
898 kumpf 1.22 if (_activeSubscriptionsTable.lookup(
899 activeSubscriptionsKey, asTableValue))
|
900 kumpf 1.1 {
|
901 kumpf 1.22 Uint32 providerIndex = providerInList(provider, asTableValue);
|
902 carolann.graves 1.9 if (providerIndex != PEG_NOT_FOUND)
|
903 kumpf 1.1 {
|
904 kumpf 1.22 Uint32 classIndex = classInList(
905 className, asTableValue.providers[providerIndex]);
|
906 carolann.graves 1.9 if (classIndex == PEG_NOT_FOUND)
907 {
|
908 kumpf 1.22 asTableValue.providers[providerIndex].classList.append(
909 className);
|
910 carolann.graves 1.9 }
911 else // classIndex != PEG_NOT_FOUND
912 {
|
913 kumpf 1.22 asTableValue.providers[providerIndex].classList.remove(
914 classIndex);
|
915 carolann.graves 1.9 }
916
|
917 kumpf 1.22 _removeActiveSubscriptionsEntry(activeSubscriptionsKey);
918 _insertActiveSubscriptionsEntry(
919 asTableValue.subscription,
920 asTableValue.providers);
|
921 kumpf 1.1 }
|
922 carolann.graves 1.9 else
|
923 kumpf 1.1 {
|
924 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL,Tracer::LEVEL2,
925 "Provider (%s) not found in list for Subscription (%s) in "
926 "ActiveSubscriptionsTable",
927 (const char*)provider.getPath().toString().getCString(),
928 (const char*)activeSubscriptionsKey.getCString()));
|
929 kumpf 1.1 }
930 }
931 else
932 {
|
933 carolann.graves 1.9 //
934 // Subscription not found in Active Subscriptions table
935 //
|
936 kumpf 1.1 }
937 }
938
939 PEG_METHOD_EXIT ();
940 }
941
|
942 carolann.graves 1.6 void SubscriptionTable::removeSubscription (
|
943 kumpf 1.1 const CIMInstance & subscription,
944 const Array <CIMName> & indicationSubclassNames,
945 const CIMNamespaceName & sourceNamespaceName,
946 const Array <ProviderClassList> & providers)
947 {
948 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
949 "SubscriptionTable::removeSubscription");
950
951 //
|
952 carolann.graves 1.9 // Remove entry from active subscriptions table
|
953 kumpf 1.1 //
954 {
955 WriteLock lock(_activeSubscriptionsTableLock);
956
957 _removeActiveSubscriptionsEntry (
958 _generateActiveSubscriptionsKey (subscription.getPath ()));
959 }
960
961 //
|
962 carolann.graves 1.9 // Remove or update entries in subscription classes table
|
963 kumpf 1.1 //
964 {
|
965 carolann.graves 1.9 //
966 // Acquire and hold the write lock during the entire
967 // lookup/remove/insert process, allowing competing threads to apply
968 // their logic over a consistent view of the data.
|
969 kumpf 1.14 // Do not call any other methods that need
|
970 carolann.graves 1.9 // _subscriptionClassesTableLock.
971 //
972 WriteLock lock (_subscriptionClassesTableLock);
973 for (Uint32 i = 0; i < indicationSubclassNames.size (); i++)
|
974 kumpf 1.1 {
|
975 carolann.graves 1.9 String subscriptionClassesKey = _generateSubscriptionClassesKey
976 (indicationSubclassNames [i], sourceNamespaceName);
|
977 kumpf 1.22 SubscriptionClassesTableEntry scTableValue;
978 if (_subscriptionClassesTable.lookup(
979 subscriptionClassesKey, scTableValue))
|
980 carolann.graves 1.9 {
981 //
982 // If entry exists for this IndicationClassName-SourceNamespace
983 // pair, remove subscription from the list
984 //
|
985 kumpf 1.22 Array<CIMInstance> subscriptions = scTableValue.subscriptions;
|
986 carolann.graves 1.9 for (Uint32 j = 0; j < subscriptions.size (); j++)
987 {
988 if (subscriptions [j].getPath().identical
989 (subscription.getPath()))
990 {
991 subscriptions.remove (j);
992 }
993 }
|
994 kumpf 1.14
|
995 carolann.graves 1.9 //
996 // Remove the old entry
997 //
998 _removeSubscriptionClassesEntry (subscriptionClassesKey);
|
999 kumpf 1.14
|
1000 carolann.graves 1.9 //
1001 // If there are still subscriptions in the list, insert the
1002 // new entry
1003 //
1004 if (subscriptions.size () > 0)
|
1005 kumpf 1.1 {
|
1006 carolann.graves 1.9 _insertSubscriptionClassesEntry (
1007 indicationSubclassNames [i],
1008 sourceNamespaceName, subscriptions);
|
1009 kumpf 1.1 }
1010 }
|
1011 carolann.graves 1.9 else
|
1012 kumpf 1.1 {
|
1013 carolann.graves 1.9 //
1014 // Entry not found in Subscription Classes table
1015 //
|
1016 thilo.boehm 1.23 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL,Tracer::LEVEL2,
1017 "Indication subclass and namespace (%s) not found "
1018 "in SubscriptionClassesTable",
1019 (const char*)subscriptionClassesKey.getCString()));
|
1020 kumpf 1.1 }
1021 }
1022 }
1023
1024 PEG_METHOD_EXIT ();
1025 }
1026
|
1027 carolann.graves 1.9 Uint32 SubscriptionTable::providerInList
1028 (const CIMInstance & provider,
|
1029 kumpf 1.1 const ActiveSubscriptionsTableEntry & tableValue) const
1030 {
1031 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
1032 "SubscriptionTable::providerInList");
1033
1034 //
1035 // Look for the provider in the list
1036 //
1037 for (Uint32 i = 0; i < tableValue.providers.size (); i++)
1038 {
|
1039 carolann.graves 1.9 if (tableValue.providers [i].provider.getPath ().identical
|
1040 kumpf 1.1 (provider.getPath ()))
1041 {
|
1042 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
1043 kumpf 1.1 return i;
1044 }
1045 }
1046
|
1047 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
1048 kumpf 1.1 return PEG_NOT_FOUND;
1049 }
1050
1051
|
1052 carolann.graves 1.9 Uint32 SubscriptionTable::classInList
1053 (const CIMName & className,
|
1054 kumpf 1.1 const ProviderClassList & providerClasses) const
1055 {
1056 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::classInList");
1057
1058 //
1059 // Look for the class in the list
1060 //
1061 for (Uint32 i = 0; i < providerClasses.classList.size (); i++)
1062 {
1063 if (providerClasses.classList [i].equal (className))
1064 {
|
1065 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
1066 kumpf 1.1 return i;
1067 }
1068 }
1069
|
1070 gs.keenan 1.4 PEG_METHOD_EXIT ();
|
1071 kumpf 1.1 return PEG_NOT_FOUND;
1072 }
1073
|
1074 kumpf 1.2 void SubscriptionTable::clear ()
1075 {
1076 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "SubscriptionTable::clear");
1077
1078 {
1079 WriteLock lock (_activeSubscriptionsTableLock);
1080 _activeSubscriptionsTable.clear ();
1081 }
1082 {
1083 WriteLock lock (_subscriptionClassesTableLock);
1084 _subscriptionClassesTable.clear ();
1085 }
1086
1087 PEG_METHOD_EXIT ();
1088 }
1089
|
1090 yi.zhou 1.17 void SubscriptionTable::getMatchingClassNamespaceSubscriptions(
|
1091 yi.zhou 1.16 const CIMName & supportedClass,
1092 const CIMNamespaceName & nameSpace,
|
1093 yi.zhou 1.17 const CIMInstance& provider,
1094 Array<CIMInstance>& matchingSubscriptions,
1095 Array<String>& matchingSubscriptionKeys)
|
1096 yi.zhou 1.16 {
1097 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
1098 "SubscriptionTable::getMatchingClassNamespaceSubscriptions");
1099
1100 Array <CIMInstance> subscriptions;
|
1101 yi.zhou 1.17 matchingSubscriptions.clear();
1102 matchingSubscriptionKeys.clear();
|
1103 yi.zhou 1.16
1104 //
1105 // Look up the indicationClass-sourceNamespace pair in the
1106 // Subscription Classes table
1107 //
1108 String subscriptionClassesKey = _generateSubscriptionClassesKey
1109 (supportedClass, nameSpace);
|
1110 kumpf 1.22 SubscriptionClassesTableEntry scTableValue;
1111 if (_lockedLookupSubscriptionClassesEntry(
1112 subscriptionClassesKey, scTableValue))
|
1113 yi.zhou 1.16 {
|
1114 kumpf 1.22 subscriptions = scTableValue.subscriptions;
|
1115 yi.zhou 1.16 for (Uint32 j = 0; j < subscriptions.size (); j++)
1116 {
1117 //
1118 // Check if the provider who generated this indication
1119 // accepted this subscription
1120 //
1121 String activeSubscriptionsKey =
1122 _generateActiveSubscriptionsKey
1123 (subscriptions [j].getPath ());
|
1124 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
1125 if (_lockedLookupActiveSubscriptionsEntry(
1126 activeSubscriptionsKey, asTableValue))
|
1127 yi.zhou 1.16 {
1128 //
1129 // If provider is in list, the subscription is acceptted
1130 //
|
1131 kumpf 1.22 if ((providerInList(provider, asTableValue)) != PEG_NOT_FOUND)
|
1132 yi.zhou 1.16 {
1133 //
1134 // Add current subscription to list
1135 //
|
1136 yi.zhou 1.17 matchingSubscriptions.append(subscriptions[j]);
1137 matchingSubscriptionKeys.append(activeSubscriptionsKey);
|
1138 yi.zhou 1.16 }
1139 }
1140 }
1141 }
1142
|
1143 yi.zhou 1.17 PEGASUS_ASSERT(
1144 matchingSubscriptions.size() == matchingSubscriptionKeys.size());
|
1145 yi.zhou 1.16 PEG_METHOD_EXIT ();
1146 }
1147
|
1148 yi.zhou 1.17 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
1149
1150 void SubscriptionTable::updateMatchedIndicationCounts(
1151 const CIMInstance & providerInstance,
1152 const Array<String>& activeSubscriptionsKeys)
1153 {
1154 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1155 "SubscriptionTable::updateMatchedIndicationCounts");
1156
1157 WriteLock lock(_activeSubscriptionsTableLock);
1158
1159 for (Uint32 i = 0; i < activeSubscriptionsKeys.size(); i++)
1160 {
1161 ActiveSubscriptionsTableEntry* entry = 0;
1162 if (_activeSubscriptionsTable.lookupReference(
1163 activeSubscriptionsKeys[i], entry))
1164 {
1165 Uint32 providerIndex = providerInList(providerInstance, *entry);
1166 if (providerIndex != PEG_NOT_FOUND)
1167 {
1168 entry->providers[providerIndex].
1169 yi.zhou 1.17 matchedIndCountPerSubscription++;
1170 }
1171 }
1172 else
1173 {
1174 // The subscription may have been deleted in the mean time.
1175 // If so, no further update is required.
1176 PEG_TRACE((TRC_INDICATION_SERVICE_INTERNAL, Tracer::LEVEL2,
1177 "Subscription %s not found in ActiveSubscriptionsTable",
1178 (const char *) activeSubscriptionsKeys[i].getCString()));
1179 }
1180 }
1181 PEG_METHOD_EXIT();
1182 }
1183
1184 Array<ActiveSubscriptionsTableEntry>
1185 SubscriptionTable::_getAllActiveSubscriptionEntries()
1186 {
1187 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1188 "SubscriptionTable::_getAllActiveSubscriptionEntries");
1189
1190 yi.zhou 1.17 Array <ActiveSubscriptionsTableEntry> subscriptionsEntries;
1191
1192 //
1193 // Iterate through the ActiveSubscriptions table to get all active
1194 // subscriptions table entries
1195 //
1196
1197 ReadLock lock(_activeSubscriptionsTableLock);
1198
1199 for (ActiveSubscriptionsTable::Iterator i =
1200 _activeSubscriptionsTable.start(); i; i++)
1201 {
1202 subscriptionsEntries.append(i.value());
1203 }
1204
1205 PEG_METHOD_EXIT();
1206 return subscriptionsEntries;
1207 }
1208
1209 Array<CIMInstance>
1210 SubscriptionTable::enumerateSubscriptionIndicationDataInstances()
1211 yi.zhou 1.17 {
1212 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1213 "SubscriptionTable::enumerateSubscriptionIndicationDataInstances");
1214
1215 Array<CIMInstance> instances;
1216
1217 //
1218 // Get all active subscriptions table entries
1219 //
1220 Array<ActiveSubscriptionsTableEntry> activeSubscriptionEntries =
1221 _getAllActiveSubscriptionEntries();
1222
1223 for (Uint32 i = 0; i < activeSubscriptionEntries.size(); i++)
1224 {
1225 //
1226 // Gets filter name and handler name of the subscription
1227 //
1228 CIMInstance subscription = activeSubscriptionEntries[i].subscription;
1229 String sourceNS = subscription.getPath().getNameSpace().getString();
1230
1231 String filterName;
1232 yi.zhou 1.17 String handlerName;
1233 _getFilterAndHandlerNames(subscription, filterName, handlerName);
1234
1235 Array<ProviderClassList> providers =
1236 activeSubscriptionEntries[i].providers;
1237
1238 for (Uint32 j = 0; j < providers.size(); j++)
1239 {
|
1240 yi.zhou 1.18 //
1241 // Gets provider name and provider module name
1242 //
1243 String providerName, providerModuleName;
1244 ProviderIndicationCountTable::getProviderKeys(
1245 providers[j].provider,
1246 providerModuleName,
1247 providerName);
1248
1249 CIMInstance subscriptionIndDataInstance =
1250 _buildSubscriptionIndDataInstance(
1251 filterName,
1252 handlerName,
1253 sourceNS,
1254 providerModuleName,
1255 providerName,
1256 providers[j].matchedIndCountPerSubscription);
1257
1258 instances.append(subscriptionIndDataInstance);
1259 }
1260 }
1261 yi.zhou 1.18
1262 PEG_METHOD_EXIT();
1263 return instances;
1264 }
1265
1266 Array<CIMObjectPath>
1267 SubscriptionTable::enumerateSubscriptionIndicationDataInstanceNames()
1268 {
1269 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1270 "SubscriptionTable::enumerateSubscriptionIndicationDataInstanceNames");
1271
1272 Array<CIMObjectPath> instanceNames;
1273
1274 //
1275 // Get all active subscriptions table entries
1276 //
1277 Array<ActiveSubscriptionsTableEntry> activeSubscriptionEntries =
1278 _getAllActiveSubscriptionEntries();
1279
1280 for (Uint32 i = 0; i < activeSubscriptionEntries.size(); i++)
1281 {
1282 yi.zhou 1.18 //
1283 // Gets filter name and handler name of the subscription
1284 //
1285 CIMInstance subscription = activeSubscriptionEntries[i].subscription;
1286 String sourceNS = subscription.getPath().getNameSpace().getString();
1287
1288 String filterName;
1289 String handlerName;
1290 _getFilterAndHandlerNames(subscription, filterName, handlerName);
|
1291 yi.zhou 1.17
|
1292 yi.zhou 1.18 Array<ProviderClassList> providers =
1293 activeSubscriptionEntries[i].providers;
|
1294 yi.zhou 1.17
|
1295 yi.zhou 1.18 for (Uint32 j = 0; j < providers.size(); j++)
1296 {
|
1297 yi.zhou 1.17 //
|
1298 yi.zhou 1.18 // Gets provider name and provider module name
|
1299 yi.zhou 1.17 //
1300 String providerName, providerModuleName;
1301 ProviderIndicationCountTable::getProviderKeys(
|
1302 yi.zhou 1.18 providers[j].provider,
1303 providerModuleName,
1304 providerName);
1305
1306 CIMObjectPath path = _buildSubscriptionIndDataInstanceName(
1307 filterName,
1308 handlerName,
1309 sourceNS,
|
1310 yi.zhou 1.17 providerModuleName,
1311 providerName);
1312
|
1313 yi.zhou 1.18 instanceNames.append(path);
1314 }
1315 }
|
1316 yi.zhou 1.17
|
1317 yi.zhou 1.18 PEG_METHOD_EXIT();
1318 return instanceNames;
1319 }
1320
1321 CIMInstance SubscriptionTable::getSubscriptionIndicationDataInstance(
1322 const CIMObjectPath& instanceName)
1323 {
1324 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1325 "SubscriptionTable::getSubscriptionIndicationDataInstance");
1326
1327 String filterName;
1328 String handlerName;
1329 String sourceNS;
1330 String specifiedProviderModuleName;
1331 String specifiedProviderName;
1332
1333 //
1334 // Gets handler name, filter name, source namespace, provider module name,
1335 // and provider name from a PG_SubscriptionIndicationData instanceName
1336 //
1337 _getSubscriptionIndicationDataKeys(
1338 yi.zhou 1.18 instanceName,
1339 filterName,
1340 handlerName,
1341 sourceNS,
1342 specifiedProviderModuleName,
1343 specifiedProviderName);
1344
1345 // Builds the PG_Provider object path
1346 CIMObjectPath providerName = _buildProviderPath(
1347 specifiedProviderModuleName, specifiedProviderName);
1348
1349 //
1350 // Builds subscription path by using the specified parameters
1351 //
1352 CIMObjectPath subscriptionPath = _buildSubscriptionPath(
1353 filterName, handlerName, sourceNS);
1354
1355 //
1356 // Look up the subscription in the active subscriptions table
1357 //
|
1358 kumpf 1.22 ActiveSubscriptionsTableEntry asTableValue;
1359 if (getSubscriptionEntry(subscriptionPath, asTableValue))
|
1360 yi.zhou 1.18 {
|
1361 kumpf 1.22 Array<ProviderClassList> providers = asTableValue.providers;
|
1362 yi.zhou 1.18 for (Uint32 i = 0; i < providers.size(); i++)
1363 {
1364 if (providerName.identical(providers[i].provider.getPath()))
1365 {
1366 CIMInstance subIndDataInstance =
1367 _buildSubscriptionIndDataInstance(
1368 filterName,
1369 handlerName,
1370 sourceNS,
1371 specifiedProviderModuleName,
1372 specifiedProviderName,
1373 providers[i].matchedIndCountPerSubscription);
1374
1375 PEG_METHOD_EXIT();
1376 return subIndDataInstance;
1377 }
|
1378 yi.zhou 1.17 }
1379 }
1380
1381 PEG_METHOD_EXIT();
|
1382 yi.zhou 1.18 throw CIMObjectNotFoundException(instanceName.toString());
|
1383 yi.zhou 1.17 }
1384
1385 void SubscriptionTable::_getFilterAndHandlerNames(
1386 const CIMInstance& subscription,
1387 String& filterName,
1388 String& handlerName)
1389 {
1390 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1391 "SubscriptionTable::_getFilterAndHandlerNames");
1392
1393 CIMObjectPath filterPath;
1394 CIMObjectPath handlerPath;
1395
1396 subscription.getProperty(subscription.findProperty(
1397 PEGASUS_PROPERTYNAME_FILTER)).getValue().get(filterPath);
1398 subscription.getProperty(subscription.findProperty(
1399 PEGASUS_PROPERTYNAME_HANDLER)).getValue().get(handlerPath);
1400
1401 //
1402 // Get Filter namespace - if not set in Filter reference property
1403 // value, namespace is the namespace of the subscription
1404 yi.zhou 1.17 //
1405 CIMNamespaceName filterNS = filterPath.getNameSpace();
1406 if (filterNS.isNull())
1407 {
1408 filterNS = subscription.getPath().getNameSpace();
1409 }
1410
1411 //
1412 // Get filter name
1413 //
1414 Array<CIMKeyBinding> filterKeyBindings = filterPath.getKeyBindings();
1415 for (Uint32 i = 0; i < filterKeyBindings.size(); i++)
1416 {
1417 if (filterKeyBindings[i].getName().equal(PEGASUS_PROPERTYNAME_NAME))
1418 {
1419 filterName.append(filterNS.getString());
1420 filterName.append(":");
1421 filterName.append(filterKeyBindings[i].getValue());
1422 break;
1423 }
1424 }
1425 yi.zhou 1.17
1426 //
1427 // Get handler namespace - if not set in handler reference property
1428 // value, namespace is the namespace of the subscription
1429 //
1430 CIMNamespaceName handlerNS = handlerPath.getNameSpace();
1431 if (handlerNS.isNull())
1432 {
1433 handlerNS = subscription.getPath().getNameSpace();
1434 }
1435
1436 //
1437 // Get handler name
1438 //
1439 Array<CIMKeyBinding> handlerKeyBindings = handlerPath.getKeyBindings();
1440 for (Uint32 i = 0; i < handlerKeyBindings.size(); i++)
1441 {
1442 if (handlerKeyBindings[i].getName().equal(PEGASUS_PROPERTYNAME_NAME))
1443 {
1444 handlerName.append(handlerNS.getString());
1445 handlerName.append(":");
1446 yi.zhou 1.17 handlerName.append(handlerPath.getClassName().getString());
1447 handlerName.append(".");
1448 handlerName.append(handlerKeyBindings[i].getValue());
1449 break;
1450 }
1451 }
1452
1453 PEG_METHOD_EXIT();
1454 }
1455
|
1456 yi.zhou 1.18 void SubscriptionTable::_getSubscriptionIndicationDataKeys(
1457 const CIMObjectPath& instanceName,
1458 String& filterName,
1459 String& handlerName,
1460 String& sourceNS,
1461 String& providerModuleName,
1462 String& providerName)
1463 {
1464 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1465 "SubscriptionTable::_getSubscriptionIndicationDataKeys");
1466
1467 Array<CIMKeyBinding> keys = instanceName.getKeyBindings();
1468 for (Uint32 i = 0; i < keys.size(); i++)
1469 {
1470 if (keys[i].getName() == "FilterName")
1471 {
1472 filterName = keys[i].getValue();
1473 }
1474 else if (keys[i].getName() == "HandlerName")
1475 {
1476 handlerName = keys[i].getValue();
1477 yi.zhou 1.18 }
1478 else if (keys[i].getName() == "SourceNamespace")
1479 {
1480 sourceNS = keys[i].getValue();
1481 }
1482 else if (keys[i].getName() == "ProviderModuleName")
1483 {
1484 providerModuleName = keys[i].getValue();
1485 }
1486 else if (keys[i].getName() == "ProviderName")
1487 {
1488 providerName = keys[i].getValue();
1489 }
1490 }
1491
1492 PEG_METHOD_EXIT();
1493 }
1494
1495
1496 CIMObjectPath SubscriptionTable::_buildFilterPath(const String& filterName)
1497 {
1498 yi.zhou 1.18 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1499 "SubscriptionTable::_buildFilterPath");
1500
1501 //
1502 // creates filter object path from input string filterName
1503 // (namespace:filtername)
1504 //
1505 String name;
1506 Uint32 colonIndex = filterName.find(':');
1507
1508 if (colonIndex != PEG_NOT_FOUND)
1509 {
1510 name = filterName.subString(colonIndex + 1);
1511 }
1512
1513 Array<CIMKeyBinding> filterKeys;
1514 filterKeys.append(CIMKeyBinding(
1515 "SystemCreationClassName",
1516 System::getSystemCreationClassName(),
1517 CIMKeyBinding::STRING));
1518 filterKeys.append(CIMKeyBinding(
1519 yi.zhou 1.18 "SystemName",
1520 System::getFullyQualifiedHostName(),
1521 CIMKeyBinding::STRING));
1522 filterKeys.append(CIMKeyBinding(
1523 "CreationClassName",
1524 PEGASUS_CLASSNAME_INDFILTER.getString(),
1525 CIMKeyBinding::STRING));
1526 filterKeys.append(CIMKeyBinding(
|
1527 marek 1.24 PEGASUS_PROPERTYNAME_NAME,
|
1528 yi.zhou 1.18 name,
1529 CIMKeyBinding::STRING));
1530
1531 CIMObjectPath filterPath = CIMObjectPath(
1532 String::EMPTY,
1533 CIMNamespaceName(),
1534 PEGASUS_CLASSNAME_INDFILTER,
1535 filterKeys);
1536
1537 PEG_METHOD_EXIT();
1538 return filterPath;
1539 }
1540
1541 CIMObjectPath SubscriptionTable::_buildHandlerPath(const String& handlerName)
1542 {
1543 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1544 "SubscriptionTable::_buildHandlerPath");
1545
1546 //
1547 // creates handler object path from input string handlerName
1548 // (namespace:classname.handlername)
1549 yi.zhou 1.18 //
1550 String name;
1551 String classname;
1552 Uint32 colonIndex = handlerName.find(':');
1553 Uint32 dotIndex = handlerName.find('.');
1554
1555 if (colonIndex != PEG_NOT_FOUND)
1556 {
1557 if ((dotIndex != PEG_NOT_FOUND) && (dotIndex > colonIndex))
1558 {
1559 classname = handlerName.subString(
1560 colonIndex + 1, dotIndex - 1 - colonIndex);
1561 name = handlerName.subString(dotIndex + 1);
1562 }
1563 }
1564
1565 Array<CIMKeyBinding> handlerKeys;
1566 handlerKeys.append(CIMKeyBinding(
1567 "SystemCreationClassName",
1568 System::getSystemCreationClassName(),
1569 CIMKeyBinding::STRING));
1570 yi.zhou 1.18 handlerKeys.append(CIMKeyBinding(
1571 "SystemName",
1572 System::getFullyQualifiedHostName(),
1573 CIMKeyBinding::STRING));
1574 handlerKeys.append(CIMKeyBinding(
1575 "CreationClassName",
1576 classname,
1577 CIMKeyBinding::STRING));
1578 handlerKeys.append(CIMKeyBinding(
|
1579 marek 1.24 PEGASUS_PROPERTYNAME_NAME,
|
1580 yi.zhou 1.18 name,
1581 CIMKeyBinding::STRING));
1582
1583 CIMObjectPath handlerPath = CIMObjectPath(
1584 String::EMPTY,
1585 CIMNamespaceName(),
1586 classname,
1587 handlerKeys);
1588
1589 PEG_METHOD_EXIT();
1590 return handlerPath;
1591 }
1592
1593 CIMObjectPath SubscriptionTable::_buildSubscriptionPath(
1594 const String& filterName,
1595 const String& handlerName,
1596 const String& sourceNS)
1597 {
1598 CIMObjectPath filterPath = _buildFilterPath(filterName);
1599 CIMObjectPath handlerPath = _buildHandlerPath(handlerName);
1600
1601 yi.zhou 1.18 CIMObjectPath subscriptionPath;
1602 Array<CIMKeyBinding> keyBindings;
1603 keyBindings.append(CIMKeyBinding(
1604 PEGASUS_PROPERTYNAME_FILTER,
1605 filterPath.toString(),
1606 CIMKeyBinding::REFERENCE));
1607 keyBindings.append(CIMKeyBinding(
1608 PEGASUS_PROPERTYNAME_HANDLER,
1609 handlerPath.toString(),
1610 CIMKeyBinding::REFERENCE));
1611
1612 subscriptionPath.setClassName(PEGASUS_CLASSNAME_INDSUBSCRIPTION);
1613 subscriptionPath.setNameSpace(sourceNS);
1614 subscriptionPath.setKeyBindings(keyBindings);
1615
1616 return subscriptionPath;
1617 }
1618
1619 CIMInstance SubscriptionTable::_buildSubscriptionIndDataInstance(
1620 const String& filterName,
1621 const String& handlerName,
1622 yi.zhou 1.18 const String& sourceNS,
1623 const String& providerModuleName,
1624 const String& providerName,
1625 Uint32 matchedIndicationCount)
1626 {
1627 CIMInstance subscriptionIndDataInstance(
1628 PEGASUS_CLASSNAME_SUBSCRIPTIONINDDATA);
1629 subscriptionIndDataInstance.addProperty(CIMProperty(
1630 CIMName("FilterName"), filterName));
1631 subscriptionIndDataInstance.addProperty(CIMProperty(
1632 CIMName("HandlerName"), handlerName));
1633 subscriptionIndDataInstance.addProperty(CIMProperty(
1634 CIMName("SourceNamespace"), sourceNS));
1635 subscriptionIndDataInstance.addProperty(CIMProperty(
1636 CIMName("ProviderModuleName"), providerModuleName));
1637 subscriptionIndDataInstance.addProperty(CIMProperty(
1638 CIMName("ProviderName"), providerName));
1639 subscriptionIndDataInstance.addProperty(CIMProperty(
1640 CIMName("MatchedIndicationCount"),
1641 matchedIndicationCount));
1642
1643 yi.zhou 1.18 CIMObjectPath path = _buildSubscriptionIndDataInstanceName(
1644 filterName,
1645 handlerName,
1646 sourceNS,
1647 providerModuleName,
1648 providerName);
1649 subscriptionIndDataInstance.setPath(path);
1650
1651 return subscriptionIndDataInstance;
1652 }
1653
1654 CIMObjectPath SubscriptionTable::_buildSubscriptionIndDataInstanceName(
1655 const String& filterName,
1656 const String& handlerName,
1657 const String& sourceNS,
1658 const String& providerModuleName,
1659 const String& providerName)
1660 {
1661 CIMObjectPath path;
1662 Array<CIMKeyBinding> keyBindings;
1663 keyBindings.append(CIMKeyBinding(
1664 yi.zhou 1.18 "FilterName",
1665 filterName,
1666 CIMKeyBinding::STRING));
1667 keyBindings.append(CIMKeyBinding(
1668 "HandlerName",
1669 handlerName,
1670 CIMKeyBinding::STRING));
1671 keyBindings.append(CIMKeyBinding(
1672 "SourceNamespace",
1673 sourceNS,
1674 CIMKeyBinding::STRING));
1675 keyBindings.append(CIMKeyBinding(
1676 "ProviderModuleName",
1677 providerModuleName,
1678 CIMKeyBinding::STRING));
1679 keyBindings.append(CIMKeyBinding(
1680 "ProviderName",
1681 providerName,
1682 CIMKeyBinding::STRING));
1683
1684 path.setClassName(PEGASUS_CLASSNAME_SUBSCRIPTIONINDDATA);
1685 yi.zhou 1.18 path.setKeyBindings(keyBindings);
1686
1687 return path;
1688 }
1689
1690 CIMObjectPath SubscriptionTable::_buildProviderPath(
1691 const String& providerModuleName,
1692 const String& providerName)
1693 {
1694 CIMObjectPath path;
1695 Array<CIMKeyBinding> keyBindings;
1696 keyBindings.append(CIMKeyBinding(
1697 _PROPERTY_PROVIDERMODULENAME,
1698 providerModuleName,
1699 CIMKeyBinding::STRING));
1700 keyBindings.append(CIMKeyBinding(
1701 PEGASUS_PROPERTYNAME_NAME,
1702 providerName,
1703 CIMKeyBinding::STRING));
1704
1705 path.setClassName(PEGASUS_CLASSNAME_PROVIDER);
1706 yi.zhou 1.18 path.setKeyBindings(keyBindings);
1707
1708 return path;
1709 }
1710
|
1711 yi.zhou 1.17 #endif
1712
|
1713 kumpf 1.1 PEGASUS_NAMESPACE_END
|