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