1 //%LICENSE////////////////////////////////////////////////////////////////
3 // 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
10 // 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:
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // 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.
28 //////////////////////////////////////////////////////////////////////////
30 //%/////////////////////////////////////////////////////////////////////////////
32 #include <Pegasus/Common/Config.h>
33 #include <Pegasus/Common/Constants.h>
34 #include <Pegasus/Common/CIMInstance.h>
35 #include <Pegasus/Common/ArrayInternal.h>
36 #include <Pegasus/Common/CIMDateTime.h>
37 #include <Pegasus/Common/CIMProperty.h>
38 #include <Pegasus/Common/MessageQueue.h>
39 #include <Pegasus/Common/System.h>
40 #include <Pegasus/Common/Tracer.h>
41 #include <Pegasus/Common/XmlWriter.h>
42 #include <Pegasus/Common/PegasusVersion.h>
43 #include <Pegasus/Common/AcceptLanguageList.h>
44 #include <Pegasus/Common/ContentLanguageList.h>
45 #include <Pegasus/Common/LanguageParser.h>
46 #include <Pegasus/Common/OperationContextInternal.h>
47 #include <Pegasus/Common/MessageLoader.h>
48 #include <Pegasus/Common/String.h>
50 #include <Pegasus/General/IndicationFormatter.h>
51 #include <Pegasus/General/Guid.h>
52 #ifdef PEGASUS_INDICATION_PERFINST
53 #include <Pegasus/General/Stopwatch.h>
56 #include <Pegasus/Server/ProviderRegistrationManager/\
57 ProviderRegistrationManager.h>
58 #include <Pegasus/Query/QueryExpression/QueryExpression.h>
59 #include <Pegasus/Query/QueryCommon/QueryException.h>
60 #include <Pegasus/Repository/RepositoryQueryContext.h>
62 #include "IndicationConstants.h"
63 #include "SubscriptionRepository.h"
64 #include "SubscriptionTable.h"
65 #include "IndicationService.h"
70 PEGASUS_NAMESPACE_BEGIN
76 static const char _MSG_PROPERTY_KEY[] =
77 "IndicationService.IndicationService._MSG_PROPERTY";
78 static const char _MSG_PROPERTY[] = "The required property $0 is missing.";
80 static const char _MSG_NO_PROVIDERS_KEY[] =
81 "IndicationService.IndicationService._MSG_NO_PROVIDERS";
82 static const char _MSG_NO_PROVIDERS[] =
83 "No providers are capable of servicing the subscription.";
85 static const char _MSG_INVALID_TYPE_FOR_PROPERTY_KEY[] =
86 "IndicationService.IndicationService._MSG_INVALID_TYPE_FOR_PROPERTY";
87 static const char _MSG_INVALID_TYPE_FOR_PROPERTY[] =
88 "The value of type $0 is not valid for property $1.";
90 static const char _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY_KEY[] =
91 "IndicationService.IndicationService."
92 "_MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY";
93 static const char _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY[] =
94 "The value of an array of type $0 is not valid for property $1.";
96 static const char _MSG_INVALID_VALUE_FOR_PROPERTY_KEY[] =
97 "IndicationService.IndicationService._MSG_INVALID_VALUE_FOR_PROPERTY";
98 static const char _MSG_INVALID_VALUE_FOR_PROPERTY[] =
99 "The value $0 is not valid for property $1.";
101 static const char _MSG_UNSUPPORTED_VALUE_FOR_PROPERTY_KEY[] =
102 "IndicationService.IndicationService._MSG_UNSUPPORTED_VALUE_FOR_PROPERTY";
103 static const char _MSG_UNSUPPORTED_VALUE_FOR_PROPERTY[] =
104 "The value $0 is not supported for property $1.";
106 static const char _MSG_CLASS_NOT_SERVED_KEY[] =
107 "IndicationService.IndicationService._MSG_CLASS_NOT_SERVED";
108 static const char _MSG_CLASS_NOT_SERVED[] =
109 "The specified class is not serviced by the CIM Indication service.";
111 static const char _MSG_INVALID_INSTANCES_KEY[] =
112 "IndicationService.IndicationService."
113 "INVALID_SUBSCRIPTION_INSTANCES_IGNORED";
114 static const char _MSG_INVALID_INSTANCES[] =
115 "One or more subscription instances are not valid and are ignored.";
117 static const char _MSG_PROVIDER_NO_LONGER_SERVING_KEY[] =
118 "IndicationService.IndicationService._MSG_PROVIDER_NO_LONGER_SERVING";
119 static const char _MSG_PROVIDER_NO_LONGER_SERVING[] =
120 "Provider ($0) is no longer serving subscription ($1) in namespace $2";
122 static const char _MSG_PROVIDER_NOW_SERVING_KEY[] =
123 "IndicationService.IndicationService._MSG_PROVIDER_NOW_SERVING";
124 static const char _MSG_PROVIDER_NOW_SERVING[] =
125 "Provider ($0) is now serving subscription ($1) in namespace $2";
127 static const char _MSG_NO_PROVIDER_KEY[] =
128 "IndicationService.IndicationService._MSG_NO_PROVIDER";
129 static const char _MSG_NO_PROVIDER[] =
130 "Subscription ($0) in namespace $1 has no provider";
132 static const char _MSG_STATE_CHANGE_FAILED_KEY[] =
133 "IndicationService.IndicationService.STATE_CHANGE_FAILED";
134 static const char _MSG_STATE_CHANGE_FAILED[] =
135 "The requested state change failed : $0. Current IndicationService"
136 " EnabledState : $1, HealthState : $2.";
138 // ATTN-RK-20020730: Temporary hack to fix Windows build
139 Boolean ContainsCIMName(const Array<CIMName>& a, const CIMName& x)
143 for (Uint32 i = 0; i < n; i++)
152 Mutex IndicationService::_mutex;
153 Uint16 IndicationService::_enabledState = _ENABLEDSTATE_DISABLED;
154 Uint16 IndicationService::_healthState = _HEALTHSTATE_OK;
157 See CIM_EnabledLogicalElement.RequestStateChange() method for return codes
158 and CIM_EnabledLogicalElement.EnabledState property for service states.
160 ATTN: Currently very few states are supported and the following utility
161 functions are hard coded to return service states directly. Write a
162 generic function to get values from ValueMap independent of class.
164 String _getEnabledStateString(Uint32 code)
166 // Check for service states
169 case _ENABLEDSTATE_ENABLED:
170 return String("Enabled");
171 case _ENABLEDSTATE_DISABLED:
172 return String("Disabled");
173 case _ENABLEDSTATE_SHUTTINGDOWN:
174 return String("Shutting Down");
175 case _ENABLEDSTATE_STARTING:
176 return String("Starting");
178 PEGASUS_ASSERT(false); // Never reach to unknown state at present.
180 return String("Unknown");
183 String _getHealthStateString(Uint32 code)
185 // Service health states
188 case _HEALTHSTATE_OK:
190 case _HEALTHSTATE_DEGRADEDWARNING:
191 return String("Degraded/Warning");
193 PEGASUS_ASSERT(false); // Never reach to unknown state at present.
195 return String("Unknown");
198 IndicationService::IndicationService(
199 CIMRepository* repository,
200 ProviderRegistrationManager* providerRegManager)
201 : MessageQueueService(
202 PEGASUS_QUEUENAME_INDICATIONSERVICE),
203 _providerRegManager(providerRegManager),
204 _cimRepository(repository)
206 _enableSubscriptionsForNonprivilegedUsers = false;
207 _authenticationEnabled = true;
211 // Determine the value for the configuration parameter
212 // enableSubscriptionsForNonprivilegedUsers
213 ConfigManager* configManager = ConfigManager::getInstance();
215 if (ConfigManager::parseBooleanValue(
216 configManager->getCurrentValue("enableAuthentication")))
218 _enableSubscriptionsForNonprivilegedUsers =
219 ConfigManager::parseBooleanValue(
220 configManager->getCurrentValue(
221 "enableSubscriptionsForNonprivilegedUsers"));
225 _authenticationEnabled = false;
226 // Authentication needs to be enabled to perform authorization
228 _enableSubscriptionsForNonprivilegedUsers = true;
233 // If there is an error reading the configuration file then
234 // the value of _enableSubscriptionsForNonprivilegedUsers will
235 // default to false (i.e., the more restrictive security
237 PEG_TRACE_CSTRING(TRC_INDICATION_SERVICE, Tracer::LEVEL2,
238 "Failure attempting to read configuration parameters during "
242 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
243 "Value of _enableSubscriptionsForNonprivilegedUsers is %d",
244 _enableSubscriptionsForNonprivilegedUsers));
248 // Create IndicationsProfileInstance Repository
249 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
250 _indicationServiceConfiguration.reset(
251 new IndicationServiceConfiguration(_cimRepository));
253 // Initialize the Indication Service
258 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
259 "Exception caught in attempting to "
260 "initialize Indication Service: %s",
261 (const char*)e.getMessage().getCString()));
262 _healthState = _HEALTHSTATE_DEGRADEDWARNING;
267 IndicationService::~IndicationService()
271 Uint16 IndicationService::getHealthState()
276 Uint16 IndicationService::getEnabledState()
278 return _enabledState;
281 void IndicationService::_handle_async_request(AsyncRequest *req)
283 if (req->getType() == ASYNC_CIMSERVICE_STOP)
290 handle_CimServiceStop(static_cast<CimServiceStop *>(req));
292 else if (req->getType() == ASYNC_CIMSERVICE_START)
294 handle_CimServiceStart(static_cast<CimServiceStart *>(req));
296 else if (req->getType() == ASYNC_ASYNC_LEGACY_OP_START)
301 static_cast<AsyncLegacyOperationStart *>(req)->get_action();
302 legacy->put_async(req);
304 handleEnqueue(legacy);
308 PEG_TRACE_CSTRING(TRC_INDICATION_SERVICE, Tracer::LEVEL1,
309 "Caught Exception in IndicationService while handling a "
310 "wrapped legacy message ");
311 _make_response(req, async_results::CIM_NAK);
317 MessageQueueService::_handle_async_request(req);
320 void IndicationService::handleEnqueue(Message* message)
322 #ifdef PEGASUS_INDICATION_PERFINST
327 CIMRequestMessage* cimRequest = dynamic_cast<CIMRequestMessage *>(message);
328 PEGASUS_ASSERT(cimRequest);
330 // Set the client's requested language into this service thread.
331 // This will allow functions in this service to return messages
332 // in the correct language.
333 cimRequest->updateThreadLanguages();
337 if (_enabledState != _ENABLEDSTATE_ENABLED)
339 _handleCimRequestWithServiceNotEnabled(message);
343 _handleCimRequest(message);
346 catch (CIMException& e)
348 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
349 "CIMException caught in IndicationService::handleEnqueue: %s",
350 (const char*)e.getMessage().getCString()));
351 CIMResponseMessage* response = cimRequest->buildResponse();
352 response->cimException = e;
353 _enqueueResponse(cimRequest, response);
357 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
358 "Exception caught in IndicationService::handleEnqueue: %s",
359 (const char*)e.getMessage().getCString()));
360 CIMResponseMessage* response = cimRequest->buildResponse();
361 response->cimException =
362 PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, e.getMessage());
363 _enqueueResponse(cimRequest, response);
367 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
368 "Unknown exception caught in IndicationService::handleEnqueue."));
369 CIMResponseMessage* response = cimRequest->buildResponse();
370 response->cimException = PEGASUS_CIM_EXCEPTION_L(
373 "IndicationService.IndicationService.UNKNOWN_ERROR",
375 _enqueueResponse(cimRequest, response);
378 #ifdef PEGASUS_INDICATION_PERFINST
381 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
383 MessageTypeToString(message->getType()),
384 stopWatch.getElapsed()));
390 void IndicationService::_handleCimRequest(Message *message)
392 switch(message->getType())
394 case CIM_GET_INSTANCE_REQUEST_MESSAGE:
395 _handleGetInstanceRequest(message);
398 case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE:
399 _handleEnumerateInstancesRequest(message);
402 case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE:
403 _handleEnumerateInstanceNamesRequest(message);
406 case CIM_CREATE_INSTANCE_REQUEST_MESSAGE:
407 _handleCreateInstanceRequest(message);
410 case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
411 _handleModifyInstanceRequest(message);
414 case CIM_DELETE_INSTANCE_REQUEST_MESSAGE:
415 _handleDeleteInstanceRequest(message);
418 case CIM_PROCESS_INDICATION_REQUEST_MESSAGE:
419 _handleProcessIndicationRequest(message);
422 case CIM_NOTIFY_PROVIDER_REGISTRATION_REQUEST_MESSAGE:
423 _handleNotifyProviderRegistrationRequest(message);
426 case CIM_NOTIFY_PROVIDER_TERMINATION_REQUEST_MESSAGE:
427 _handleNotifyProviderTerminationRequest(message);
430 case CIM_NOTIFY_PROVIDER_ENABLE_REQUEST_MESSAGE:
431 _handleNotifyProviderEnableRequest(message);
434 case CIM_NOTIFY_PROVIDER_FAIL_REQUEST_MESSAGE:
435 _handleNotifyProviderFailRequest(message);
438 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
439 case CIM_INVOKE_METHOD_REQUEST_MESSAGE:
440 _handleInvokeMethodRequest(message);
445 CIMRequestMessage* cimRequest =
446 dynamic_cast<CIMRequestMessage *>(message);
448 // A message type not supported by the Indication Service
449 // Should not reach here
451 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
452 "IndicationService::_handleCimRequest rcv'd unsupported "
453 "message of type %s.",
454 MessageTypeToString(message->getType())));
456 // Note: not setting Content-Language in the response
457 CIMResponseMessage* response = cimRequest->buildResponse();
458 response->cimException = PEGASUS_CIM_EXCEPTION_L(
459 CIM_ERR_NOT_SUPPORTED,
461 "IndicationService.IndicationService."
462 "UNSUPPORTED_OPERATION",
463 "The requested operation is not supported or not "
464 "recognized by the indication service."));
466 _enqueueResponse(cimRequest, response);
470 void IndicationService::_handleCimRequestWithServiceNotEnabled(
473 Boolean requestHandled = false;
474 CIMRequestMessage* cimRequest = dynamic_cast<CIMRequestMessage *>(message);
476 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
477 requestHandled = true;
478 switch(message->getType())
480 case CIM_INVOKE_METHOD_REQUEST_MESSAGE:
481 _handleInvokeMethodRequest(message);
483 case CIM_NOTIFY_PROVIDER_REGISTRATION_REQUEST_MESSAGE:
484 case CIM_NOTIFY_PROVIDER_TERMINATION_REQUEST_MESSAGE:
485 case CIM_NOTIFY_PROVIDER_ENABLE_REQUEST_MESSAGE:
486 case CIM_NOTIFY_PROVIDER_FAIL_REQUEST_MESSAGE:
487 _enqueueResponse(cimRequest, cimRequest->buildResponse());
490 case CIM_PROCESS_INDICATION_REQUEST_MESSAGE:
491 _handleProcessIndicationRequest(message);
494 // Handle only CIM_IndicationService class operations.
495 case CIM_GET_INSTANCE_REQUEST_MESSAGE:
497 CIMGetInstanceRequestMessage *request =
498 (CIMGetInstanceRequestMessage*)message;
499 if (request->className.equal(
500 PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE))
502 _handleGetInstanceRequest(message);
506 requestHandled = false;
510 case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE:
512 CIMEnumerateInstancesRequestMessage *request =
513 (CIMEnumerateInstancesRequestMessage*)message;
514 if (request->className.equal(
515 PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE))
517 _handleEnumerateInstancesRequest(message);
521 requestHandled = false;
526 case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE:
528 CIMEnumerateInstanceNamesRequestMessage *request =
529 (CIMEnumerateInstanceNamesRequestMessage*)message;
530 if (request->className.equal(
531 PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE))
533 _handleEnumerateInstanceNamesRequest(message);
537 requestHandled = false;
542 requestHandled = false;
550 Logger::STANDARD_LOG,
554 "IndicationService.IndicationService."
555 "CANNOT_EXECUTE_REQUEST",
556 "The requested operation cannot be executed."
557 " IndicationService EnabledState : $0.",
558 _getEnabledStateString(_enabledState)));
560 CIMResponseMessage* response = cimRequest->buildResponse();
561 response->cimException = PEGASUS_CIM_EXCEPTION_L(
564 "IndicationService.IndicationService."
565 "CANNOT_EXECUTE_REQUEST",
566 "The requested operation cannot be executed."
567 " IndicationService EnabledState : $0.",
568 _getEnabledStateString(_enabledState)));
569 _enqueueResponse(cimRequest, response);
574 void IndicationService::handleEnqueue()
576 Message * message = dequeue();
578 PEGASUS_ASSERT(message != 0);
579 handleEnqueue(message);
582 void IndicationService::_initialize()
584 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE, "IndicationService::_initialize");
587 // Find required services
588 _providerManager = find_service_qid(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
589 _handlerService = find_service_qid(PEGASUS_QUEUENAME_INDHANDLERMANAGER);
592 // Set arrays of valid and supported property values
594 // Note: Valid values are defined by the CIM Event Schema MOF
595 // Supported values are a subset of the valid values
596 // Some valid values, as defined in the MOF, are not currently supported
597 // by the Pegasus IndicationService
599 _validStates.append(STATE_UNKNOWN);
600 _validStates.append(STATE_OTHER);
601 _validStates.append(STATE_ENABLED);
602 _validStates.append(STATE_ENABLEDDEGRADED);
603 _validStates.append(STATE_DISABLED);
604 _supportedStates.append(STATE_ENABLED);
605 _supportedStates.append(STATE_DISABLED);
606 _validRepeatPolicies.append(_POLICY_UNKNOWN);
607 _validRepeatPolicies.append(_POLICY_OTHER);
608 _validRepeatPolicies.append(_POLICY_NONE);
609 _validRepeatPolicies.append(_POLICY_SUPPRESS);
610 _validRepeatPolicies.append(_POLICY_DELAY);
611 _supportedRepeatPolicies.append(_POLICY_UNKNOWN);
612 _supportedRepeatPolicies.append(_POLICY_OTHER);
613 _supportedRepeatPolicies.append(_POLICY_NONE);
614 _supportedRepeatPolicies.append(_POLICY_SUPPRESS);
615 _supportedRepeatPolicies.append(_POLICY_DELAY);
616 _validErrorPolicies.append(_ERRORPOLICY_OTHER);
617 _validErrorPolicies.append(_ERRORPOLICY_IGNORE);
618 _validErrorPolicies.append(_ERRORPOLICY_DISABLE);
619 _validErrorPolicies.append(_ERRORPOLICY_REMOVE);
620 _supportedErrorPolicies.append(_ERRORPOLICY_IGNORE);
621 _supportedErrorPolicies.append(_ERRORPOLICY_DISABLE);
622 _supportedErrorPolicies.append(_ERRORPOLICY_REMOVE);
623 _validPersistenceTypes.append(PERSISTENCE_OTHER);
624 _validPersistenceTypes.append(PERSISTENCE_PERMANENT);
625 _validPersistenceTypes.append(PERSISTENCE_TRANSIENT);
626 _supportedPersistenceTypes.append(PERSISTENCE_PERMANENT);
627 _supportedPersistenceTypes.append(PERSISTENCE_TRANSIENT);
628 _validSNMPVersion.append(SNMPV1_TRAP);
629 _validSNMPVersion.append(SNMPV2C_TRAP);
630 _validSNMPVersion.append(SNMPV2C_INFORM);
631 _validSNMPVersion.append(SNMPV3_TRAP);
632 _validSNMPVersion.append(SNMPV3_INFORM);
633 _supportedSNMPVersion.append(SNMPV1_TRAP);
634 _supportedSNMPVersion.append(SNMPV2C_TRAP);
637 // Set arrays of names of supported properties for each class
639 // Currently, all properties in these classes in CIM 2.5 through CIM 2.9
640 // final schemas are supported. If support for a new class is added, a new
641 // list of names of supported properties for the class must be added as a
642 // private member to the IndicationService class, and the array values
643 // must be appended here. When support for a new property is added, the
644 // property name must be appended to the appropriate array(s) here.
646 _supportedSubscriptionProperties.append(PEGASUS_PROPERTYNAME_FILTER);
647 _supportedSubscriptionProperties.append(PEGASUS_PROPERTYNAME_HANDLER);
648 _supportedSubscriptionProperties.append(_PROPERTY_ONFATALERRORPOLICY);
649 _supportedSubscriptionProperties.append(_PROPERTY_OTHERONFATALERRORPOLICY);
650 _supportedSubscriptionProperties.append(
651 _PROPERTY_FAILURETRIGGERTIMEINTERVAL);
652 _supportedSubscriptionProperties.append(
653 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE);
654 _supportedSubscriptionProperties.append(_PROPERTY_OTHERSTATE);
655 _supportedSubscriptionProperties.append(_PROPERTY_LASTCHANGE);
656 _supportedSubscriptionProperties.append(_PROPERTY_DURATION);
657 _supportedSubscriptionProperties.append(_PROPERTY_STARTTIME);
658 _supportedSubscriptionProperties.append(_PROPERTY_TIMEREMAINING);
659 _supportedSubscriptionProperties.append(_PROPERTY_REPEATNOTIFICATIONPOLICY);
660 _supportedSubscriptionProperties.append(
661 _PROPERTY_OTHERREPEATNOTIFICATIONPOLICY);
662 _supportedSubscriptionProperties.append(
663 _PROPERTY_REPEATNOTIFICATIONINTERVAL);
664 _supportedSubscriptionProperties.append(_PROPERTY_REPEATNOTIFICATIONGAP);
665 _supportedSubscriptionProperties.append(_PROPERTY_REPEATNOTIFICATIONCOUNT);
667 _supportedFormattedSubscriptionProperties =
668 _supportedSubscriptionProperties;
669 _supportedFormattedSubscriptionProperties.append(
670 _PROPERTY_TEXTFORMATOWNINGENTITY);
671 _supportedFormattedSubscriptionProperties.append(
672 _PROPERTY_TEXTFORMATID);
673 _supportedFormattedSubscriptionProperties.append(
674 _PROPERTY_TEXTFORMAT);
675 _supportedFormattedSubscriptionProperties.append(
676 _PROPERTY_TEXTFORMATPARAMETERS);
678 _supportedFilterProperties.append(_PROPERTY_CAPTION);
679 _supportedFilterProperties.append(_PROPERTY_DESCRIPTION);
680 _supportedFilterProperties.append(_PROPERTY_ELEMENTNAME);
681 _supportedFilterProperties.append(_PROPERTY_SYSTEMCREATIONCLASSNAME);
682 _supportedFilterProperties.append(_PROPERTY_SYSTEMNAME);
683 _supportedFilterProperties.append(PEGASUS_PROPERTYNAME_CREATIONCLASSNAME);
684 _supportedFilterProperties.append(PEGASUS_PROPERTYNAME_NAME);
685 _supportedFilterProperties.append(_PROPERTY_SOURCENAMESPACE);
686 _supportedFilterProperties.append(PEGASUS_PROPERTYNAME_QUERY);
687 _supportedFilterProperties.append(PEGASUS_PROPERTYNAME_QUERYLANGUAGE);
689 Array<CIMName> commonListenerDestinationProperties;
690 commonListenerDestinationProperties.append(_PROPERTY_CAPTION);
691 commonListenerDestinationProperties.append(_PROPERTY_DESCRIPTION);
692 commonListenerDestinationProperties.append(_PROPERTY_ELEMENTNAME);
693 commonListenerDestinationProperties.append(
694 _PROPERTY_SYSTEMCREATIONCLASSNAME);
695 commonListenerDestinationProperties.append(_PROPERTY_SYSTEMNAME);
696 commonListenerDestinationProperties.append(
697 PEGASUS_PROPERTYNAME_CREATIONCLASSNAME);
698 commonListenerDestinationProperties.append(PEGASUS_PROPERTYNAME_NAME);
699 commonListenerDestinationProperties.append(
700 PEGASUS_PROPERTYNAME_PERSISTENCETYPE);
701 commonListenerDestinationProperties.append(_PROPERTY_OTHERPERSISTENCETYPE);
703 _supportedCIMXMLHandlerProperties = commonListenerDestinationProperties;
704 _supportedCIMXMLHandlerProperties.append(_PROPERTY_OWNER);
705 _supportedCIMXMLHandlerProperties.append(
706 PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION);
708 _supportedCIMXMLListenerDestinationProperties =
709 commonListenerDestinationProperties;
710 _supportedCIMXMLListenerDestinationProperties.append(
711 PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION);
713 _supportedSNMPHandlerProperties = commonListenerDestinationProperties;
714 _supportedSNMPHandlerProperties.append(_PROPERTY_OWNER);
715 _supportedSNMPHandlerProperties.append(
716 PEGASUS_PROPERTYNAME_LSTNRDST_TARGETHOST);
717 _supportedSNMPHandlerProperties.append(_PROPERTY_TARGETHOSTFORMAT);
718 _supportedSNMPHandlerProperties.append(_PROPERTY_OTHERTARGETHOSTFORMAT);
719 _supportedSNMPHandlerProperties.append(_PROPERTY_PORTNUMBER);
720 _supportedSNMPHandlerProperties.append(PEGASUS_PROPERTYNAME_SNMPVERSION);
721 _supportedSNMPHandlerProperties.append(_PROPERTY_SNMPSECURITYNAME);
722 _supportedSNMPHandlerProperties.append(_PROPERTY_SNMPENGINEID);
724 _supportedSyslogListenerDestinationProperties =
725 commonListenerDestinationProperties;
727 _supportedEmailListenerDestinationProperties =
728 commonListenerDestinationProperties;
729 _supportedEmailListenerDestinationProperties.append(
730 PEGASUS_PROPERTYNAME_LSTNRDST_MAILTO);
731 _supportedEmailListenerDestinationProperties.append(
732 PEGASUS_PROPERTYNAME_LSTNRDST_MAILCC);
733 _supportedEmailListenerDestinationProperties.append(
734 PEGASUS_PROPERTYNAME_LSTNRDST_MAILSUBJECT);
736 ConfigManager* configManager = ConfigManager::getInstance();
738 if (ConfigManager::parseBooleanValue(
739 configManager->getCurrentValue("enableIndicationService")))
741 _enabledState = _ENABLEDSTATE_ENABLED;
742 _initializeActiveSubscriptionsFromRepository(0);
750 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
752 String _getReturnCodeString(Uint32 code)
754 // Method return codes
757 case _RETURNCODE_TIMEOUT:
758 return String("Cannot complete within Timeout Period");
759 case _RETURNCODE_NOTSUPPORTED:
760 return String("Not Supported");
761 case _RETURNCODE_FAILED:
762 return String("Failed");
763 case _RETURNCODE_INVALIDPARAMETER:
764 return String("Invalid Parameter");
767 PEGASUS_ASSERT(false); // Never reach to unknown return code
769 return String("Unknown");
772 void IndicationService::_sendIndicationServiceDisabled()
774 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
775 "IndicationService::_sendIndicationServiceDisabled");
777 if (_enabledState == _ENABLEDSTATE_ENABLED)
783 CIMIndicationServiceDisabledRequestMessage * request =
784 new CIMIndicationServiceDisabledRequestMessage(
785 XmlWriter::getNextMessageId(),
786 QueueIdStack(_providerManager, getQueueId()));
788 AsyncLegacyOperationStart * asyncRequest =
789 new AsyncLegacyOperationStart(
793 AutoPtr<AsyncReply> asyncReply(SendWait(asyncRequest));
800 void IndicationService::_handleInvokeMethodRequest(Message *message)
802 Uint32 timeoutSeconds = 0;
804 CIMInvokeMethodRequestMessage *request =
805 dynamic_cast<CIMInvokeMethodRequestMessage*>(message);
807 PEGASUS_ASSERT(request);
809 CIMInvokeMethodResponseMessage *response =
810 static_cast<CIMInvokeMethodResponseMessage*>(request->buildResponse());
812 // Get userName and only privileged user can execute this operation
813 String userName = ((IdentityContainer)request->operationContext.get(
814 IdentityContainer::NAME)).getUserName();
816 #ifndef PEGASUS_OS_ZOS
817 if (userName.size() && !System::isPrivilegedUser(userName))
819 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED,
821 "IndicationService.IndicationService."
822 "_MSG_NON_PRIVILEGED_ACCESS_DISABLED",
823 "User ($0) is not authorized to perform this operation.",
828 CIMException cimException;
830 CIMNamespaceName nameSpace = request->nameSpace;
831 CIMName className = request->instanceName.getClassName().getString();
833 Uint32 retCode = _RETURNCODE_COMPLETEDWITHNOERROR;
834 Uint16 requestedState;
836 if(!nameSpace.equal(PEGASUS_NAMESPACENAME_INTEROP))
838 cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
839 nameSpace.getString());
841 else if(!className.equal(PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE))
843 cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
844 className.getString());
846 else if (!request->methodName.equal(_METHOD_REQUESTSTATECHANGE))
848 cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_METHOD_NOT_FOUND,
855 for (Uint32 i = 0, n = request->inParameters.size(); i < n ; ++i)
857 CIMName name = request->inParameters[i].getParameterName();
858 if (name.equal(_PARAM_REQUESTEDSTATE))
860 CIMValue cimValue = request->inParameters[i].getValue();
861 cimValue.get(requestedState);
863 else if ((name.equal(_PARAM_TIMEOUTPERIOD)))
865 CIMDateTime timeoutInterval;
866 CIMValue cimValue = request->inParameters[i].getValue();
867 cimValue.get(timeoutInterval);
868 if (!timeoutInterval.isInterval())
870 retCode = _RETURNCODE_INVALIDPARAMETER;
873 // Get timeout in seconds
875 timeoutInterval.toMicroSeconds() / 1000000;
879 retCode = _RETURNCODE_INVALIDPARAMETER;
885 if (cimException.getCode() == CIM_ERR_SUCCESS &&
886 retCode == _RETURNCODE_COMPLETEDWITHNOERROR)
888 if (requestedState == _ENABLEDSTATE_ENABLED)
890 retCode = _enableIndicationService(timeoutSeconds);
892 else if (requestedState == _ENABLEDSTATE_DISABLED)
894 retCode = _disableIndicationService(
900 // We don't support any other state changes now.
901 retCode = _RETURNCODE_NOTSUPPORTED;
905 response->cimException = cimException;
906 response->retValue = CIMValue(retCode);
907 _enqueueResponse(request, response);
911 Uint32 IndicationService::_enableIndicationService(Uint32 timeoutSeconds)
913 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
914 "IndicationService::_enableIndicationService");
916 Uint32 retCode = _RETURNCODE_COMPLETEDWITHNOERROR;
918 AutoMutex mtx(_mutex);
920 // Check if the service is already enabled.
921 if (_enabledState == _ENABLEDSTATE_ENABLED)
923 // Check if the service is in degraded state.
924 if (_healthState == _HEALTHSTATE_DEGRADEDWARNING)
926 struct timeval startTime;
927 Time::gettimeofday(&startTime);
929 // Wait if there are any pending requests.
930 if (!_waitForAsyncRequestsComplete(&startTime, timeoutSeconds))
933 Logger::STANDARD_LOG,
936 "Failed to recover from degraded state within timeout "
937 "period of $0 seconds. There are $1 async"
938 " requests pending.",
940 _asyncRequestsPending.get());
942 retCode = _RETURNCODE_TIMEOUT;
946 // No async requests pending.
947 _healthState = _HEALTHSTATE_OK;
954 _enabledState = _ENABLEDSTATE_STARTING;
960 if (_initializeActiveSubscriptionsFromRepository(
963 _healthState = _HEALTHSTATE_OK;
967 _healthState = _HEALTHSTATE_DEGRADEDWARNING;
968 retCode = _RETURNCODE_TIMEOUT;
971 catch (const Exception &e)
973 exceptionMsg = e.getMessage();
977 exceptionMsg = "Unknown error";
980 _enabledState = _ENABLEDSTATE_ENABLED;
981 sendSubscriptionInitComplete();
983 if (exceptionMsg.size())
985 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
986 "Exception while enabling the indication Service : %s",
987 (const char*)exceptionMsg.getCString()));
989 _healthState = _HEALTHSTATE_DEGRADEDWARNING;
996 Uint32 IndicationService::_disableIndicationService(Uint32 timeoutSeconds,
997 CIMException &cimException)
999 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1000 "IndicationService::_disableIndicationService");
1002 Uint32 retCode = _RETURNCODE_COMPLETEDWITHNOERROR;
1004 AutoMutex mtx(_mutex);
1006 // Check if the service is already disabled.
1007 if (_enabledState == _ENABLEDSTATE_DISABLED)
1013 _enabledState = _ENABLEDSTATE_SHUTTINGDOWN;
1015 // Wait for threads running other than indication threads.
1016 while (_threads.get() - _processIndicationThreads.get() > 1)
1018 Threads::sleep(100);
1021 String exceptionMsg;
1025 if (_deleteActiveSubscriptions(timeoutSeconds))
1027 _sendIndicationServiceDisabled();
1028 _enabledState = _ENABLEDSTATE_DISABLED;
1029 _healthState = _HEALTHSTATE_OK;
1033 _enabledState = _ENABLEDSTATE_ENABLED;
1034 retCode = _RETURNCODE_TIMEOUT;
1035 _healthState = _HEALTHSTATE_DEGRADEDWARNING;
1036 cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
1038 _MSG_STATE_CHANGE_FAILED_KEY,
1039 _MSG_STATE_CHANGE_FAILED,
1040 _getReturnCodeString(_RETURNCODE_TIMEOUT),
1041 _getEnabledStateString(_enabledState),
1042 _getHealthStateString(_healthState)));
1045 catch (const Exception &e)
1047 exceptionMsg = e.getMessage();
1051 exceptionMsg = "Unknown Error";
1054 if (exceptionMsg.size())
1056 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
1057 "Exception while disabling the indication Service : %s",
1058 (const char*)exceptionMsg.getCString()));
1060 _enabledState = _ENABLEDSTATE_ENABLED;
1061 retCode = _RETURNCODE_FAILED;
1062 _healthState = _HEALTHSTATE_DEGRADEDWARNING;
1063 cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
1065 _MSG_STATE_CHANGE_FAILED_KEY,
1066 _MSG_STATE_CHANGE_FAILED,
1068 _getEnabledStateString(_enabledState),
1069 _getHealthStateString(_healthState)));
1076 Boolean IndicationService::_deleteActiveSubscriptions(Uint32 timeoutSeconds)
1078 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1079 "IndicationService::_deleteActiveSubscriptions");
1081 struct timeval startTime;
1082 Time::gettimeofday(&startTime);
1083 Boolean completed = true;
1085 // Check if there are existing pending async requests
1086 if (!_waitForAsyncRequestsComplete(&startTime, timeoutSeconds))
1089 Logger::STANDARD_LOG,
1092 "Failed to disable Indication service within timeout "
1093 "period of $0 seconds. There are $1 existing async "
1094 "requests pending.",
1096 _asyncRequestsPending.get());
1102 Array <ActiveSubscriptionsTableEntry> subscriptionsEntries;
1103 subscriptionsEntries =
1104 _subscriptionTable->getAllActiveSubscriptionEntries();
1106 CIMPropertyList requiredProperties;
1109 String queryLanguage;
1111 for (Uint32 i=0; i < subscriptionsEntries.size(); i++)
1113 CIMInstance instance = subscriptionsEntries[i].subscription;
1114 String creator = instance.getProperty (instance.findProperty
1115 (PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue ().toString ();
1117 AcceptLanguageList acceptLangs;
1118 Uint32 propIndex = instance.findProperty(
1119 PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
1120 if (propIndex != PEG_NOT_FOUND)
1122 String acceptLangsString;
1123 instance.getProperty(propIndex).getValue().get(acceptLangsString);
1124 if (acceptLangsString.size())
1126 acceptLangs = LanguageParser::parseAcceptLanguageHeader(
1130 ContentLanguageList contentLangs;
1131 propIndex = instance.findProperty
1132 (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
1133 if (propIndex != PEG_NOT_FOUND)
1135 String contentLangsString;
1136 instance.getProperty(propIndex).getValue().get(
1137 contentLangsString);
1138 if (contentLangsString.size())
1140 contentLangs = LanguageParser::parseContentLanguageHeader(
1141 contentLangsString);
1144 CIMNamespaceName sourceNameSpace;
1145 Array<CIMName> indicationSubclasses;
1147 _getCreateParams (instance,
1148 indicationSubclasses, requiredProperties,
1149 sourceNameSpace, condition, query, queryLanguage);
1151 _sendAsyncDeleteRequests(
1152 subscriptionsEntries[i].providers,
1158 indicationSubclasses,
1163 if (!_waitForAsyncRequestsComplete(&startTime, timeoutSeconds))
1166 Logger::STANDARD_LOG,
1169 "Failed to disable Indication service within timeout "
1170 "period of $0 seconds. There are $1 async requests pending.",
1172 _asyncRequestsPending.get());
1178 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
1179 _providerIndicationCountTable.clear();
1182 _subscriptionTable->clear();
1191 Boolean IndicationService::_waitForAsyncRequestsComplete(
1192 struct timeval* startTime,
1193 Uint32 timeoutSeconds)
1195 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1196 "IndicationService::_waitForAsyncRequestsComplete");
1198 struct timeval timeNow;
1199 Boolean requestsPending = false;
1200 while (_asyncRequestsPending.get() > 0)
1204 Time::gettimeofday(&timeNow);
1205 if ((Uint32)(timeNow.tv_sec - startTime->tv_sec) > timeoutSeconds)
1207 requestsPending = true;
1211 Threads::sleep(100);
1215 return !requestsPending;
1218 void IndicationService::_sendSubscriptionNotActiveMessagetoHandlerService(
1219 const CIMObjectPath &subscriptionName)
1221 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1222 "IndicationService::_sendSubscriptionNotActiveMessagetoHandlerService");
1224 CIMRequestMessage * notifyRequest =
1225 new CIMNotifySubscriptionNotActiveRequestMessage (
1226 XmlWriter::getNextMessageId (),
1228 QueueIdStack(_handlerService));
1230 AsyncLegacyOperationStart *req =
1231 new AsyncLegacyOperationStart(
1236 AsyncReply *reply = SendWait(req);
1243 void IndicationService::_sendListenerNotActiveMessagetoHandlerService(
1244 const CIMObjectPath &handlerName)
1246 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1247 "IndicationService::_sendListenerNotActiveMessagetoHandlerService");
1249 // Send notify request only to CIMXML handlers
1251 CIMRequestMessage * notifyRequest =
1252 new CIMNotifyListenerNotActiveRequestMessage (
1253 XmlWriter::getNextMessageId (),
1255 QueueIdStack(_handlerService));
1257 AsyncLegacyOperationStart *req =
1258 new AsyncLegacyOperationStart(
1263 AsyncReply *reply = SendWait(req);
1273 void IndicationService::_updateAcceptedSubscription(
1274 CIMInstance &subscription,
1275 const Array<ProviderClassList> &acceptedProviders,
1276 const Array<CIMName> &indicationSubclasses,
1277 const CIMNamespaceName &sourceNameSpace)
1279 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1280 "IndicationService::_updateAcceptedSubscription");
1282 if (acceptedProviders.size() == 0)
1284 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
1285 "No providers accepted subscription on initialization: %s",
1287 subscription.getPath().toString().getCString()));
1290 // No providers accepted the subscription
1291 // Implement the subscription's On Fatal Error Policy
1292 // If subscription is not disabled or removed, send alert and
1293 // Insert entries into the subscription hash tables
1295 if (!_subscriptionRepository->reconcileFatalError(
1299 // Insert entries into the subscription hash tables
1301 _subscriptionTable->insertSubscription(
1304 indicationSubclasses,
1312 // Send NoProviderAlertIndication to handler instances
1313 // ATTN: NoProviderAlertIndication must be defined
1315 Array<CIMInstance> subscriptions;
1316 subscriptions.append(activeSubscriptions[i]);
1317 CIMInstance indicationInstance = _createAlertInstance(
1318 _CLASS_NO_PROVIDER_ALERT, subscriptions);
1320 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
1321 "Sending NoProvider Alert for %u subscriptions",
1322 subscriptions.size()));
1323 _sendAlerts(subscriptions, indicationInstance);
1327 // Get Subscription Filter Name and Handler Name
1329 String logString = _getSubscriptionLogString(
1333 // Log a message for the subscription
1335 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
1338 _MSG_NO_PROVIDER_KEY,
1341 subscription.getPath().getNameSpace().getString()));
1347 // At least one provider accepted the subscription
1348 // Insert entries into the subscription hash tables
1350 _subscriptionTable->insertSubscription(
1353 indicationSubclasses,
1360 Boolean IndicationService::_initializeActiveSubscriptionsFromRepository(
1361 Uint32 timeoutSeconds)
1363 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1364 "IndicationService::_initializeActiveSubscriptionsFromRepository");
1366 struct timeval startTime;
1367 Time::gettimeofday(&startTime);
1368 Boolean completed = true;
1370 #ifdef PEGASUS_INDICATION_PERFINST
1371 Stopwatch stopWatch;
1376 // Create Subscription Repository
1377 _subscriptionRepository.reset(new SubscriptionRepository(_cimRepository));
1379 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
1380 _asyncRequestsPending = 0;
1381 _processIndicationThreads = 0;
1384 // Create Subscription Table
1385 _subscriptionTable.reset(
1386 new SubscriptionTable(_subscriptionRepository.get()));
1388 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
1389 _providerIndicationCountTable.clear();
1392 Array<CIMInstance> activeSubscriptions;
1393 Array<CIMInstance> noProviderSubscriptions;
1394 Boolean invalidInstance = false;
1396 // Get existing active subscriptions from each namespace in the repository
1398 invalidInstance = _subscriptionRepository->getActiveSubscriptions(
1399 activeSubscriptions);
1400 noProviderSubscriptions.clear();
1402 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
1403 "%u active subscription(s) found on initialization",
1404 activeSubscriptions.size()));
1408 String queryLanguage;
1409 CIMPropertyList propertyList;
1410 Array<ProviderClassList> indicationProviders;
1412 for (Uint32 i = 0; i < activeSubscriptions.size(); i++)
1415 // Check for expired subscription
1419 if (_isExpired(activeSubscriptions[i]))
1421 CIMObjectPath path = activeSubscriptions[i].getPath();
1423 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
1424 "Deleting expired subscription on initialization: %s",
1425 (const char *) path.toString().getCString()));
1427 _deleteExpiredSubscription(path);
1429 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
1430 _sendSubscriptionNotActiveMessagetoHandlerService(path);
1432 // If subscription is expired delete the subscription
1433 // and continue on to the next one.
1437 catch (DateTimeOutOfRangeException& e)
1440 // This instance from the repository is invalid
1441 // Log a message and skip it
1443 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
1446 "IndicationService.IndicationService."
1447 "INVALID_SUBSCRIPTION_INSTANCE_IGNORED",
1448 "An invalid Subscription instance was ignored: $0.",
1453 CIMNamespaceName sourceNameSpace;
1454 Array<CIMName> indicationSubclasses;
1455 _getCreateParams(activeSubscriptions[i], indicationSubclasses,
1456 indicationProviders, propertyList, sourceNameSpace, condition,
1457 query, queryLanguage);
1459 if (indicationProviders.size() == 0)
1461 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
1462 "No providers found for subscription on initialization: %s",
1464 activeSubscriptions[i].getPath().toString().getCString()));
1467 // There are no providers that can support this subscription
1468 // Implement the subscription's On Fatal Error Policy
1469 // If subscription is not disabled or removed,
1470 // Append this subscription to no provider list and
1471 // Insert entries into the subscription hash tables
1473 if (!_subscriptionRepository->reconcileFatalError(
1474 activeSubscriptions[i]))
1476 noProviderSubscriptions.append(activeSubscriptions[i]);
1478 _subscriptionTable->insertSubscription(activeSubscriptions[i],
1479 indicationProviders, indicationSubclasses, sourceNameSpace);
1485 // Send Create request message to each provider
1486 // NOTE: These Create requests are not associated with a user request,
1487 // so there is no associated authType or userName
1488 // The Creator from the subscription instance is used for userName,
1489 // and authType is not set
1491 CIMInstance instance = activeSubscriptions[i];
1493 if (!_getCreator(instance, creator))
1496 // This instance from the repository is corrupted
1499 invalidInstance = true;
1503 // Get the language tags that were saved with the subscription instance
1504 AcceptLanguageList acceptLangs;
1505 Uint32 propIndex = instance.findProperty(
1506 PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
1507 if (propIndex != PEG_NOT_FOUND)
1509 String acceptLangsString;
1510 instance.getProperty(propIndex).getValue().get(acceptLangsString);
1511 if (acceptLangsString.size())
1513 acceptLangs = LanguageParser::parseAcceptLanguageHeader(
1517 ContentLanguageList contentLangs;
1518 propIndex = instance.findProperty(
1519 PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
1520 if (propIndex != PEG_NOT_FOUND)
1522 String contentLangsString;
1523 instance.getProperty(propIndex).getValue().get(contentLangsString);
1524 if (contentLangsString.size())
1526 contentLangs = LanguageParser::parseContentLanguageHeader(
1527 contentLangsString);
1531 // If Indication profile support is enabled indication service can be
1532 // enabled dynamically. Send create subscription requests using
1533 // SendAsync() to honor the timeout.
1534 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
1535 if (timeoutSeconds > 0) // if timeout is specified
1537 _sendAsyncCreateRequests(
1538 indicationProviders,
1544 activeSubscriptions[i],
1547 0, // original request is 0
1548 indicationSubclasses,
1554 // Send Create request message to each provider using SendWait() if
1555 // timeout is not specified.
1556 // Note: SendWait is used instead of SendAsync. Initialization must
1557 // deal with multiple subscriptions, each with multiple providers.
1558 // Using SendWait eliminates the need for a callback and the necessity
1559 // to handle multiple levels of aggregation, which would add
1560 // significant complexity. Since initialization cannot complete
1561 // anyway until responses have been received for all subscriptions,
1562 // from all the providers, use of SendWait should not cause a
1563 // significant performance issue.
1566 Array<ProviderClassList> acceptedProviders;
1567 acceptedProviders = _sendWaitCreateRequests(
1568 indicationProviders,
1574 activeSubscriptions[i],
1579 _updateAcceptedSubscription(
1580 activeSubscriptions[i],
1582 indicationSubclasses,
1585 } // for each active subscription
1588 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
1589 if (timeoutSeconds > 0)
1591 if (!_waitForAsyncRequestsComplete(&startTime, timeoutSeconds))
1594 Logger::STANDARD_LOG,
1597 "Failed to enable Indication service within timeout "
1598 "period of $0 seconds. There are $1 async"
1599 " requests pending.",
1601 _asyncRequestsPending.get());
1608 // Log a message if any invalid instances were found
1610 if (invalidInstance)
1612 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
1614 _MSG_INVALID_INSTANCES_KEY, _MSG_INVALID_INSTANCES));
1617 // Log a message for any subscription for which there is no longer any
1620 if (noProviderSubscriptions.size() > 0)
1624 // Send NoProviderAlertIndication to handler instances
1625 // ATTN: NoProviderAlertIndication must be defined
1627 CIMInstance indicationInstance = _createAlertInstance(
1628 _CLASS_NO_PROVIDER_ALERT, noProviderSubscriptions);
1630 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
1631 "Sending NoProvider Alert for %u subscriptions",
1632 noProviderSubscriptions.size()));
1633 _sendAlerts(noProviderSubscriptions, indicationInstance);
1636 // Log a message for each subscription
1638 for (Uint32 i = 0; i < noProviderSubscriptions.size(); i++)
1641 // Get Subscription Filter Name and Handler Name
1644 _getSubscriptionLogString(noProviderSubscriptions[i]);
1647 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
1649 _MSG_NO_PROVIDER_KEY,
1652 noProviderSubscriptions[i].getPath().getNameSpace().
1657 #ifdef PEGASUS_INDICATION_PERFINST
1660 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
1661 "%s: %.3f seconds", "Initialize", stopWatch.getElapsed()));
1669 void IndicationService::_terminate()
1671 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE, "IndicationService::_terminate");
1673 Array<CIMInstance> activeSubscriptions;
1674 CIMInstance indicationInstance;
1677 // A message is already logged that CIM Server is shutting down --
1678 // no need to log a message
1682 // Get existing active subscriptions from hash table
1684 activeSubscriptions = _getActiveSubscriptions();
1686 if (activeSubscriptions.size() > 0)
1689 // Create CimomShutdownAlertIndication instance
1690 // ATTN: CimomShutdownAlertIndication must be defined
1692 indicationInstance = _createAlertInstance(
1693 _CLASS_CIMOM_SHUTDOWN_ALERT, activeSubscriptions);
1696 // Send CimomShutdownAlertIndication to each unique handler instance
1698 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
1699 "Sending CIMServerShutdown Alert for %u subscriptions",
1700 activeSubscriptions.size()));
1701 _sendAlerts(activeSubscriptions, indicationInstance);
1706 // Remove entries from the SubscriptionTable's Active Subscriptions and
1707 // Subscription Classes tables
1709 // NOTE: The table entries are removed when the SubscriptionTable
1710 // destructor is called by the IndicationService destructor. However,
1711 // currently the IndicationService destructor is never called, so the
1712 // IndicationService must call the SubscriptionTable clear() function to
1713 // remove the table entries.
1714 _subscriptionTable->clear();
1719 void IndicationService::_checkNonprivilegedAuthorization(
1720 const String& userName)
1722 #ifndef PEGASUS_OS_ZOS
1723 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1724 "IndicationService::_checkNonprivilegedAuthorization");
1726 if (!_enableSubscriptionsForNonprivilegedUsers)
1728 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
1729 "_checkNonprivilegedAuthorization - checking whether user %s is "
1731 (const char*) userName.getCString()));
1732 if (!System::isPrivilegedUser(userName))
1734 MessageLoaderParms parms(
1735 "IndicationService.IndicationService."
1736 "_MSG_NON_PRIVILEGED_ACCESS_DISABLED",
1737 "User ($0) is not authorized to perform this operation.",
1740 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_ACCESS_DENIED, parms);
1748 void IndicationService::_handleCreateInstanceRequest(const Message * message)
1750 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1751 "IndicationService::_handleCreateInstanceRequest");
1753 CIMCreateInstanceRequestMessage* request =
1754 (CIMCreateInstanceRequestMessage*) message;
1756 Boolean responseSent = false;
1758 CIMObjectPath instanceRef;
1759 CIMObjectPath subscriptionPath;
1761 CIMInstance instance = request->newInstance.clone();
1763 String userName = ((IdentityContainer)request->operationContext.get(
1764 IdentityContainer::NAME)).getUserName();
1765 _checkNonprivilegedAuthorization(userName);
1767 AcceptLanguageList acceptLangs =
1768 ((AcceptLanguageListContainer)request->operationContext.get(
1769 AcceptLanguageListContainer::NAME)).getLanguages();
1770 ContentLanguageList contentLangs =
1771 ((ContentLanguageListContainer)request->operationContext.get(
1772 ContentLanguageListContainer::NAME)).getLanguages();
1774 if (_canCreate(instance, request->nameSpace))
1777 // If the instance is of the PEGASUS_CLASSNAME_INDSUBSCRIPTION
1778 // class or the PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION
1779 // class and subscription state is enabled, determine if any
1780 // providers can serve the subscription
1782 Uint16 subscriptionState;
1785 String queryLanguage;
1786 CIMPropertyList requiredProperties;
1787 CIMNamespaceName sourceNameSpace;
1788 Array<CIMName> indicationSubclasses;
1789 Array<ProviderClassList> indicationProviders;
1791 if ((instance.getClassName().equal(
1792 PEGASUS_CLASSNAME_INDSUBSCRIPTION)) ||
1793 (instance.getClassName().equal(
1794 PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION)))
1796 _subscriptionRepository->
1797 beginCreateSubscription(instance.getPath());
1801 subscriptionPath = instance.getPath();
1803 // Get subscription state
1805 // NOTE: _canCreate has already validated the
1806 // SubscriptionState property in the instance; if missing, it
1807 // was added with the default value; if null, it was set to
1808 // the default value; if invalid, an exception was thrown
1810 CIMValue subscriptionStateValue;
1811 subscriptionStateValue = instance.getProperty(
1812 instance.findProperty(
1813 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE)).getValue();
1814 subscriptionStateValue.get(subscriptionState);
1816 if ((subscriptionState == STATE_ENABLED) ||
1817 (subscriptionState == STATE_ENABLEDDEGRADED))
1819 _getCreateParams(instance, indicationSubclasses,
1820 indicationProviders, requiredProperties,
1821 sourceNameSpace, condition, query, queryLanguage);
1823 if (indicationProviders.size() == 0)
1826 // There are no providers that can support this
1830 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
1831 MessageLoaderParms(_MSG_NO_PROVIDERS_KEY,
1832 _MSG_NO_PROVIDERS));
1836 // Send Create request message to each provider
1838 _sendAsyncCreateRequests(indicationProviders,
1839 sourceNameSpace, requiredProperties, condition,
1840 query, queryLanguage, instance,
1844 indicationSubclasses,
1845 userName, request->authType);
1848 // Response is sent from _handleCreateResponseAggregation
1850 responseSent = true;
1855 // Create instance for disabled subscription
1857 instanceRef = _subscriptionRepository->createInstance(
1858 instance, request->nameSpace, userName,
1859 acceptLangs, contentLangs, false);
1864 _subscriptionRepository->cancelCreateSubscription(
1872 // Create instance for filter or handler
1874 instanceRef = _subscriptionRepository->createInstance(
1875 instance, request->nameSpace, userName,
1876 acceptLangs, contentLangs, false);
1881 // Send response, if not sent from callback
1882 // (for example, if there are no indication providers that can support a
1887 // l10n - no Content-Language in response
1888 CIMCreateInstanceResponseMessage* response =
1889 dynamic_cast<CIMCreateInstanceResponseMessage*>(
1890 request->buildResponse());
1891 PEGASUS_ASSERT(response != 0);
1892 response->instanceName = instanceRef;
1893 _enqueueResponse(request, response);
1899 void IndicationService::_handleGetInstanceRequest(const Message* message)
1901 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
1902 "IndicationService::_handleGetInstanceRequest");
1904 CIMGetInstanceRequestMessage* request =
1905 (CIMGetInstanceRequestMessage*) message;
1907 CIMInstance instance;
1908 String contentLangsString;
1910 String userName = ((IdentityContainer)request->operationContext.
1911 get(IdentityContainer::NAME)).getUserName();
1913 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
1914 if (request->className.equal(PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE)||
1915 request->className.equal(
1916 PEGASUS_CLASSNAME_CIM_INDICATIONSERVICECAPABILITIES))
1918 _checkNonprivilegedAuthorization(userName);
1919 instance = _indicationServiceConfiguration->getInstance(
1921 request->instanceName,
1922 request->includeQualifiers,
1923 request->includeClassOrigin,
1924 request->propertyList);
1929 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
1930 if (request->className.equal(PEGASUS_CLASSNAME_PROVIDERINDDATA))
1932 instance = _providerIndicationCountTable.
1933 getProviderIndicationDataInstance(request->instanceName);
1935 else if (request->className.equal(
1936 PEGASUS_CLASSNAME_SUBSCRIPTIONINDDATA))
1938 instance = _subscriptionTable->
1939 getSubscriptionIndicationDataInstance(request->instanceName);
1944 _checkNonprivilegedAuthorization(userName);
1947 // Add Creator to property list, if not null
1948 // Also, if a Subscription and Time Remaining is requested,
1949 // Ensure Subscription Duration and Start Time are in property list
1951 Boolean setTimeRemaining;
1952 Boolean startTimeAdded;
1953 Boolean durationAdded;
1954 CIMPropertyList propertyList = request->propertyList;
1955 CIMName className = request->instanceName.getClassName();
1956 _updatePropertyList(
1964 // Get instance from repository
1966 instance = _subscriptionRepository->getInstance(
1968 request->instanceName,
1969 request->includeQualifiers,
1970 request->includeClassOrigin,
1974 // Remove Creator property from instance before returning
1977 if (!_getCreator(instance, creator))
1980 // This instance from the repository is corrupted
1982 MessageLoaderParms parms(
1983 _MSG_INVALID_INSTANCES_KEY,
1984 _MSG_INVALID_INSTANCES);
1985 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, parms);
1987 instance.removeProperty(
1988 instance.findProperty(
1989 PEGASUS_PROPERTYNAME_INDSUB_CREATOR));
1991 // Remove CretaionTime property from CIMXML handlers
1992 CIMName clsName = instance.getClassName();
1994 if (clsName.equal(PEGASUS_CLASSNAME_INDHANDLER_CIMXML) ||
1995 clsName.equal(PEGASUS_CLASSNAME_LSTNRDST_CIMXML))
1997 Uint32 idx = instance.findProperty(
1998 PEGASUS_PROPERTYNAME_LSTNRDST_CREATIONTIME);
2000 if (idx != PEG_NOT_FOUND)
2002 instance.removeProperty(idx);
2008 // Remove the language properties from instance before returning
2010 Uint32 propIndex = instance.findProperty(
2011 PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
2012 if (propIndex != PEG_NOT_FOUND)
2014 instance.removeProperty(propIndex);
2017 propIndex = instance.findProperty(
2018 PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
2019 if (propIndex != PEG_NOT_FOUND)
2021 // Get the content languages to be sent in the Content-Language
2023 instance.getProperty(propIndex).getValue().
2024 get(contentLangsString);
2025 instance.removeProperty(propIndex);
2029 // If a subscription with a duration, calculate subscription time
2030 // remaining, and add property to the instance
2032 if (setTimeRemaining)
2034 _setTimeRemaining(instance);
2037 instance.removeProperty(
2038 instance.findProperty(
2039 _PROPERTY_STARTTIME));
2043 instance.removeProperty(
2044 instance.findProperty(
2045 _PROPERTY_DURATION));
2050 CIMGetInstanceResponseMessage * response =
2051 dynamic_cast<CIMGetInstanceResponseMessage *>(request->buildResponse());
2052 if (contentLangsString.size())
2054 // Note: setting Content-Language in the response to the
2055 // contentLanguage in the repository.
2056 response->operationContext.set(ContentLanguageListContainer(
2057 LanguageParser::parseContentLanguageHeader(contentLangsString)));
2059 response->getResponseData().setInstance(instance);
2060 _enqueueResponse(request, response);
2065 void IndicationService::_handleEnumerateInstancesRequest(const Message* message)
2067 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
2068 "IndicationService::_handleEnumerateInstancesRequest");
2070 CIMEnumerateInstancesRequestMessage* request =
2071 (CIMEnumerateInstancesRequestMessage*) message;
2073 Array<CIMInstance> returnedInstances;
2074 String aggregatedLangs;
2076 String userName = ((IdentityContainer)request->operationContext.
2077 get(IdentityContainer::NAME)).getUserName();
2079 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
2080 if (request->className.equal(PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE) ||
2081 request->className.equal(
2082 PEGASUS_CLASSNAME_CIM_INDICATIONSERVICECAPABILITIES))
2084 _checkNonprivilegedAuthorization(userName);
2085 returnedInstances = _indicationServiceConfiguration->
2086 enumerateInstancesForClass(
2089 request->includeQualifiers,
2090 request->includeClassOrigin,
2091 request->propertyList);
2096 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
2097 if (request->className.equal(PEGASUS_CLASSNAME_PROVIDERINDDATA))
2099 returnedInstances = _providerIndicationCountTable.
2100 enumerateProviderIndicationDataInstances();
2102 else if (request->className.equal(
2103 PEGASUS_CLASSNAME_SUBSCRIPTIONINDDATA))
2105 returnedInstances = _subscriptionTable->
2106 enumerateSubscriptionIndicationDataInstances();
2111 _checkNonprivilegedAuthorization(userName);
2112 Array<CIMInstance> enumInstances;
2115 // Add Creator to property list, if not null
2116 // Also, if a Subscription and Time Remaining is requested,
2117 // Ensure Subscription Duration and Start Time are in property
2120 Boolean setTimeRemaining;
2121 Boolean startTimeAdded;
2122 Boolean durationAdded;
2123 CIMPropertyList propertyList = request->propertyList;
2124 _updatePropertyList(request->className,
2125 propertyList, setTimeRemaining, startTimeAdded, durationAdded);
2128 _subscriptionRepository->enumerateInstancesForClass(
2129 request->nameSpace, request->className,
2130 request->includeQualifiers, request->includeClassOrigin,
2133 // Vars used to aggregate the content languages of the subscription
2135 Boolean langMismatch = false;
2139 // Remove Creator and language properties from instances before
2142 for (Uint32 i = 0; i < enumInstances.size(); i++)
2145 if (!_getCreator(enumInstances[i], creator))
2148 // This instance from the repository is corrupted
2154 enumInstances[i].removeProperty(
2155 enumInstances[i].findProperty(
2156 PEGASUS_PROPERTYNAME_INDSUB_CREATOR));
2158 // Remove CretaionTime property from CIMXML handlers
2159 CIMName clsName = enumInstances[i].getClassName();
2161 if (clsName.equal(PEGASUS_CLASSNAME_INDHANDLER_CIMXML) ||
2162 clsName.equal(PEGASUS_CLASSNAME_LSTNRDST_CIMXML))
2164 Uint32 idx = enumInstances[i].findProperty(
2165 PEGASUS_PROPERTYNAME_LSTNRDST_CREATIONTIME);
2167 if (idx != PEG_NOT_FOUND)
2169 enumInstances[i].removeProperty(idx);
2173 propIndex = enumInstances[i].findProperty(
2174 PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
2175 String contentLangs;
2176 if (propIndex != PEG_NOT_FOUND)
2178 enumInstances[i].getProperty(propIndex).getValue().get(
2180 enumInstances[i].removeProperty(propIndex);
2183 propIndex = enumInstances[i].findProperty(
2184 PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
2185 if (propIndex != PEG_NOT_FOUND)
2187 enumInstances[i].removeProperty(propIndex);
2190 // Determine what to set into the Content-Language header back
2194 if (contentLangs == String::EMPTY)
2196 langMismatch = true;
2197 aggregatedLangs = String::EMPTY;
2201 if (aggregatedLangs == String::EMPTY)
2203 aggregatedLangs = contentLangs;
2205 else if (aggregatedLangs != contentLangs)
2207 langMismatch = true;
2208 aggregatedLangs = String::EMPTY;
2214 // If a subscription with a duration, calculate subscription
2215 // time remaining, and add property to the instance
2217 if (setTimeRemaining)
2221 _setTimeRemaining(enumInstances[i]);
2223 catch (DateTimeOutOfRangeException&)
2226 // This instance from the repository is invalid
2233 enumInstances[i].removeProperty(enumInstances[i].
2234 findProperty(_PROPERTY_STARTTIME));
2238 enumInstances[i].removeProperty(
2239 enumInstances[i].findProperty(_PROPERTY_DURATION));
2243 returnedInstances.append(enumInstances[i]);
2247 CIMEnumerateInstancesResponseMessage* response =
2248 dynamic_cast<CIMEnumerateInstancesResponseMessage*>(
2249 request->buildResponse());
2250 PEGASUS_ASSERT(response != 0);
2251 if (aggregatedLangs.size())
2253 // Note: setting Content-Language in the response to the aggregated
2254 // contentLanguage from the instances in the repository.
2255 response->operationContext.set(ContentLanguageListContainer(
2256 LanguageParser::parseContentLanguageHeader(aggregatedLangs)));
2258 response->getResponseData().setInstances(returnedInstances);
2259 _enqueueResponse(request, response);
2264 void IndicationService::_handleEnumerateInstanceNamesRequest(
2265 const Message* message)
2267 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
2268 "IndicationService::_handleEnumerateInstanceNamesRequest");
2270 CIMEnumerateInstanceNamesRequestMessage* request =
2271 (CIMEnumerateInstanceNamesRequestMessage*) message;
2273 Array<CIMObjectPath> enumInstanceNames;
2275 String userName = ((IdentityContainer)request->operationContext.get(
2276 IdentityContainer::NAME)).getUserName();
2278 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
2279 if (request->className.equal(
2280 PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE) ||
2281 request->className.equal(
2282 PEGASUS_CLASSNAME_CIM_INDICATIONSERVICECAPABILITIES))
2284 _checkNonprivilegedAuthorization(userName);
2285 enumInstanceNames = _indicationServiceConfiguration->
2286 enumerateInstanceNamesForClass(
2288 request->className);
2293 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
2294 if (request->className.equal(PEGASUS_CLASSNAME_PROVIDERINDDATA))
2296 enumInstanceNames = _providerIndicationCountTable.
2297 enumerateProviderIndicationDataInstanceNames();
2299 else if (request->className.equal(
2300 PEGASUS_CLASSNAME_SUBSCRIPTIONINDDATA))
2302 enumInstanceNames = _subscriptionTable->
2303 enumerateSubscriptionIndicationDataInstanceNames();
2308 _checkNonprivilegedAuthorization(userName);
2310 _subscriptionRepository->enumerateInstanceNamesForClass(
2312 request->className);
2315 // Note: not setting Content-Language in the response
2316 CIMEnumerateInstanceNamesResponseMessage* response =
2317 dynamic_cast<CIMEnumerateInstanceNamesResponseMessage *>(
2318 request->buildResponse());
2319 PEGASUS_ASSERT(response != 0);
2320 response->getResponseData().setInstanceNames(enumInstanceNames);
2321 _enqueueResponse(request, response);
2326 void IndicationService::_handleModifyInstanceRequest(const Message* message)
2328 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
2329 "IndicationService::_handleModifyInstanceRequest");
2331 CIMModifyInstanceRequestMessage* request =
2332 (CIMModifyInstanceRequestMessage*) message;
2334 Boolean responseSent = false;
2336 String userName = ((IdentityContainer)request->operationContext.get(
2337 IdentityContainer::NAME)).getUserName();
2338 _checkNonprivilegedAuthorization(userName);
2341 // Get the instance name
2343 CIMObjectPath instanceReference = request->modifiedInstance.getPath();
2346 // Get instance from repository
2348 CIMInstance instance;
2350 instance = _subscriptionRepository->getInstance(
2351 request->nameSpace, instanceReference);
2353 CIMInstance modifiedInstance = request->modifiedInstance;
2354 if (_canModify(request, instanceReference, instance, modifiedInstance))
2357 // Set path in instance
2359 instanceReference.setNameSpace(request->nameSpace);
2360 instance.setPath(instanceReference);
2363 // Check for expired subscription
2367 if (_isExpired(instance))
2370 // Delete the subscription instance
2372 _deleteExpiredSubscription(instanceReference);
2373 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
2374 _sendSubscriptionNotActiveMessagetoHandlerService(
2379 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
2381 "IndicationService.IndicationService._MSG_EXPIRED",
2382 "An expired subscription cannot be modified: the "
2383 "subscription is deleted."));
2386 catch (DateTimeOutOfRangeException&)
2389 // This instance from the repository is invalid
2396 // _canModify, above, already checked that propertyList is not
2397 // null, and that numProperties is 0 or 1
2399 CIMPropertyList propertyList = request->propertyList;
2400 if (request->propertyList.size() > 0)
2403 // Get current state from instance
2405 Uint16 currentState;
2406 Boolean valid = true;
2407 if (_subscriptionRepository->getState(instance, currentState))
2409 valid = _validateState(currentState);
2415 // This instance from the repository is corrupted
2418 MessageLoaderParms parms(_MSG_INVALID_INSTANCES_KEY,
2419 _MSG_INVALID_INSTANCES);
2420 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, parms);
2426 // NOTE: _canModify has already validated the
2427 // SubscriptionState property in the instance; if missing, it
2428 // was added with the default value; if null, it was set to
2429 // the default value; if invalid, an exception was thrown
2432 modifiedInstance.getProperty(modifiedInstance.findProperty(
2433 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE)).getValue().get(
2437 // If Subscription State has changed,
2438 // Set Time of Last State Change to current date time
2440 CIMDateTime currentDateTime =
2441 CIMDateTime::getCurrentDateTime();
2442 if (newState != currentState)
2444 if (modifiedInstance.findProperty(_PROPERTY_LASTCHANGE) !=
2447 CIMProperty lastChange = modifiedInstance.getProperty(
2448 modifiedInstance.findProperty(
2449 _PROPERTY_LASTCHANGE));
2450 lastChange.setValue(CIMValue(currentDateTime));
2454 modifiedInstance.addProperty(CIMProperty(
2455 _PROPERTY_LASTCHANGE, CIMValue(currentDateTime)));
2457 Array<CIMName> properties =
2458 propertyList.getPropertyNameArray();
2459 properties.append(_PROPERTY_LASTCHANGE);
2460 propertyList.set(properties);
2464 // If Subscription is to be enabled, and this is the first
2465 // time, set Subscription Start Time
2467 if ((newState == STATE_ENABLED) ||
2468 (newState == STATE_ENABLEDDEGRADED))
2471 // If Subscription Start Time is null, set value
2472 // to the current date time
2474 CIMDateTime startTime;
2475 CIMProperty startTimeProperty = instance.getProperty(
2476 instance.findProperty(_PROPERTY_STARTTIME));
2477 CIMValue startTimeValue = startTimeProperty.getValue();
2478 Boolean setStart = false;
2479 if (startTimeValue.isNull())
2485 startTimeValue.get(startTime);
2487 if (startTime.isInterval())
2489 if (startTime.equal(
2490 CIMDateTime(_ZERO_INTERVAL_STRING)))
2499 if (modifiedInstance.findProperty(_PROPERTY_STARTTIME)
2502 CIMProperty startTimeProperty =
2503 modifiedInstance.getProperty(
2504 modifiedInstance.findProperty(
2505 _PROPERTY_STARTTIME));
2506 startTimeProperty.setValue(CIMValue(currentDateTime));
2510 modifiedInstance.addProperty(CIMProperty(
2511 _PROPERTY_STARTTIME,
2512 CIMValue(currentDateTime)));
2515 Array<CIMName> properties =
2516 propertyList.getPropertyNameArray();
2517 properties.append(_PROPERTY_STARTTIME);
2518 propertyList.set(properties);
2522 // Add the language properties to the modified instance.
2523 // Note: These came from the Accept-Language and
2524 // Content-Language headers in the HTTP messages, and may be
2526 AcceptLanguageList acceptLangs =
2527 ((AcceptLanguageListContainer)request->operationContext.get(
2528 AcceptLanguageListContainer::NAME)).getLanguages();
2529 modifiedInstance.addProperty(CIMProperty(
2530 PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS,
2531 LanguageParser::buildAcceptLanguageHeader(acceptLangs)));
2533 ContentLanguageList contentLangs =
2534 ((ContentLanguageListContainer)request->operationContext.get
2535 (ContentLanguageListContainer::NAME)).getLanguages();
2536 modifiedInstance.addProperty (CIMProperty
2537 (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS,
2538 LanguageParser::buildContentLanguageHeader(contentLangs)));
2540 Array<CIMName> properties = propertyList.getPropertyNameArray();
2541 properties.append (PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
2542 properties.append (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
2543 propertyList.set (properties);
2546 // If subscription is to be enabled, determine if there are
2547 // any indication providers that can serve the subscription
2549 Array<ProviderClassList> indicationProviders;
2550 CIMPropertyList requiredProperties;
2551 CIMNamespaceName sourceNameSpace;
2554 String queryLanguage;
2555 Array<CIMName> indicationSubclasses;
2557 if (((newState == STATE_ENABLED) ||
2558 (newState == STATE_ENABLEDDEGRADED))
2559 && ((currentState != STATE_ENABLED) &&
2560 (currentState != STATE_ENABLEDDEGRADED)))
2563 // Subscription was previously not enabled but is now to
2566 _getCreateParams(instance, indicationSubclasses,
2567 indicationProviders, requiredProperties,
2568 sourceNameSpace, condition, query, queryLanguage);
2570 if (indicationProviders.size() == 0)
2573 // There are no providers that can support this
2576 instance.setPath(instanceReference);
2577 _subscriptionRepository->reconcileFatalError(instance);
2580 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
2581 MessageLoaderParms(_MSG_NO_PROVIDERS_KEY,
2582 _MSG_NO_PROVIDERS));
2587 // Modify the instance in the repository
2589 modifiedInstance.setPath(instanceReference);
2590 _subscriptionRepository->modifyInstance(
2591 request->nameSpace, modifiedInstance,
2592 request->includeQualifiers, propertyList);
2595 TRC_INDICATION_SERVICE,
2597 "IndicationService::_handleModifyInstanceRequest - "
2598 "Name Space: %s Instance name: %s",
2600 request->nameSpace.getString().getCString(),
2602 modifiedInstance.getClassName().getString().getCString()
2606 // If subscription is newly enabled, send Create requests
2607 // and enable providers
2609 if (((newState == STATE_ENABLED) ||
2610 (newState == STATE_ENABLEDDEGRADED))
2611 && ((currentState != STATE_ENABLED) &&
2612 (currentState != STATE_ENABLEDDEGRADED)))
2614 instanceReference.setNameSpace(request->nameSpace);
2615 instance.setPath(instanceReference);
2617 _sendAsyncCreateRequests(
2618 indicationProviders,
2628 indicationSubclasses,
2633 // Response is sent from _handleCreateResponseAggregation
2635 responseSent = true;
2637 else if ((newState == STATE_DISABLED) &&
2638 ((currentState == STATE_ENABLED) ||
2639 (currentState == STATE_ENABLEDDEGRADED)))
2642 // Subscription was previously enabled but is now to be
2645 instanceReference.setNameSpace(request->nameSpace);
2646 instance.setPath(instanceReference);
2647 indicationProviders = _getDeleteParams(instance,
2648 indicationSubclasses, sourceNameSpace);
2651 // Send Delete requests
2653 if (indicationProviders.size() > 0)
2655 _sendAsyncDeleteRequests(
2656 indicationProviders,
2662 indicationSubclasses,
2667 // Response is sent from
2668 // _handleDeleteResponseAggregation
2670 responseSent = true;
2671 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
2672 _sendSubscriptionNotActiveMessagetoHandlerService(
2681 // Send response, if not sent from callback
2682 // (for example, if there are no indication providers that can support a
2687 // Note: don't need to set content-language in the response.
2688 CIMResponseMessage * response = request->buildResponse();
2689 _enqueueResponse(request, response);
2695 void IndicationService::_handleDeleteInstanceRequest(const Message* message)
2697 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
2698 "IndicationService::_handleDeleteInstanceRequest");
2700 CIMDeleteInstanceRequestMessage* request =
2701 (CIMDeleteInstanceRequestMessage*) message;
2703 Boolean responseSent = false;
2705 String userName = ((IdentityContainer)request->operationContext.get(
2706 IdentityContainer::NAME)).getUserName();
2707 _checkNonprivilegedAuthorization(userName);
2710 // Check if instance may be deleted -- a filter or handler instance
2711 // referenced by a subscription instance may not be deleted
2713 if (_canDelete(request->instanceName, request->nameSpace, userName))
2716 // If a subscription, get the instance from the repository
2718 CIMInstance subscriptionInstance;
2719 if (request->instanceName.getClassName().equal(
2720 PEGASUS_CLASSNAME_INDSUBSCRIPTION) ||
2721 request->instanceName.getClassName ().equal(
2722 PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))
2724 subscriptionInstance =
2725 _subscriptionRepository->getInstance(
2726 request->nameSpace, request->instanceName);
2730 // Delete instance from repository
2732 _subscriptionRepository->deleteInstance(
2733 request->nameSpace, request->instanceName);
2735 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
2736 if (request->instanceName.getClassName().equal(
2737 PEGASUS_CLASSNAME_LSTNRDST_CIMXML) ||
2738 request->instanceName.getClassName().equal(
2739 PEGASUS_CLASSNAME_INDHANDLER_CIMXML))
2741 CIMObjectPath handlerName = request->instanceName;
2742 handlerName.setNameSpace(request->nameSpace);
2743 _sendListenerNotActiveMessagetoHandlerService(handlerName);
2748 TRC_INDICATION_SERVICE,
2750 "IndicationService::_handleDeleteInstanceRequest - "
2751 "Name Space: %s Instance name: %s",
2752 (const char*) request->nameSpace.getString().getCString(),
2754 request->instanceName.getClassName().getString().getCString()
2757 if (request->instanceName.getClassName().equal(
2758 PEGASUS_CLASSNAME_INDSUBSCRIPTION) ||
2759 request->instanceName.getClassName ().equal(
2760 PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))
2763 // If subscription is active, send delete requests to providers
2764 // and update hash tables
2766 Uint16 subscriptionState;
2767 CIMValue subscriptionStateValue;
2768 subscriptionStateValue = subscriptionInstance.getProperty(
2769 subscriptionInstance.findProperty(
2770 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE)).getValue();
2771 subscriptionStateValue.get(subscriptionState);
2773 if ((subscriptionState == STATE_ENABLED) ||
2774 (subscriptionState == STATE_ENABLEDDEGRADED))
2776 Array<ProviderClassList> indicationProviders;
2777 Array<CIMName> indicationSubclasses;
2778 CIMNamespaceName sourceNamespaceName;
2779 CIMObjectPath instanceReference = request->instanceName;
2780 instanceReference.setNameSpace(request->nameSpace);
2781 subscriptionInstance.setPath(instanceReference);
2783 indicationProviders = _getDeleteParams(
2784 subscriptionInstance,
2785 indicationSubclasses,
2786 sourceNamespaceName);
2788 if (indicationProviders.size() > 0)
2791 // Send Delete requests
2793 _sendAsyncDeleteRequests(
2794 indicationProviders,
2795 sourceNamespaceName,
2796 subscriptionInstance,
2797 ((AcceptLanguageListContainer)
2798 request->operationContext.get(
2799 AcceptLanguageListContainer::NAME)).
2801 ((ContentLanguageListContainer)
2802 request->operationContext.get(
2803 ContentLanguageListContainer::NAME)).
2806 indicationSubclasses,
2811 // Response is sent from
2812 // _handleDeleteResponseAggregation
2814 responseSent = true;
2815 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
2816 _sendSubscriptionNotActiveMessagetoHandlerService(
2823 // Subscription was enabled, but had no providers
2824 // Remove entries from the subscription hash tables
2826 _subscriptionTable->removeSubscription(
2827 subscriptionInstance,
2828 indicationSubclasses,
2829 sourceNamespaceName,
2830 indicationProviders);
2837 // Send response, if not sent from callback
2838 // (for example, if a subscription had no indication providers)
2842 CIMResponseMessage * response = request->buildResponse();
2843 _enqueueResponse(request, response);
2849 // l10n TODO - might need to globalize another flow and another consumer
2850 // interface (ie. mdd's) if we can't agree on one export flow and consumer
2851 // interface (see PEP67)
2853 void IndicationService::_handleProcessIndicationRequest(Message* message)
2856 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
2857 _processIndicationThreads++;
2858 AutoPtr<AtomicInt, DecAtomicInt> counter(&_processIndicationThreads);
2861 #ifdef PEGASUS_INDICATION_PERFINST
2862 Stopwatch stopWatch;
2865 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
2866 "IndicationService::_handleProcessIndicationRequest");
2868 #ifdef PEGASUS_INDICATION_PERFINST
2873 CIMProcessIndicationRequestMessage* request = dynamic_cast<
2874 CIMProcessIndicationRequestMessage*> (message);
2875 PEGASUS_ASSERT(request != 0);
2877 Array<CIMInstance> matchedSubscriptions;
2878 Array<String> matchedSubscriptionsKeys;
2880 CIMInstance indication = request->indicationInstance;
2884 PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL4,
2885 "Received %s Indication %s from namespace %s from provider %s",
2886 (const char*)(indication.getClassName().getString().getCString()),
2887 (const char*)(request->messageId.getCString()),
2888 (const char*)(request->nameSpace.getString().getCString()),
2889 (const char*)(request->provider.getProperty(request->provider.
2890 findProperty(PEGASUS_PROPERTYNAME_NAME)).getValue().toString().
2894 // Get supported properties by the indication provider
2895 // Get Indication class properties
2896 // Check if the provider supports all properties of the indication
2897 // class, if so, set to null
2899 Array<CIMName> providerSupportedProperties;
2900 Array<CIMName> indicationClassProperties;
2901 CIMPropertyList supportedPropertyList;
2903 for (Uint32 i = 0; i < indication.getPropertyCount(); i++)
2905 providerSupportedProperties.append(
2906 indication.getProperty(i).getName());
2909 supportedPropertyList = _checkPropertyList(providerSupportedProperties,
2911 indication.getClassName(),
2912 indicationClassProperties);
2915 // Get initial subscriptions based on the class name, namespace
2916 // of the generated indication, and subscriptions specified by the
2917 // indication provider if the provider included subscriptions
2918 // in the subscriptionInstanceNamesContainer
2920 Array<CIMInstance> subscriptions;
2921 Array<String> subscriptionKeys;
2922 _getRelevantSubscriptions(
2923 request->subscriptionInstanceNames,
2924 indication.getClassName(),
2930 for (Uint32 i = 0; i < subscriptions.size(); i++)
2934 QueryExpression queryExpr;
2936 String queryLanguage;
2938 CIMNamespaceName sourceNameSpace;
2941 // Get filter query expression of the subscription
2943 _subscriptionRepository->getFilterProperties
2944 (subscriptions[i], filterQuery, sourceNameSpace,
2945 queryLanguage, filterName);
2947 queryExpr = _getQueryExpression(
2948 filterQuery, queryLanguage, sourceNameSpace);
2951 // Evaluate if the subscription matches the indication by
2953 // 1) Whether the properties (in WHERE clause) from filter
2954 // query are supported by the indication provider;
2955 // 2) Whether the subscripton is expired;
2956 // 3) Whether the filter criteria are met by the generated
2959 if (_subscriptionMatch (subscriptions[i], indication,
2960 supportedPropertyList, queryExpr, sourceNameSpace))
2962 PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL4,
2963 "%s Indication %s satisfies filter %s:%s query "
2964 "expression \"%s\"",
2965 (const char*)(indication.getClassName().
2966 getString().getCString()),
2967 (const char*)(request->messageId.getCString()),
2968 (const char*)(sourceNameSpace.getString().
2970 (const char*)(filterName.getCString()),
2971 (const char*)(filterQuery.getCString())));
2974 // Format the indication
2975 // This includes two parts:
2976 // 1) Use QueryExpression::applyProjection to remove
2977 // properties not listed in the SELECT clause;
2978 // 2) Remove any properties that may be left on the
2979 // indication that are not in the indication class.
2980 // These are properties added by the provider
2983 CIMInstance formattedIndication = indication.clone();
2985 if (_formatIndication(formattedIndication,
2987 providerSupportedProperties,
2988 indicationClassProperties))
2991 // get the handler instance and forward the formatted
2992 // indication to the handler
2994 CIMInstance handlerInstance =
2995 _subscriptionRepository->getHandler(
2998 PEG_TRACE((TRC_INDICATION_GENERATION, Tracer::LEVEL4,
2999 "Handler %s:%s.%s found for %s Indication %s",
3000 (const char*)(request->nameSpace.getString().
3002 (const char*)(handlerInstance.getClassName().
3003 getString().getCString()),
3004 (const char*)(handlerInstance.getProperty(
3005 handlerInstance.findProperty(
3006 PEGASUS_PROPERTYNAME_NAME)).getValue().
3007 toString().getCString()),
3008 (const char*)(indication.getClassName().
3009 getString().getCString()),
3010 (const char*)(request->messageId.getCString())));
3012 _forwardIndToHandler(subscriptions[i],
3014 formattedIndication,
3016 request->operationContext);
3018 matchedSubscriptions.append(subscriptions[i]);
3019 matchedSubscriptionsKeys.append(subscriptionKeys[i]);
3023 catch (Exception& e)
3025 PEG_TRACE ((TRC_DISCARDED_DATA, Tracer::LEVEL1,
3026 "Exception caught in attempting to process indication "
3027 "for the subscription %s: %s",
3028 (const char *) subscriptions[i].getPath ().toString().
3030 (const char *) e.getMessage ().getCString()));
3032 catch (exception& e)
3034 PEG_TRACE ((TRC_DISCARDED_DATA, Tracer::LEVEL1,
3035 "Exception caught in attempting to process indication "
3036 "for the subscription %s: %s",
3037 (const char *) subscriptions[i].getPath ().toString().
3038 getCString(), e.what()));
3042 PEG_TRACE ((TRC_DISCARDED_DATA, Tracer::LEVEL1,
3043 "Unknown exception caught in attempting to process "
3044 "indication for the subscription %s",
3045 (const char *) subscriptions[i].getPath ().toString ().
3051 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
3052 _providerIndicationCountTable.incrementEntry(
3053 request->provider, matchedSubscriptions.size() == 0);
3054 _subscriptionTable->updateMatchedIndicationCounts(
3055 request->provider, matchedSubscriptionsKeys);
3059 // Log subscriptions info to a trace message
3061 if (matchedSubscriptions.size() == 0)
3063 PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL1,
3064 "No matching subscriptions found for %s Indication %s",
3065 (const char*)(indication.getClassName().getString().
3067 (const char*)(request->messageId.getCString())));
3071 PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL4,
3072 "%d subscriptions found for %s Indication %s in namespace %s",
3073 matchedSubscriptions.size(),
3074 (const char*)(indication.getClassName().getString().
3076 (const char*)(request->messageId.getCString()),
3077 (const char*)(request->nameSpace.getString().getCString())));
3080 catch (Exception& e)
3082 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
3083 "Exception caught while processing indication: %s. "
3084 "Indication may be lost.",
3085 (const char*)e.getMessage().getCString()));
3091 PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
3092 "Exception caught while processing indication. Indication may be "
3098 _enqueueResponse(request, request->buildResponse());
3100 #ifdef PEGASUS_INDICATION_PERFINST
3103 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
3104 "%s: %.3f seconds", "Process Indication", stopWatch.getElapsed()));
3111 void IndicationService::_handleIndicationCallBack (
3112 AsyncOpNode * operation,
3113 MessageQueue * destination,
3114 void * userParameter)
3116 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
3117 "IndicationService::_handleIndicationCallBack");
3119 IndicationService * service =
3120 static_cast<IndicationService *> (destination);
3121 CIMInstance * subscription =
3122 reinterpret_cast<CIMInstance *> (userParameter);
3123 AsyncReply * asyncReply =
3124 static_cast<AsyncReply *>(operation->removeResponse());
3125 CIMHandleIndicationResponseMessage* handlerResponse =
3126 reinterpret_cast<CIMHandleIndicationResponseMessage *>(
3127 (static_cast<AsyncLegacyOperationResult *>(
3128 asyncReply))->get_result());
3129 PEGASUS_ASSERT (handlerResponse != 0);
3131 if (handlerResponse->cimException.getCode () != CIM_ERR_SUCCESS)
3133 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
3134 "Sending Indication and HandlerService returns CIMException: %s",
3136 handlerResponse->cimException.getMessage().getCString()));
3139 // ATTN-CAKG-P1-20020326: Implement subscription's OnFatalErrorPolicy
3141 //service->_subscriptionRepository->reconcileFatalError (*subscription);
3144 delete handlerResponse;
3146 service->return_op (operation);
3151 void IndicationService::_handleNotifyProviderRegistrationRequest
3152 (const Message* message)
3154 PEG_METHOD_ENTER ( TRC_INDICATION_SERVICE,
3155 "IndicationService::_handleNotifyProviderRegistrationRequest");
3157 CIMNotifyProviderRegistrationRequestMessage* request =
3158 (CIMNotifyProviderRegistrationRequestMessage*) message;
3160 ProviderIdContainer pidc = request->operationContext.get
3161 (ProviderIdContainer::NAME);
3162 CIMInstance provider = pidc.getProvider();
3163 CIMInstance providerModule = pidc.getModule();
3164 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
3165 Boolean isRemoteNameSpace = pidc.isRemoteNameSpace();
3166 String remoteInfo = pidc.getRemoteInfo();
3169 CIMName className = request->className;
3170 Array<CIMNamespaceName> newNameSpaces = request->newNamespaces;
3171 Array<CIMNamespaceName> oldNameSpaces = request->oldNamespaces;
3172 CIMPropertyList newPropertyNames = request->newPropertyNames;
3173 CIMPropertyList oldPropertyNames = request->oldPropertyNames;
3175 Array<CIMInstance> newSubscriptions;
3176 Array<CIMInstance> formerSubscriptions;
3177 Array<ProviderClassList> indicationProviders;
3178 ProviderClassList indicationProvider;
3180 newSubscriptions.clear ();
3181 formerSubscriptions.clear ();
3183 switch (request->operation)
3188 // Get matching subscriptions
3190 newSubscriptions = _getMatchingSubscriptions (className,
3191 newNameSpaces, newPropertyNames);
3199 // Get matching subscriptions
3201 formerSubscriptions = _getMatchingSubscriptions (className,
3202 oldNameSpaces, oldPropertyNames);
3204 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
3205 _providerIndicationCountTable.removeEntry(provider);
3214 // Get lists of affected subscriptions
3216 _getModifiedSubscriptions (className, newNameSpaces, oldNameSpaces,
3217 newPropertyNames, oldPropertyNames,
3218 newSubscriptions, formerSubscriptions);
3224 // Error condition: operation not supported
3227 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
3232 // Construct provider class list from input provider and class name
3234 indicationProvider.provider = provider;
3235 indicationProvider.providerModule = providerModule;
3236 indicationProvider.classList.append (className);
3237 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
3238 indicationProvider.isRemoteNameSpace = isRemoteNameSpace;
3239 indicationProvider.remoteInfo = remoteInfo;
3241 indicationProviders.append (indicationProvider);
3243 if (newSubscriptions.size () > 0)
3245 CIMPropertyList requiredProperties;
3248 String queryLanguage;
3251 // Send Create or Modify request for each subscription that can newly
3254 for (Uint32 i = 0; i < newSubscriptions.size (); i++)
3256 CIMNamespaceName sourceNameSpace;
3257 Array<CIMName> indicationSubclasses;
3258 _getCreateParams (newSubscriptions[i], indicationSubclasses,
3259 requiredProperties, sourceNameSpace, condition,
3260 query, queryLanguage);
3263 // NOTE: These Create or Modify requests are not associated with a
3264 // user request, so there is no associated authType or userName
3265 // The Creator from the subscription instance is used for
3266 // userName, and authType is not set
3268 // NOTE: the subscriptions in the newSubscriptions list came from
3269 // the IndicationService's internal hash tables, and thus
3270 // each instance is known to have a valid Creator property
3272 CIMInstance instance = newSubscriptions[i];
3273 String creator = instance.getProperty (instance.findProperty
3274 (PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue ().toString ();
3277 AcceptLanguageList acceptLangs;
3278 Uint32 propIndex = instance.findProperty
3279 (PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
3280 if (propIndex != PEG_NOT_FOUND)
3282 String acceptLangsString;
3283 instance.getProperty(propIndex).getValue().get(
3285 if (acceptLangsString.size())
3287 acceptLangs = LanguageParser::parseAcceptLanguageHeader(
3291 ContentLanguageList contentLangs;
3292 propIndex = instance.findProperty
3293 (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
3294 if (propIndex != PEG_NOT_FOUND)
3296 String contentLangsString;
3297 instance.getProperty(propIndex).getValue().get(
3298 contentLangsString);
3299 if (contentLangsString.size())
3301 contentLangs = LanguageParser::parseContentLanguageHeader(
3302 contentLangsString);
3308 // Look up the subscription in the active subscriptions table
3310 ActiveSubscriptionsTableEntry tableValue;
3311 if (_subscriptionTable->getSubscriptionEntry
3312 (newSubscriptions[i].getPath (), tableValue))
3315 // If the provider is already in the subscription's list,
3316 // send a Modify request, otherwise send a Create request
3318 Uint32 providerIndex = _subscriptionTable->providerInList
3319 (provider, tableValue);
3320 if (providerIndex != PEG_NOT_FOUND)
3323 // Send Modify requests
3325 _sendWaitModifyRequests (indicationProviders,
3327 requiredProperties, condition, query, queryLanguage,
3328 newSubscriptions[i],
3336 // Send Create requests
3338 Array<ProviderClassList> acceptedProviders;
3339 acceptedProviders = _sendWaitCreateRequests
3340 (indicationProviders,
3341 sourceNameSpace, requiredProperties, condition,
3342 query, queryLanguage, newSubscriptions[i],
3347 if (acceptedProviders.size () > 0)
3350 // Provider is not yet in the list for this
3351 // subscription; add provider to the list
3353 _subscriptionTable->updateProviders
3354 (instance.getPath (), indicationProvider, true);
3361 // Subscription not found in Active Subscriptions table
3367 // NOTE: When a provider that was previously not serving a subscription
3368 // now serves the subscription due to a provider registration change,
3369 // a log message is sent, even if there were previously other providers
3370 // serving the subscription
3374 // Log a message for each subscription
3376 CIMClass providerClass = _subscriptionRepository->getClass
3377 (PEGASUS_NAMESPACENAME_INTEROP, PEGASUS_CLASSNAME_PROVIDER,
3378 true, true, false, CIMPropertyList ());
3379 CIMInstance providerCopy = provider.clone ();
3380 CIMObjectPath path = providerCopy.buildPath (providerClass);
3381 providerCopy.setPath (path);
3382 String logString1 = getProviderLogString (providerCopy);
3384 for (Uint32 j = 0; j < newSubscriptions.size (); j++)
3387 // Get Provider Name, Subscription Filter Name and Handler Name
3389 String logString2 = _getSubscriptionLogString
3390 (newSubscriptions[j]);
3392 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
3395 _MSG_PROVIDER_NOW_SERVING_KEY,
3396 _MSG_PROVIDER_NOW_SERVING, logString1, logString2,
3397 newSubscriptions[j].getPath().getNameSpace().getString()));
3401 if (formerSubscriptions.size () > 0)
3403 CIMPropertyList requiredProperties;
3406 String queryLanguage;
3409 // Send Delete or Modify request for each subscription that can no
3410 // longer be supported
3412 for (Uint32 i = 0; i < formerSubscriptions.size (); i++)
3415 // NOTE: These Delete or Modify requests are not associated with a
3416 // user request, so there is no associated authType or userName
3417 // The Creator from the subscription instance is used for userName,
3418 // and authType is not set
3420 // NOTE: the subscriptions in the formerSubscriptions list came
3421 // from the IndicationService's internal hash tables, and thus
3422 // each instance is known to have a valid Creator property
3424 CIMInstance instance = formerSubscriptions[i];
3425 String creator = instance.getProperty (instance.findProperty
3426 (PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue ().toString ();
3427 AcceptLanguageList acceptLangs;
3428 Uint32 propIndex = instance.findProperty
3429 (PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
3430 if (propIndex != PEG_NOT_FOUND)
3432 String acceptLangsString;
3433 instance.getProperty(propIndex).getValue().get(
3435 if (acceptLangsString.size())
3437 acceptLangs = LanguageParser::parseAcceptLanguageHeader(
3441 ContentLanguageList contentLangs;
3442 propIndex = instance.findProperty
3443 (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
3444 if (propIndex != PEG_NOT_FOUND)
3446 String contentLangsString;
3447 instance.getProperty(propIndex).getValue().get(
3448 contentLangsString);
3449 if (contentLangsString.size())
3451 contentLangs = LanguageParser::parseContentLanguageHeader(
3452 contentLangsString);
3457 // Look up the subscription in the active subscriptions table
3458 // If class list contains only the class name from the current
3459 // operation, send a Delete request
3460 // Otherwise, send a Modify request
3462 ActiveSubscriptionsTableEntry tableValue;
3463 if (_subscriptionTable->getSubscriptionEntry
3464 (formerSubscriptions[i].getPath (), tableValue))
3466 Uint32 providerIndex = _subscriptionTable->providerInList
3467 (provider, tableValue);
3468 if (providerIndex != PEG_NOT_FOUND)
3470 CIMNamespaceName sourceNameSpace;
3471 Array<CIMName> indicationSubclasses;
3472 _getCreateParams (formerSubscriptions[i],
3473 indicationSubclasses, requiredProperties,
3474 sourceNameSpace, condition, query, queryLanguage);
3477 // If class list contains only the class name from the
3478 // current delete, send a Delete request
3480 if ((tableValue.providers[providerIndex].classList.size()
3482 (tableValue.providers[providerIndex].classList[0].equal(
3485 _sendWaitDeleteRequests (indicationProviders,
3487 formerSubscriptions[i],
3495 _subscriptionTable->updateProviders
3496 (instance.getPath (), indicationProvider, false);
3500 // Otherwise, send a Modify request
3504 Uint32 classIndex = _subscriptionTable->classInList
3505 (className, tableValue.providers[providerIndex]);
3506 if (classIndex != PEG_NOT_FOUND)
3509 // Send Modify requests
3511 _sendWaitModifyRequests (indicationProviders,
3513 requiredProperties, condition,
3514 query, queryLanguage,
3515 formerSubscriptions[i],
3522 PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL1,
3523 "Class %s not found in tableValue.providers",
3524 (const char*)className.getString().getCString()
3532 // The subscription was not served by the provider
3539 // Subscription not found in Active Subscriptions table
3546 // Create NoProviderAlertIndication instance
3547 // ATTN: NoProviderAlertIndication must be defined
3549 CIMInstance indicationInstance = _createAlertInstance
3550 (_CLASS_NO_PROVIDER_ALERT, formerSubscriptions);
3553 // Send NoProviderAlertIndication to each unique handler instance
3555 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
3556 "Sending NoProvider Alert for %u subscriptions",
3557 formerSubscriptions.size ()));
3558 _sendAlerts (formerSubscriptions, indicationInstance);
3561 // NOTE: When a provider that was previously serving a subscription
3562 // no longer serves the subscription due to a provider registration
3563 // change, a log message is sent, even if there are still other
3564 // providers serving the subscription
3568 // Log a message for each subscription
3570 CIMClass providerClass = _subscriptionRepository->getClass
3571 (PEGASUS_NAMESPACENAME_INTEROP, PEGASUS_CLASSNAME_PROVIDER,
3572 true, true, false, CIMPropertyList ());
3573 CIMInstance providerCopy = provider.clone ();
3574 CIMObjectPath path = providerCopy.buildPath (providerClass);
3575 providerCopy.setPath (path);
3576 String logString1 = getProviderLogString (providerCopy);
3578 for (Uint32 j = 0; j < formerSubscriptions.size (); j++)
3581 // Get Provider Name, Subscription Filter Name and Handler Name
3583 String logString2 = _getSubscriptionLogString
3584 (formerSubscriptions[j]);
3586 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
3589 _MSG_PROVIDER_NO_LONGER_SERVING_KEY,
3590 _MSG_PROVIDER_NO_LONGER_SERVING, logString1, logString2,
3591 formerSubscriptions[j].getPath().getNameSpace().
3599 CIMResponseMessage * response = request->buildResponse ();
3600 _enqueueResponse (request, response);
3605 void IndicationService::_handleNotifyProviderTerminationRequest
3606 (const Message * message)
3608 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
3609 "IndicationService::_handleNotifyProviderTermination");
3611 Array<CIMInstance> providerSubscriptions;
3612 CIMInstance indicationInstance;
3614 CIMNotifyProviderTerminationRequestMessage* request =
3615 (CIMNotifyProviderTerminationRequestMessage*) message;
3617 Array<CIMInstance> providers = request->providers;
3619 for (Uint32 i = 0; i < providers.size (); i++)
3621 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
3622 _providerIndicationCountTable.removeEntry(providers[i]);
3626 // Get list of affected subscriptions
3628 // _subscriptionTable->reflectProviderDisable also updates the
3629 // Active Subscriptions hash table, and implements each subscription's
3630 // On Fatal Error policy, if necessary
3632 providerSubscriptions.clear();
3633 providerSubscriptions = _subscriptionTable->reflectProviderDisable(
3636 if (providerSubscriptions.size() > 0)
3639 // NOTE: When a provider that was previously serving a subscription
3640 // no longer serves the subscription due to a provider termination,
3641 // an alert is always sent, even if there are still other providers
3642 // serving the subscription
3647 // Create ProviderTerminatedAlertIndication instance
3648 // ATTN: ProviderTerminatedAlertIndication must be defined
3650 indicationInstance = _createAlertInstance
3651 (_CLASS_PROVIDER_TERMINATED_ALERT, providerSubscriptions);
3654 // Send ProviderTerminatedAlertIndication to each unique handler
3657 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
3658 "Sending ProviderDisabled Alert for %u subscriptions",
3659 providerSubscriptions.size ()));
3660 _sendAlerts (providerSubscriptions, indicationInstance);
3663 // Log a message for each subscription
3665 CIMClass providerClass = _subscriptionRepository->getClass(
3666 PEGASUS_NAMESPACENAME_INTEROP, PEGASUS_CLASSNAME_PROVIDER,
3667 true, true, false, CIMPropertyList());
3668 CIMInstance providerCopy = providers[i].clone();
3669 CIMObjectPath path = providerCopy.buildPath (providerClass);
3670 providerCopy.setPath (path);
3671 for (Uint32 j = 0; j < providerSubscriptions.size (); j++)
3674 // Get Provider Name, Subscription Filter Name and Handler Name
3676 String logString1 = getProviderLogString (providerCopy);
3677 String logString2 = _getSubscriptionLogString
3678 (providerSubscriptions[j]);
3680 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER,
3683 _MSG_PROVIDER_NO_LONGER_SERVING_KEY,
3684 _MSG_PROVIDER_NO_LONGER_SERVING, logString1, logString2,
3685 providerSubscriptions[j].getPath().getNameSpace().
3691 CIMResponseMessage * response = request->buildResponse ();
3692 _enqueueResponse (request, response);
3697 void IndicationService::_handleNotifyProviderEnableRequest
3698 (const Message * message)
3700 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
3701 "IndicationService::_handleNotifyProviderEnableRequest");
3703 CIMNotifyProviderEnableRequestMessage * request =
3704 (CIMNotifyProviderEnableRequestMessage *) message;
3705 ProviderIdContainer pidc = request->operationContext.get
3706 (ProviderIdContainer::NAME);
3707 CIMInstance providerModule = pidc.getModule();
3708 CIMInstance provider = pidc.getProvider();
3709 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
3710 Boolean isRemoteNameSpace = pidc.isRemoteNameSpace();
3711 String remoteInfo = pidc.getRemoteInfo();
3713 Array<CIMInstance> capabilities = request->capInstances;
3715 CIMException cimException;
3716 Array<CIMInstance> subscriptions;
3717 Array<ProviderClassList> indicationProviders;
3720 // Get class name, namespace names, and property list
3721 // from each capability instance
3723 Uint32 numCapabilities = capabilities.size ();
3724 for (Uint32 i = 0; i < numCapabilities; i++)
3727 Array<CIMNamespaceName> namespaceNames;
3728 CIMPropertyList propertyList;
3729 Array<CIMInstance> currentSubscriptions;
3734 capabilities[i].getProperty (capabilities[i].findProperty
3735 (_PROPERTY_CLASSNAME)).getValue ().get (cName);
3736 className = CIMName (cName);
3738 Array<String> nsNames;
3739 capabilities[i].getProperty (capabilities[i].findProperty
3740 (_PROPERTY_NAMESPACES)).getValue ().get (nsNames);
3741 for (Uint32 j = 0; j < nsNames.size (); j++)
3743 namespaceNames.append (CIMNamespaceName (nsNames[j]));
3746 Array<String> pNames;
3747 Array<CIMName> propertyNames;
3748 Uint32 propertiesIndex = capabilities[i].findProperty
3749 (_PROPERTY_SUPPORTEDPROPERTIES);
3750 if (propertiesIndex != PEG_NOT_FOUND)
3752 CIMValue propertiesValue = capabilities[i].getProperty
3753 (propertiesIndex).getValue ();
3755 // If the property list is not null, set the property names
3757 if (!propertiesValue.isNull ())
3759 propertiesValue.get (pNames);
3760 for (Uint32 k = 0; k < pNames.size (); k++)
3762 propertyNames.append (CIMName (pNames[k]));
3764 propertyList.set (propertyNames);
3768 catch (Exception& exception)
3771 // Error getting information from Capabilities instance
3773 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
3774 "Exception caught in handling provider enable notification: %s",
3775 (const char*)exception.getMessage().getCString()));
3777 cimException = CIMException(CIM_ERR_FAILED, exception.getMessage());
3782 PEG_TRACE_CSTRING (TRC_INDICATION_SERVICE, Tracer::LEVEL1,
3783 "Error in handling provider enable notification");
3785 cimException = PEGASUS_CIM_EXCEPTION_L(
3788 "IndicationService.IndicationService.UNKNOWN_ERROR",
3794 // Get matching subscriptions
3796 currentSubscriptions = _getMatchingSubscriptions
3797 (className, namespaceNames, propertyList);
3799 for (Uint32 c = 0; c < currentSubscriptions.size (); c++)
3801 Boolean inList = false;
3803 for (Uint32 m = 0; m < subscriptions.size (); m++)
3806 // If the current subscription is already in the list of
3807 // matching subscriptions, add the current class to the
3808 // indication provider class list for the subscription
3810 if (currentSubscriptions[c].identical (subscriptions[m]))
3813 indicationProviders[m].classList.append (className);
3821 // If the current subscription is not already in the list of
3822 // matching subscriptions, add it to the list and add the
3823 // indication provider class list for the subscription
3825 subscriptions.append (currentSubscriptions[c]);
3826 ProviderClassList indicationProvider;
3827 indicationProvider.provider = provider;
3828 indicationProvider.providerModule = providerModule;
3829 indicationProvider.classList.append (className);
3830 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
3831 indicationProvider.isRemoteNameSpace = isRemoteNameSpace;
3832 indicationProvider.remoteInfo = remoteInfo;
3834 indicationProviders.append (indicationProvider);
3837 } // for each capability instance
3839 if (subscriptions.size () > 0)
3841 CIMPropertyList requiredProperties;
3844 String queryLanguage;
3847 // Get Provider Name
3849 String logString1 = getProviderLogString (provider);
3851 for (Uint32 s = 0; s < subscriptions.size (); s++)
3853 CIMNamespaceName sourceNameSpace;
3854 Array<CIMName> indicationSubclasses;
3855 CIMInstance instance = subscriptions[s];
3856 _getCreateParams (instance, indicationSubclasses,
3857 requiredProperties, sourceNameSpace, condition, query,
3861 // NOTE: These Create requests are not associated with a
3862 // user request, so there is no associated authType or userName
3863 // The Creator from the subscription instance is used for
3864 // userName, and authType is not set
3866 // NOTE: the subscriptions in the subscriptions list came from
3867 // the IndicationService's internal hash tables, and thus
3868 // each instance is known to have a valid Creator property
3870 String creator = instance.getProperty (instance.findProperty
3871 (PEGASUS_PROPERTYNAME_INDSUB_CREATOR)).getValue
3874 AcceptLanguageList acceptLangs;
3875 Uint32 propIndex = instance.findProperty
3876 (PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
3877 if (propIndex != PEG_NOT_FOUND)
3879 String acceptLangsString;
3880 instance.getProperty(propIndex).getValue().get(
3882 if (acceptLangsString.size())
3884 acceptLangs = LanguageParser::parseAcceptLanguageHeader(
3888 ContentLanguageList contentLangs;
3889 propIndex = instance.findProperty
3890 (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
3891 if (propIndex != PEG_NOT_FOUND)
3893 String contentLangsString;
3894 instance.getProperty(propIndex).getValue().get(
3895 contentLangsString);
3896 if (contentLangsString.size())
3898 contentLangs = LanguageParser::parseContentLanguageHeader(
3899 contentLangsString);
3904 // Send Create requests
3906 Array<ProviderClassList> currentIndicationProviders;
3907 currentIndicationProviders.append (indicationProviders[s]);
3908 Array<ProviderClassList> acceptedProviders;
3909 acceptedProviders = _sendWaitCreateRequests
3910 (currentIndicationProviders,
3911 sourceNameSpace, requiredProperties, condition,
3912 query, queryLanguage, instance,
3917 if (acceptedProviders.size () > 0)
3920 // Get Subscription entry from Active Subscriptions table
3922 ActiveSubscriptionsTableEntry tableValue;
3923 if (_subscriptionTable->getSubscriptionEntry
3924 (instance.getPath (), tableValue))
3927 // Look for the provider in the subscription's list
3929 Uint32 providerIndex =
3930 _subscriptionTable->providerInList
3931 (indicationProviders[s].provider, tableValue);
3932 if (providerIndex != PEG_NOT_FOUND)
3935 // Provider is already in the list for this
3936 // subscription; add class to provider class list
3939 cn < indicationProviders[s].classList.size ();
3942 _subscriptionTable->updateClasses
3943 (instance.getPath (),
3944 indicationProviders[s].provider,
3945 indicationProviders[s].classList[cn]);
3951 // Provider is not yet in the list for this
3952 // subscription; add provider to the list
3954 _subscriptionTable->updateProviders
3955 (instance.getPath (), indicationProviders[s],
3959 // NOTE: When a provider that was previously not
3960 // serving a subscription now serves the
3961 // subscription due to a provider being enabled, a
3962 // log message is sent, even if there were
3963 // previously other providers serving the
3968 // Get Subscription Filter Name and Handler Name
3970 String logString2 = _getSubscriptionLogString
3974 // Log a message for each subscription
3976 Logger::put_l(Logger::STANDARD_LOG,
3977 System::CIMSERVER, Logger::WARNING,
3979 _MSG_PROVIDER_NOW_SERVING_KEY,
3980 _MSG_PROVIDER_NOW_SERVING,
3981 logString1, logString2,
3982 subscriptions[s].getPath().getNameSpace().
3986 } // if any provider accepted the create subscription request
3987 } // for each matching subscription
3988 } // if any matching subscriptions
3993 CIMResponseMessage * response = request->buildResponse ();
3994 response->cimException = cimException;
3995 _enqueueResponse (request, response);
4000 void IndicationService::_handleNotifyProviderFailRequest
4003 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
4004 "IndicationService::_handleNotifyProviderFailRequest");
4006 CIMNotifyProviderFailRequestMessage* request =
4007 dynamic_cast<CIMNotifyProviderFailRequestMessage*>(message);
4008 PEGASUS_ASSERT(request != 0);
4010 String moduleName = request->moduleName;
4011 String userName = request->userName;
4014 // Determine providers in module that were serving active subscriptions
4015 // and update the Active Subscriptions Table
4017 Array<ActiveSubscriptionsTableEntry> providerModuleSubscriptions =
4018 _subscriptionTable->reflectProviderModuleFailure
4019 (moduleName, userName, _authenticationEnabled);
4021 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
4022 _providerIndicationCountTable.removeModuleEntries(moduleName);
4026 // FUTURE: Attempt to recreate the subscription state
4032 CIMResponseMessage * response = request->buildResponse ();
4033 CIMNotifyProviderFailResponseMessage * failResponse =
4034 (CIMNotifyProviderFailResponseMessage *) response;
4035 failResponse->numSubscriptionsAffected =
4036 providerModuleSubscriptions.size ();
4037 _enqueueResponse (request, response);
4040 Boolean IndicationService::_canCreate (
4041 CIMInstance& instance,
4042 const CIMNamespaceName& nameSpace)
4044 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "IndicationService::_canCreate");
4046 // REVIEW: Derived classes of CIM_IndicationSubscription not
4047 // handled. It is reasonable for a user to derive from this
4048 // class and add extra properties.
4050 // REVIEW: how does the provider manager know to forward
4051 // requests to this service? Is it by class name? If so,
4052 // shouldn't the provider use an is-a operator on the new
4056 // Validate that all properties in the instance are supported properties,
4057 // and reject create if an unknown, unsupported property is found
4059 _checkSupportedProperties (instance);
4062 // Check all required properties exist
4063 // For a property that has a default value, if it does not exist or is
4064 // null, add or set property with default value
4065 // For a property that has a specified set of valid values, validate
4067 if ((instance.getClassName ().equal (PEGASUS_CLASSNAME_INDSUBSCRIPTION)) ||
4068 (instance.getClassName ().equal
4069 (PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION)))
4072 // Filter and Handler are key properties for Subscription
4073 // No other properties are required
4075 _checkRequiredProperty(
4077 PEGASUS_PROPERTYNAME_FILTER,
4080 _checkRequiredProperty(
4082 PEGASUS_PROPERTYNAME_HANDLER,
4087 // Get filter and handler property values
4089 CIMProperty filterProperty = instance.getProperty
4090 (instance.findProperty (PEGASUS_PROPERTYNAME_FILTER));
4091 CIMValue filterValue = filterProperty.getValue ();
4092 CIMObjectPath filterPath;
4093 filterValue.get (filterPath);
4095 CIMProperty handlerProperty = instance.getProperty
4096 (instance.findProperty (PEGASUS_PROPERTYNAME_HANDLER));
4097 CIMValue handlerValue = handlerProperty.getValue ();
4098 CIMObjectPath handlerPath;
4099 handlerValue.get (handlerPath);
4102 // Currently, the Indication Service requires that a Subscription
4103 // instance and the Filter and Handler instances to which it refers
4104 // all be created on the same Host.
4105 // Developers are recommended NOT to include Host in the
4106 // Filter or Handler reference property values.
4110 // If Host is included in a Filter or Handler reference property
4111 // value, attempt to validate that it is correct.
4112 // If Host cannot be validated, reject the create operation.
4114 CIMObjectPath origFilterPath = filterPath;
4115 if (filterPath.getHost () != String::EMPTY)
4117 if (!System::isLocalHost (filterPath.getHost()))
4120 // Reject subscription creation
4123 throw PEGASUS_CIM_EXCEPTION_L(
4124 CIM_ERR_INVALID_PARAMETER,
4126 _MSG_INVALID_VALUE_FOR_PROPERTY_KEY,
4127 _MSG_INVALID_VALUE_FOR_PROPERTY,
4128 origFilterPath.toString(),
4129 PEGASUS_PROPERTYNAME_FILTER.getString()));
4133 CIMObjectPath origHandlerPath = handlerPath;
4134 if (handlerPath.getHost () != String::EMPTY)
4136 if (!System::isLocalHost (handlerPath.getHost()))
4139 // Reject subscription creation
4142 throw PEGASUS_CIM_EXCEPTION_L(
4143 CIM_ERR_INVALID_PARAMETER,
4145 _MSG_INVALID_VALUE_FOR_PROPERTY_KEY,
4146 _MSG_INVALID_VALUE_FOR_PROPERTY,
4147 origHandlerPath.toString(),
4148 PEGASUS_PROPERTYNAME_HANDLER.getString()));
4153 // Get Filter namespace - if not set in Filter reference property
4154 // value, namespace is the namespace of the subscription
4156 CIMNamespaceName filterNS = filterPath.getNameSpace ();
4157 if (filterNS.isNull ())
4159 filterNS = nameSpace;
4163 // Get Handler namespace - if not set in Handler reference property
4164 // value, namespace is the namespace of the subscription
4166 CIMNamespaceName handlerNS = handlerPath.getNameSpace();
4167 if (handlerNS.isNull())
4169 handlerNS = nameSpace;
4173 // Validate the Filter and Handler reference properties
4174 // Ensure Filter and Handler instances can be retrieved from the
4177 CIMInstance filterInstance =
4178 _subscriptionRepository->getInstance(filterNS, filterPath,
4179 false, false, CIMPropertyList());
4181 CIMInstance handlerInstance =
4182 _subscriptionRepository->getInstance(handlerNS, handlerPath,
4183 false, false, CIMPropertyList());
4186 // Set the key bindings in the subscription instance
4188 Array<CIMKeyBinding> kb;
4189 kb.append(CIMKeyBinding(PEGASUS_PROPERTYNAME_FILTER, filterValue));
4190 kb.append(CIMKeyBinding(PEGASUS_PROPERTYNAME_HANDLER, handlerValue));
4192 CIMObjectPath instanceRef = instance.getPath ();
4193 instanceRef.setKeyBindings(kb);
4194 instanceRef.setNameSpace(nameSpace);
4195 instance.setPath(instanceRef);
4198 // Subscription State, Repeat Notification Policy, and On Fatal Error
4199 // Policy properties each has a default value, a corresponding
4200 // Other___ property, and a set of valid values
4202 _checkPropertyWithOther(
4204 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE,
4205 _PROPERTY_OTHERSTATE,
4206 (Uint16) STATE_ENABLED,
4207 (Uint16) STATE_OTHER,
4211 _checkPropertyWithOther(
4213 _PROPERTY_REPEATNOTIFICATIONPOLICY,
4214 _PROPERTY_OTHERREPEATNOTIFICATIONPOLICY,
4215 (Uint16) _POLICY_NONE,
4216 (Uint16) _POLICY_OTHER,
4217 _validRepeatPolicies,
4218 _supportedRepeatPolicies);
4220 _checkPropertyWithOther(
4222 _PROPERTY_ONFATALERRORPOLICY,
4223 _PROPERTY_OTHERONFATALERRORPOLICY,
4224 (Uint16) _ERRORPOLICY_IGNORE,
4225 (Uint16) _ERRORPOLICY_OTHER,
4226 _validErrorPolicies,
4227 _supportedErrorPolicies);
4230 // For each remaining property, verify that if the property exists in
4231 // the instance it is of the correct type
4233 _checkProperty(instance, _PROPERTY_FAILURETRIGGERTIMEINTERVAL,
4235 _checkProperty(instance, _PROPERTY_LASTCHANGE, CIMTYPE_DATETIME);
4236 _checkProperty(instance, _PROPERTY_DURATION, CIMTYPE_UINT64);
4237 _checkProperty(instance, _PROPERTY_STARTTIME, CIMTYPE_DATETIME);
4238 _checkProperty(instance, _PROPERTY_TIMEREMAINING, CIMTYPE_UINT64);
4239 _checkProperty(instance, _PROPERTY_REPEATNOTIFICATIONINTERVAL,
4241 _checkProperty(instance, _PROPERTY_REPEATNOTIFICATIONGAP,
4243 _checkProperty(instance, _PROPERTY_REPEATNOTIFICATIONCOUNT,
4246 if (instance.getClassName().equal(
4247 PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))
4249 Array<String> textFormatParams;
4250 CIMValue textFormatParamsValue;
4251 CIMClass indicationClass;
4253 // get TextFormatParameters from instance
4254 Uint32 textFormatParamsPos =
4255 instance.findProperty(_PROPERTY_TEXTFORMATPARAMETERS);
4257 if (textFormatParamsPos != PEG_NOT_FOUND)
4259 textFormatParamsValue = instance.getProperty(
4260 textFormatParamsPos).getValue();
4262 if (!textFormatParamsValue.isNull())
4264 textFormatParamsValue.get(textFormatParams);
4268 // get indication class
4269 indicationClass = _getIndicationClass (instance);
4271 String textFormatStr;
4272 CIMValue textFormatValue;
4274 // get TextFormatStr from instance
4275 Uint32 textFormatPos =
4276 instance.findProperty(_PROPERTY_TEXTFORMAT);
4278 if (textFormatPos != PEG_NOT_FOUND)
4280 textFormatValue = instance.getProperty(
4281 textFormatPos).getValue();
4283 #if defined(PEGASUS_ENABLE_SYSTEM_LOG_HANDLER) || \
4284 defined(PEGASUS_ENABLE_EMAIL_HANDLER)
4285 // if the value of textFormat is not null
4286 if (!(textFormatValue.isNull()) &&
4287 (textFormatValue.getType() == CIMTYPE_STRING) &&
4288 !(textFormatValue.isArray()))
4290 textFormatValue.get(textFormatStr);
4292 // Validates the syntax and the provided type for the
4293 // property TextFormat
4294 IndicationFormatter::validateTextFormat (
4295 textFormatStr, indicationClass,
4298 // Validates the property names in TextFormatParameters
4299 CIMNamespaceName sourceNameSpace;
4301 String queryLanguage;
4303 CIMPropertyList propertyList;
4305 // Get filter properties
4306 _subscriptionRepository->getFilterProperties (instance,
4307 query, sourceNameSpace, queryLanguage, filterName);
4309 // Build the query expression from the filter query
4310 QueryExpression queryExpression = _getQueryExpression(query,
4311 queryLanguage, sourceNameSpace);
4313 // the select clause projection
4314 propertyList = queryExpression.getPropertyList();
4316 IndicationFormatter::validateTextFormatParameters(
4317 propertyList, indicationClass, textFormatParams);
4323 else // Filter or Handler
4326 // Name, CreationClassName, SystemName, and SystemCreationClassName
4327 // are key properties for Filter and Handler
4329 // If others do not exist, add and set to default
4330 // If they exist but are NULL, set value to the default
4331 // If they exist and are not NULL, validate the value
4334 if (instance.getClassName ().equal (PEGASUS_CLASSNAME_INDFILTER))
4336 _checkRequiredProperty(
4338 PEGASUS_PROPERTYNAME_NAME,
4344 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
4345 // Name is an optional property for Handler. If Name key property
4346 // not found then set the Name value using GUID.
4347 _checkPropertyWithGuid(
4349 PEGASUS_PROPERTYNAME_NAME);
4351 _checkRequiredProperty(
4353 PEGASUS_PROPERTYNAME_NAME,
4359 _initOrValidateStringProperty(
4361 PEGASUS_PROPERTYNAME_CREATIONCLASSNAME,
4362 instance.getClassName().getString());
4364 _initOrValidateStringProperty(
4366 _PROPERTY_SYSTEMNAME,
4367 System::getFullyQualifiedHostName());
4369 _initOrValidateStringProperty(
4371 _PROPERTY_SYSTEMCREATIONCLASSNAME,
4372 System::getSystemCreationClassName());
4374 if (instance.getClassName ().equal (PEGASUS_CLASSNAME_INDFILTER))
4377 // Query and QueryLanguage properties are required for Filter
4379 _checkRequiredProperty(
4381 PEGASUS_PROPERTYNAME_QUERY,
4384 _checkRequiredProperty(
4386 PEGASUS_PROPERTYNAME_QUERYLANGUAGE,
4391 // Validate the query language is supported
4393 String queryLanguage;
4394 instance.getProperty(
4395 instance.findProperty(PEGASUS_PROPERTYNAME_QUERYLANGUAGE)).
4396 getValue().get(queryLanguage);
4398 #ifndef PEGASUS_ENABLE_CQL
4399 // Special code to block CQL, if CQL is disabled
4400 if ((queryLanguage == "CIM:CQL") || (queryLanguage == "DMTF:CQL"))
4402 // CQL is not allowed in this case
4404 throw PEGASUS_CIM_EXCEPTION(
4405 CIM_ERR_NOT_SUPPORTED, queryLanguage);
4410 // Default value for Source Namespace is the namespace of the
4411 // Filter registration
4413 CIMNamespaceName sourceNameSpace = CIMNamespaceName(
4414 _checkPropertyWithDefault(
4416 _PROPERTY_SOURCENAMESPACE,
4417 nameSpace.getString()));
4420 // Validate the query and indication class name
4421 // An exception is thrown if the query is invalid or the class
4422 // is not an indication class
4424 String filterQuery = instance.getProperty (instance.findProperty
4425 (PEGASUS_PROPERTYNAME_QUERY)).getValue ().toString ();
4427 QueryExpression queryExpression;
4430 queryExpression = _getQueryExpression(
4431 filterQuery, queryLanguage, sourceNameSpace);
4433 catch (QueryLanguageInvalidException&)
4435 // The filter query had an invalid language name.
4437 throw PEGASUS_CIM_EXCEPTION(
4438 CIM_ERR_NOT_SUPPORTED, queryLanguage);
4441 CIMName indicationClassName = _getIndicationClassName
4442 (queryExpression, sourceNameSpace);
4445 // Make sure that the FROM class exists in the repository.
4447 CIMClass indicationClass = _subscriptionRepository->getClass
4448 (sourceNameSpace, indicationClassName,
4449 false, false, false, CIMPropertyList ());
4452 // Validate all the properties in the SELECT statement exist
4453 // on their class context.
4457 queryExpression.validate();
4459 catch (QueryMissingPropertyException& qmp)
4461 // A property does not exist on the class it is scoped to.
4463 throw PEGASUS_CIM_EXCEPTION
4464 (CIM_ERR_INVALID_PARAMETER, qmp.getMessage());
4466 catch (QueryValidationException& qv)
4468 // Received some other validation error.
4469 // This includes detecting an array property
4470 // is in the WHERE list for WQL.
4472 throw PEGASUS_CIM_EXCEPTION
4473 (CIM_ERR_NOT_SUPPORTED, qv.getMessage());
4478 // Currently only five subclasses of the Listener Destination
4479 // class are supported -- further subclassing is not currently
4482 else if ((instance.getClassName ().equal
4483 (PEGASUS_CLASSNAME_INDHANDLER_CIMXML)) ||
4484 (instance.getClassName ().equal
4485 (PEGASUS_CLASSNAME_LSTNRDST_CIMXML)) ||
4486 (instance.getClassName ().equal
4487 (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG)) ||
4488 (instance.getClassName ().equal
4489 (PEGASUS_CLASSNAME_LSTNRDST_EMAIL)) ||
4490 (instance.getClassName ().equal
4491 (PEGASUS_CLASSNAME_INDHANDLER_SNMP)))
4493 #ifndef PEGASUS_ENABLE_SYSTEM_LOG_HANDLER
4494 if (instance.getClassName ().equal
4495 (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG))
4498 // The System Log Handler is not enabled currently,
4499 // this class is not currently served by the Indication Service
4503 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_NOT_SUPPORTED,
4504 MessageLoaderParms(_MSG_CLASS_NOT_SERVED_KEY,
4505 _MSG_CLASS_NOT_SERVED));
4509 #if !defined(PEGASUS_ENABLE_EMAIL_HANDLER)
4511 if (instance.getClassName ().equal
4512 (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))
4515 // The Email Handler is not enabled currently,
4516 // this class is not currently served by the Indication Service
4520 throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_NOT_SUPPORTED,
4521 MessageLoaderParms(_MSG_CLASS_NOT_SERVED_KEY,
4522 _MSG_CLASS_NOT_SERVED));
4525 _checkPropertyWithOther(
4527 PEGASUS_PROPERTYNAME_PERSISTENCETYPE,
4528 _PROPERTY_OTHERPERSISTENCETYPE,
4529 (Uint16) PERSISTENCE_PERMANENT,
4530 (Uint16) PERSISTENCE_OTHER,
4531 _validPersistenceTypes,
4532 _supportedPersistenceTypes);
4535 // For remaining property, verify that if the property exists in
4536 // the instance it is of the correct type
4538 _checkProperty(instance, _PROPERTY_OWNER, CIMTYPE_STRING);
4540 if (instance.getClassName().equal(
4541 PEGASUS_CLASSNAME_INDHANDLER_CIMXML) ||
4542 instance.getClassName().equal(
4543 PEGASUS_CLASSNAME_LSTNRDST_CIMXML))
4546 // Destination property is required for CIMXML
4549 _checkRequiredProperty(
4551 PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION,
4556 if (instance.getClassName().equal
4557 (PEGASUS_CLASSNAME_INDHANDLER_SNMP))
4560 // TargetHost property is required for SNMP
4563 _checkRequiredProperty(
4565 PEGASUS_PROPERTYNAME_LSTNRDST_TARGETHOST,
4570 // TargetHostFormat property is required for SNMP
4573 _checkRequiredProperty(
4575 _PROPERTY_TARGETHOSTFORMAT,
4580 // SNMPVersion property is required for SNMP Handler
4582 _checkRequiredProperty(
4584 PEGASUS_PROPERTYNAME_SNMPVERSION,
4588 // Currently, only SNMPv1 trap and SNMPv2C trap are supported,
4589 // verify if the value of SNMPVersion is one of them
4593 PEGASUS_PROPERTYNAME_SNMPVERSION,
4595 _supportedSNMPVersion);
4598 // For each remaining property, verify that if the property
4599 // exists in the instance it is of the correct type
4601 _checkProperty(instance, _PROPERTY_PORTNUMBER, CIMTYPE_UINT32);
4602 _checkProperty(instance, _PROPERTY_SNMPSECURITYNAME,
4604 _checkProperty(instance, _PROPERTY_SNMPENGINEID,
4608 if (instance.getClassName().equal
4609 (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))
4612 // MailTo property is required for Email
4615 _checkRequiredProperty(
4617 PEGASUS_PROPERTYNAME_LSTNRDST_MAILTO,
4622 // get MailTo from handler instance
4623 Array<String> mailTo;
4624 instance.getProperty(instance.findProperty(
4625 PEGASUS_PROPERTYNAME_LSTNRDST_MAILTO)).getValue().get(
4628 // Build mail address string
4630 Uint32 mailAddrSize = mailTo.size();
4632 for (Uint32 i=0; i < mailAddrSize; i++)
4634 mailAddrStr.append(mailTo[i]);
4636 if (i < (mailAddrSize - 1))
4638 mailAddrStr.append(",");
4644 // Email address can not be an empty string
4646 if (mailAddrStr == String::EMPTY)
4649 throw PEGASUS_CIM_EXCEPTION_L(
4652 "IndicationService.IndicationService."
4653 "_MSG_DO_NOT_HAVE_EMAIL_ADDRESS",
4654 "Do not have an e-mail address."));
4658 // MailSubject property is required for Email
4661 _checkRequiredProperty(
4663 PEGASUS_PROPERTYNAME_LSTNRDST_MAILSUBJECT,
4668 // For MailCc property, verify that if the property
4669 // exists in the instance it is of the correct type
4673 PEGASUS_PROPERTYNAME_LSTNRDST_MAILCC,
4682 // A class not currently served by the Indication Service
4686 throw PEGASUS_CIM_EXCEPTION_L(
4687 CIM_ERR_NOT_SUPPORTED,
4689 _MSG_CLASS_NOT_SERVED_KEY,
4690 _MSG_CLASS_NOT_SERVED));
4698 void IndicationService::_checkRequiredProperty(
4699 CIMInstance& instance,
4700 const CIMName& propertyName,
4701 const CIMType expectedType,
4702 Boolean isKeyProperty,
4705 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
4706 "IndicationService::_checkRequiredProperty");
4708 Boolean missingProperty = false;
4711 // Required property must exist in instance
4713 if (instance.findProperty (propertyName) == PEG_NOT_FOUND)
4715 missingProperty = true;
4722 CIMProperty theProperty = instance.getProperty
4723 (instance.findProperty (propertyName));
4724 CIMValue theValue = theProperty.getValue ();
4727 // Required property must have a non-null value
4729 if (theValue.isNull ())
4731 missingProperty = true;
4736 // Check that the property value is of the correct type
4738 if ((theValue.getType () != expectedType) ||
4739 (theValue.isArray () != isArray))
4741 if (theValue.isArray ())
4744 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER,
4746 _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY_KEY,
4747 _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY,
4748 cimTypeToString(theValue.getType()),
4749 propertyName.getString()));
4754 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_INVALID_PARAMETER,
4756 _MSG_INVALID_TYPE_FOR_PROPERTY_KEY,
4757 _MSG_INVALID_TYPE_FOR_PROPERTY,
4758 cimTypeToString(theValue.getType()),
4759 propertyName.getString()));
4765 if (missingProperty)
4770 throw PEGASUS_CIM_EXCEPTION_L(
4771 CIM_ERR_INVALID_PARAMETER,
4773 "IndicationService.IndicationService._MSG_KEY_PROPERTY",
4774 "The key property $0 is missing.",
4775 propertyName.getString()));
4780 throw PEGASUS_CIM_EXCEPTION_L(
4781 CIM_ERR_INVALID_PARAMETER,
4785 propertyName.getString()));
4792 void IndicationService::_checkPropertyWithOther (
4793 CIMInstance& instance,
4794 const CIMName& propertyName,
4795 const CIMName& otherPropertyName,
4796 const Uint16 defaultValue,
4797 const Uint16 otherValue,
4798 const Array<Uint16>& validValues,
4799 const Array<Uint16>& supportedValues)
4801 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
4802 "IndicationService::_checkPropertyWithOther");
4804 Uint16 result = defaultValue;
4807 // If the property doesn't exist, add it with the default value
4809 if (instance.findProperty (propertyName) == PEG_NOT_FOUND)
4811 instance.addProperty (CIMProperty (propertyName,
4812 CIMValue (defaultValue)));
4819 CIMProperty theProperty = instance.getProperty
4820 (instance.findProperty (propertyName));
4821 CIMValue theValue = theProperty.getValue ();
4824 // Check that the value is of the correct type
4826 if ((theValue.getType () != CIMTYPE_UINT16) || (theValue.isArray ()))
4828 String exceptionStr;
4829 if (theValue.isArray ())
4831 MessageLoaderParms parms(
4832 "IndicationService.IndicationService."
4833 "_MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY",
4834 "Invalid type array of $0 for property $1",
4835 cimTypeToString(theValue.getType()),
4836 propertyName.getString());
4838 exceptionStr.append(MessageLoader::getMessage(parms));
4842 MessageLoaderParms parms(
4843 "IndicationService.IndicationService."
4844 "_MSG_INVALID_TYPE_FOR_PROPERTY",
4845 "Invalid type $0 for property $1",
4846 cimTypeToString(theValue.getType()),
4847 propertyName.getString());
4849 exceptionStr.append(MessageLoader::getMessage(parms));
4852 throw PEGASUS_CIM_EXCEPTION (CIM_ERR_INVALID_PARAMETER,
4857 // If the value is null, set to the default value
4859 if (theValue.isNull ())
4861 theProperty.setValue (CIMValue (defaultValue));
4865 theValue.get (result);
4868 // Validate the value
4870 // Note: Valid values are defined by the CIM Event Schema MOF
4872 if (!Contains (validValues, result))
4875 throw PEGASUS_CIM_EXCEPTION_L(
4876 CIM_ERR_INVALID_PARAMETER,
4878 _MSG_INVALID_VALUE_FOR_PROPERTY_KEY,
4879 _MSG_INVALID_VALUE_FOR_PROPERTY,
4880 theValue.toString(),
4881 propertyName.getString()));
4885 // Check for valid values that are not supported
4887 // Note: Supported values are a subset of the valid values
4888 // Some valid values, as defined in the MOF, are not currently
4889 // supported by the Pegasus IndicationService
4891 if (!Contains(supportedValues, result))
4894 throw PEGASUS_CIM_EXCEPTION_L(
4895 CIM_ERR_NOT_SUPPORTED,
4897 _MSG_UNSUPPORTED_VALUE_FOR_PROPERTY_KEY,
4898 _MSG_UNSUPPORTED_VALUE_FOR_PROPERTY,
4899 theValue.toString(),
4900 propertyName.getString()));
4905 // If the value is Other, the Other
4906 // property must exist, value must not be NULL and type must be String
4908 if (result == otherValue)
4910 if (instance.findProperty(otherPropertyName) == PEG_NOT_FOUND)
4913 throw PEGASUS_CIM_EXCEPTION_L(
4914 CIM_ERR_INVALID_PARAMETER,
4918 otherPropertyName.getString()));
4922 CIMProperty otherProperty = instance.getProperty
4923 (instance.findProperty(otherPropertyName));
4924 CIMValue theOtherValue = otherProperty.getValue();
4925 if (theOtherValue.isNull())
4928 throw PEGASUS_CIM_EXCEPTION_L(
4929 CIM_ERR_INVALID_PARAMETER,
4933 otherPropertyName.getString()));
4935 else if (theOtherValue.getType() != CIMTYPE_STRING)
4938 // Property exists and is not null,
4939 // but is not of correct type
4942 throw PEGASUS_CIM_EXCEPTION_L(
4943 CIM_ERR_INVALID_PARAMETER,
4945 _MSG_INVALID_TYPE_FOR_PROPERTY_KEY,
4946 _MSG_INVALID_TYPE_FOR_PROPERTY,
4947 cimTypeToString(theOtherValue.getType()),
4948 otherPropertyName.getString()));
4954 // If value is not Other, Other property must not exist
4957 else if (instance.findProperty (otherPropertyName) != PEG_NOT_FOUND)
4959 CIMProperty otherProperty = instance.getProperty(
4960 instance.findProperty(otherPropertyName));
4961 CIMValue theOtherValue = otherProperty.getValue();
4962 if (!theOtherValue.isNull())
4965 throw PEGASUS_CIM_EXCEPTION_L(
4966 CIM_ERR_INVALID_PARAMETER,
4968 "IndicationService.IndicationService."
4969 "_MSG_PROPERTY_PRESENT_BUT_VALUE_NOT",
4970 "The $0 property is present, but the $1 value is "
4972 otherPropertyName.getString(),
4973 propertyName.getString(),
4974 CIMValue(otherValue).toString()));
4982 String IndicationService::_checkPropertyWithGuid(
4983 CIMInstance& instance,
4984 const CIMName& propertyName)
4986 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
4987 "IndicationService::_checkPropertyWithGuid");
4989 String value = _checkPropertyWithDefault(
4992 Guid::getGuid(PEGASUS_INSTANCEID_GLOBAL_PREFIX));
4999 String IndicationService::_checkPropertyWithDefault(
5000 CIMInstance& instance,
5001 const CIMName& propertyName,
5002 const String& defaultValue)
5004 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
5005 "IndicationService::_checkPropertyWithDefault");
5007 String result = defaultValue;
5010 // If the property doesn't exist, add it with the default value
5012 if (instance.findProperty (propertyName) == PEG_NOT_FOUND)
5014 instance.addProperty (CIMProperty (propertyName,
5015 CIMValue (defaultValue)));
5022 CIMProperty theProperty = instance.getProperty
5023 (instance.findProperty (propertyName));
5024 CIMValue theValue = theProperty.getValue ();
5027 // If the value is null, set to the default value
5029 if (theValue.isNull ())
5031 theProperty.setValue (CIMValue (defaultValue));
5033 else if ((theValue.getType () != CIMTYPE_STRING) ||
5034 (theValue.isArray ()))
5037 // Property exists and is not null,
5038 // but is not of correct type
5040 if (theValue.isArray ())
5043 throw PEGASUS_CIM_EXCEPTION_L(
5044 CIM_ERR_INVALID_PARAMETER,
5046 _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY_KEY,
5047 _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY,
5048 cimTypeToString(theValue.getType()),
5049 propertyName.getString()));
5054 throw PEGASUS_CIM_EXCEPTION_L(
5055 CIM_ERR_INVALID_PARAMETER,
5057 _MSG_INVALID_TYPE_FOR_PROPERTY_KEY,
5058 _MSG_INVALID_TYPE_FOR_PROPERTY,
5059 cimTypeToString(theValue.getType()),
5060 propertyName.getString()));
5065 theValue.get (result);
5073 String IndicationService::_initOrValidateStringProperty (
5074 CIMInstance& instance,
5075 const CIMName& propertyName,
5076 const String& defaultValue)
5078 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
5079 "IndicationService::_initOrValidateStringProperty");
5081 String result = defaultValue;
5083 String propertyValue = _checkPropertyWithDefault (instance, propertyName,
5086 if (propertyValue != defaultValue)
5088 #ifdef PEGASUS_SNIA_EXTENSIONS
5089 // SNIA requires SystemName and SystemCreationClassName to be
5090 // overridden with the correct values.
5091 if ((propertyName == _PROPERTY_SYSTEMNAME) ||
5092 (propertyName == _PROPERTY_SYSTEMCREATIONCLASSNAME))
5094 // The property must exist after _checkPropertyWithDefault is called
5096 instance.getProperty(instance.findProperty(propertyName));
5097 p.setValue(CIMValue(defaultValue));
5104 // Property value specified is invalid
5107 throw PEGASUS_CIM_EXCEPTION_L(
5108 CIM_ERR_INVALID_PARAMETER,
5110 _MSG_INVALID_VALUE_FOR_PROPERTY_KEY,
5111 _MSG_INVALID_VALUE_FOR_PROPERTY,
5113 propertyName.getString()));
5120 void IndicationService::_checkProperty (
5121 CIMInstance& instance,
5122 const CIMName& propertyName,
5123 const CIMType expectedType,
5124 const Boolean isArray)
5126 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
5127 "IndicationService::_checkProperty");
5130 // If the property exists, get it
5132 Uint32 propPos = instance.findProperty (propertyName);
5133 if (propPos != PEG_NOT_FOUND)
5135 CIMProperty theProperty = instance.getProperty (propPos);
5136 CIMValue theValue = theProperty.getValue ();
5139 // If the value is not null, check the type
5141 if (!theValue.isNull ())
5143 if ((theValue.getType () != expectedType) ||
5144 (theValue.isArray () != isArray))
5147 // Property exists and is not null, but is not of correct type
5149 if (theValue.isArray ())
5152 throw PEGASUS_CIM_EXCEPTION_L(
5153 CIM_ERR_INVALID_PARAMETER,
5155 _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY_KEY,
5156 _MSG_INVALID_TYPE_ARRAY_OF_FOR_PROPERTY,
5157 cimTypeToString(theValue.getType()),
5158 propertyName.getString()));
5163 throw PEGASUS_CIM_EXCEPTION_L(
5164 CIM_ERR_INVALID_PARAMETER,
5166 _MSG_INVALID_TYPE_FOR_PROPERTY_KEY,
5167 _MSG_INVALID_TYPE_FOR_PROPERTY,
5168 cimTypeToString(theValue.getType()),
5169 propertyName.getString()));
5178 void IndicationService::_checkSupportedProperties (
5179 const CIMInstance& instance)
5181 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
5182 "IndicationService::_checkSupportedProperties");
5184 CIMName className = instance.getClassName ();
5185 Array<CIMName> emptyArray;
5186 Array<CIMName>& supportedProperties = emptyArray;
5189 // Get list of supported properties for the class
5191 if (className.equal (PEGASUS_CLASSNAME_INDSUBSCRIPTION))
5193 supportedProperties = _supportedSubscriptionProperties;
5195 else if (className.equal (PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))
5197 supportedProperties = _supportedFormattedSubscriptionProperties;
5199 else if (className.equal (PEGASUS_CLASSNAME_INDFILTER))
5201 supportedProperties = _supportedFilterProperties;
5203 else if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_CIMXML))
5205 supportedProperties = _supportedCIMXMLHandlerProperties;
5207 else if (className.equal (PEGASUS_CLASSNAME_LSTNRDST_CIMXML))
5209 supportedProperties = _supportedCIMXMLListenerDestinationProperties;
5211 else if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_SNMP))
5213 supportedProperties = _supportedSNMPHandlerProperties;
5215 else if (className.equal (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG))
5217 supportedProperties = _supportedSyslogListenerDestinationProperties;
5219 else if (className.equal (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))
5221 supportedProperties = _supportedEmailListenerDestinationProperties;
5225 PEGASUS_ASSERT (false);
5229 // Check if each property in the instance is in the list of supported,
5230 // known properties for its class
5232 for (Uint32 i = 0; i < instance.getPropertyCount (); i++)
5234 if (!ContainsCIMName (supportedProperties,
5235 instance.getProperty (i).getName ()))
5238 // Throw an exception if an unknown, unsupported property was found
5241 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
5243 "IndicationService.IndicationService."
5244 "_MSG_PROPERTY_NOT_SUPPORTED",
5245 "Property $0 is not supported in class $1",
5246 instance.getProperty (i).getName ().getString (),
5247 className.getString ()));
5254 void IndicationService::_checkValue (
5255 const CIMInstance& instance,
5256 const CIMName& propertyName,
5257 const Array<Uint16>& validValues,
5258 const Array<Uint16>& supportedValues)
5260 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
5261 "IndicationService::_checkValue");
5265 // get the property value
5266 Uint32 propPos = instance.findProperty (propertyName);
5267 if (propPos != PEG_NOT_FOUND)
5269 CIMValue propertyValue = (instance.getProperty(propPos)).getValue();
5271 if (!(propertyValue.isNull()))
5273 propertyValue.get(theValue);
5275 // Validate the value
5276 // Note: Valid values are defined by the PG Events MOF
5277 if (!Contains(validValues, theValue))
5281 throw PEGASUS_CIM_EXCEPTION_L(
5282 CIM_ERR_INVALID_PARAMETER,
5284 _MSG_INVALID_VALUE_FOR_PROPERTY_KEY,
5285 _MSG_INVALID_VALUE_FOR_PROPERTY,
5287 propertyName.getString()));
5291 // Check for valid values that are not supported
5292 // Note: Supported values are a subset of the valid values
5293 // Some valid values, as defined in the MOF, are not currently
5295 if (!Contains(supportedValues, theValue))
5298 throw PEGASUS_CIM_EXCEPTION_L(
5299 CIM_ERR_NOT_SUPPORTED,
5301 _MSG_UNSUPPORTED_VALUE_FOR_PROPERTY_KEY,
5302 _MSG_UNSUPPORTED_VALUE_FOR_PROPERTY,
5304 propertyName.getString()));
5312 Boolean IndicationService::_canModify (
5313 const CIMModifyInstanceRequestMessage * request,
5314 const CIMObjectPath& instanceReference,
5315 const CIMInstance& instance,
5316 CIMInstance& modifiedInstance)
5318 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "IndicationService::_canModify");
5321 // Currently, only modification allowed is of Subscription State
5322 // property in Subscription class
5324 if (!(instanceReference.getClassName ().equal
5325 (PEGASUS_CLASSNAME_INDSUBSCRIPTION)) &&
5326 !(instanceReference.getClassName ().equal
5327 (PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION)))
5330 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
5333 if (request->includeQualifiers)
5336 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
5340 // Request is invalid if property list is null, meaning all properties
5341 // are to be updated
5343 if (request->propertyList.isNull ())
5346 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
5350 // Request is invalid if more than one property is specified
5352 else if (request->propertyList.size() > 1)
5355 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
5359 // For request to be valid, zero or one property must be specified
5360 // If one property specified, it must be Subscription State property
5362 else if ((request->propertyList.size() == 1) &&
5363 (!request->propertyList[0].equal(
5364 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE)))
5367 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
5371 // Check the SubscriptionState property in the modified instance
5373 _checkPropertyWithOther(
5375 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE,
5376 _PROPERTY_OTHERSTATE,
5377 (Uint16) STATE_ENABLED,
5378 (Uint16) STATE_OTHER,
5383 // Get creator from instance
5386 if (!_getCreator (instance, creator))
5389 // This instance from the repository is corrupted
5392 MessageLoaderParms parms(_MSG_INVALID_INSTANCES_KEY,
5393 _MSG_INVALID_INSTANCES);
5394 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, parms);
5398 // Current user must be privileged user or instance Creator to modify
5399 // NOTE: if authentication was not turned on when instance was created,
5400 // instance creator will be String::EMPTY
5401 // If creator is String::EMPTY, anyone may modify or delete the
5404 String currentUser = ((IdentityContainer)request->operationContext.get
5405 (IdentityContainer :: NAME)).getUserName();
5406 if ((creator != String::EMPTY) &&
5407 #ifndef PEGASUS_OS_ZOS
5408 (!System::isPrivilegedUser (currentUser)) &&
5410 (currentUser != creator))
5413 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ACCESS_DENIED, String::EMPTY);
5420 Boolean IndicationService::_canDelete (
5421 const CIMObjectPath& instanceReference,
5422 const CIMNamespaceName& nameSpace,
5423 const String& currentUser)
5425 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE, "IndicationService::_canDelete");
5431 // Get the instance to be deleted from the repository
5433 CIMInstance instance;
5435 instance = _subscriptionRepository->getInstance
5436 (nameSpace, instanceReference);
5439 // Get creator from instance
5442 if (!_getCreator (instance, creator))
5445 // This instance from the repository is corrupted
5446 // Allow the delete if a Privileged User
5447 // (or authentication turned off),
5448 // Otherwise disallow as access denied
5450 #ifndef PEGASUS_OS_ZOS
5451 if ((!System::isPrivilegedUser (currentUser)) &&
5452 (currentUser != String::EMPTY))
5455 throw PEGASUS_CIM_EXCEPTION (CIM_ERR_ACCESS_DENIED, String::EMPTY);
5461 // Current user must be privileged user or instance Creator to delete
5462 // NOTE: if authentication was not turned on when instance was created,
5463 // instance creator will be String::EMPTY
5464 // If creator is String::EMPTY, anyone may modify or delete the
5467 if ((creator != String::EMPTY) &&
5468 #ifndef PEGASUS_OS_ZOS
5469 (!System::isPrivilegedUser (currentUser)) &&
5471 (currentUser != creator))
5474 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ACCESS_DENIED, String::EMPTY);
5478 // Get the class and superclass of the instance to be deleted
5482 refClass = _subscriptionRepository->getClass (nameSpace,
5483 instanceReference.getClassName (), true, true, false,
5484 CIMPropertyList ());
5485 superClass = refClass.getSuperClassName();
5488 // If the class is Filter or superclass is Handler or Listener Destination,
5489 // check for subscription instances referring to the instance to be deleted
5491 if ((superClass.equal (PEGASUS_CLASSNAME_INDHANDLER)) ||
5492 (superClass.equal (PEGASUS_CLASSNAME_LSTNRDST)) ||
5493 (instanceReference.getClassName().equal (PEGASUS_CLASSNAME_INDFILTER)))
5495 if (instanceReference.getClassName ().equal
5496 (PEGASUS_CLASSNAME_INDFILTER))
5498 propName = PEGASUS_PROPERTYNAME_FILTER;
5500 else if ((superClass.equal (PEGASUS_CLASSNAME_INDHANDLER)) ||
5501 (superClass.equal (PEGASUS_CLASSNAME_LSTNRDST)))
5503 propName = PEGASUS_PROPERTYNAME_HANDLER;
5506 // If deleting transient handler, first delete any referencing
5509 if (_subscriptionRepository->isTransient (nameSpace,
5512 _deleteReferencingSubscriptions (nameSpace, propName,
5520 // Get all the subscriptions from the repository
5522 Array<CIMInstance> subscriptions =
5523 _subscriptionRepository->getAllSubscriptions ();
5528 // Check each subscription for a reference to the instance to be
5531 for (Uint32 i = 0; i < subscriptions.size(); i++)
5534 // Get the subscription Filter or Handler property value
5536 propValue = subscriptions[i].getProperty
5537 (subscriptions[i].findProperty
5538 (propName)).getValue();
5541 propValue.get (ref);
5544 // If the Filter or Handler reference property value includes
5545 // namespace, check if it is the namespace of the Filter or Handler
5547 // If the Filter or Handler reference property value does not
5548 // include namespace, check if the current subscription namespace
5549 // is the namespace of the Filter or Handler being deleted.
5551 CIMNamespaceName instanceNS = ref.getNameSpace ();
5552 if (((instanceNS.isNull ()) &&
5553 (subscriptions[i].getPath ().getNameSpace () == nameSpace))
5554 || (instanceNS == nameSpace))
5558 // Remove Host and Namespace from reference property value, if
5559 // present, before comparing
5561 CIMObjectPath path ("", CIMNamespaceName (),
5562 ref.getClassName (), ref.getKeyBindings ());
5565 // Remove Host and Namespace from reference of instance to be
5566 // deleted, if present, before comparing
5568 CIMObjectPath iref ("", CIMNamespaceName (),
5569 instanceReference.getClassName (),
5570 instanceReference.getKeyBindings ());
5573 // If the current subscription Filter or Handler is the
5574 // instance to be deleted, it may not be deleted
5579 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
5581 "IndicationService.IndicationService."
5583 "A filter or handler referenced by a subscription "
5584 "cannot be deleted."));
5594 Array<CIMInstance> IndicationService::_getMatchingSubscriptions (
5595 const CIMName& supportedClass,
5596 const Array<CIMNamespaceName> nameSpaces,
5597 const CIMPropertyList& supportedProperties,
5598 const Boolean checkProvider,
5599 const CIMInstance& provider)
5601 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
5602 "IndicationService::_getMatchingSubscriptions");
5604 Array<CIMInstance> matchingSubscriptions;
5605 Array<CIMInstance> subscriptions;
5607 subscriptions = _subscriptionTable->getMatchingSubscriptions
5608 (supportedClass, nameSpaces, checkProvider, provider);
5610 for (Uint32 i = 0; i < subscriptions.size (); i++)
5612 Boolean match = true;
5615 // If supported properties is null (all properties)
5616 // the subscription can be supported
5618 if (!supportedProperties.isNull ())
5621 String queryLanguage;
5622 CIMName indicationClassName;
5623 CIMNamespaceName sourceNameSpace;
5624 CIMPropertyList propertyList;
5630 // Get filter properties
5632 _subscriptionRepository->getFilterProperties
5633 (subscriptions[i], filterQuery, sourceNameSpace,
5634 queryLanguage, filterName);
5636 QueryExpression queryExpr = _getQueryExpression(
5637 filterQuery, queryLanguage, sourceNameSpace);
5639 // Get the class paths in the FROM list
5640 // Since neither WQL nor CQL support joins, so we can
5641 // assume one class path.
5642 indicationClassName =
5643 queryExpr.getClassPathList()[0].getClassName();
5645 if (!_subscriptionRepository->validateIndicationClassName(
5646 indicationClassName, sourceNameSpace))
5648 // Invalid FROM class, skip the subscription
5653 // Get required property list from filter query (WHERE clause)
5655 // Note that the supportedClass is passed in,
5656 // not the indicationClassName.
5657 // The supportedClass is the class of the indication
5658 // instance, while the indicationClassName is the FROM class.
5659 // This is needed because CQL can have class scoping operators
5660 // on properties that may not be the same class
5661 // as the FROM class. The required properties
5662 // for an indication are based on its class,
5663 // not the FROM class.
5665 // Also note that for CQL, this does not return
5666 // required embedded object properties.
5667 propertyList = _getPropertyList (queryExpr,
5672 // If the subscription requires all properties,
5673 // but supported property list does not include all
5674 // properties, the subscription cannot be supported
5676 if (propertyList.isNull ())
5679 // Current subscription does not match
5680 // Continue to next subscription in list
5687 // Compare subscription required property list
5688 // with supported property list
5691 j < propertyList.size () && match;
5694 if (!ContainsCIMName
5695 (supportedProperties.getPropertyNameArray(),
5704 catch(const Exception & e)
5706 // This subscription is invalid
5708 PEG_TRACE ((TRC_DISCARDED_DATA, Tracer::LEVEL2,
5709 "Exception caught trying to verify required properties"
5710 " in a subscription are all contained in the list of"
5711 " supported indication properties: %s",
5712 (const char *) e.getMessage ().getCString()));
5715 catch(const exception & e)
5717 // This subscription is invalid
5719 PEG_TRACE ((TRC_DISCARDED_DATA, Tracer::LEVEL2,
5720 "Exception caught trying to verify required properties"
5721 " in a subscription are all contained in the list of"
5722 " supported indication properties: %s", e.what ()));
5727 // This subscription is invalid
5729 PEG_TRACE_CSTRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
5730 "Unknown exception caught trying to verify "
5731 "required properties in a subscription are all contained "
5732 "in the list of supported indication properties.");
5740 // Add current subscription to list
5742 matchingSubscriptions.append (subscriptions[i]);
5747 return matchingSubscriptions;
5750 void IndicationService::_getModifiedSubscriptions (
5751 const CIMName& supportedClass,
5752 const Array<CIMNamespaceName>& newNameSpaces,
5753 const Array<CIMNamespaceName>& oldNameSpaces,
5754 const CIMPropertyList& newProperties,
5755 const CIMPropertyList& oldProperties,
5756 Array<CIMInstance>& newSubscriptions,
5757 Array<CIMInstance>& formerSubscriptions)
5759 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
5760 "IndicationService::_getModifiedSubscriptions");
5762 Array<CIMInstance> newList;
5763 Array<CIMInstance> formerList;
5764 Array<CIMInstance> bothList;
5766 newSubscriptions.clear ();
5767 formerSubscriptions.clear ();
5770 // For each newly supported namespace, lookup to retrieve list of
5771 // subscriptions for the indication class-source namespace pair
5773 newList = _subscriptionTable->getMatchingSubscriptions
5774 (supportedClass, newNameSpaces);
5777 // For each formerly supported namespace, lookup to retrieve list of
5778 // subscriptions for the indication class-source namespace pair
5780 formerList = _subscriptionTable->getMatchingSubscriptions
5781 (supportedClass, oldNameSpaces);
5784 // Find subscriptions that appear in both lists, and move them to a third
5788 for (Uint32 p = 0; p < newList.size (); p++)
5791 for (Uint32 q = 0; q < formerList.size (); q++)
5793 if (newList[p].identical (formerList[q]))
5796 bothList.append (newList[p]);
5804 formerList.remove (found);
5809 // For indicationClassName-sourceNamespace pair that is now supported, but
5810 // previously was not, add to list of newly supported subscriptions if
5811 // required properties are now supported
5813 for (Uint32 n = 0; n < newList.size (); n++)
5816 String queryLanguage;
5817 CIMName indicationClassName;
5818 CIMNamespaceName sourceNameSpace;
5819 CIMPropertyList requiredProperties;
5823 // Get filter properties
5825 _subscriptionRepository->getFilterProperties (newList[n], filterQuery,
5826 sourceNameSpace, queryLanguage, filterName);
5827 QueryExpression queryExpression = _getQueryExpression(
5828 filterQuery, queryLanguage, sourceNameSpace);
5831 // Get indication class name from filter query (FROM clause)
5833 indicationClassName = _getIndicationClassName (queryExpression,
5837 // Get required property list from filter query (WHERE clause)
5839 // Note: the supportedClass is passed to _getPropertyList
5840 // rather than the FROM class because CQL could have
5841 // class scoping operators that scope properties to
5842 // specific subclasses of the FROM.
5844 requiredProperties = _getPropertyList (queryExpression,
5845 sourceNameSpace, supportedClass);
5848 // Check if required properties are now supported
5850 if (_inPropertyList (requiredProperties, newProperties))
5852 newSubscriptions.append (newList[n]);
5857 // For indicationClassName-sourceNamespace pair that was previously
5858 // supported, but now is not, add to list of formerly supported
5861 for (Uint32 f = 0; f < formerList.size (); f++)
5863 formerSubscriptions.append (formerList[f]);
5867 // For indicationClassName-sourceNamespace pair that is now supported,
5868 // and was also previously supported, add to appropriate list, based on
5869 // required properties
5871 for (Uint32 b = 0; b < bothList.size (); b++)
5874 String queryLanguage;
5875 CIMName indicationClassName;
5876 CIMNamespaceName sourceNameSpace;
5877 CIMPropertyList requiredProperties;
5878 Boolean newMatch = false;
5879 Boolean formerMatch = false;
5883 // Get filter properties
5885 _subscriptionRepository->getFilterProperties (bothList[b], filterQuery,
5886 sourceNameSpace, queryLanguage, filterName);
5887 QueryExpression queryExpression = _getQueryExpression(
5888 filterQuery, queryLanguage, sourceNameSpace);
5891 // Get indication class name from filter query (FROM clause)
5893 indicationClassName = _getIndicationClassName (queryExpression,
5897 // Get required property list from filter query (WHERE clause)
5899 // Note: the supportedClass is passed to _getPropertyList
5900 // rather than the FROM class because CQL could have
5901 // class scoping operators that scope properties to
5902 // specific subclasses of the FROM.
5904 requiredProperties = _getPropertyList (queryExpression,
5905 sourceNameSpace, supportedClass);
5908 // Check required properties
5910 newMatch = _inPropertyList (requiredProperties,
5912 formerMatch = _inPropertyList (requiredProperties,
5916 // Add current subscription to appropriate list
5918 if (newMatch && !formerMatch)
5920 newSubscriptions.append (bothList[b]);
5922 else if (!newMatch && formerMatch)
5924 formerSubscriptions.append (bothList[b]);
5931 Boolean IndicationService::_inPropertyList (
5932 const CIMPropertyList& requiredProperties,
5933 const CIMPropertyList& supportedProperties)
5935 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
5936 "IndicationService::_inPropertyList");
5939 // If property list is null (all properties)
5940 // all the required properties are supported
5942 if (supportedProperties.isNull ())
5950 // If the subscription requires all properties,
5951 // but property list does not include all
5952 // properties, the required properties cannot be supported
5954 if (requiredProperties.isNull ())
5962 // Compare required property list
5963 // with property list
5965 for (Uint32 i = 0; i < requiredProperties.size (); i++)
5967 if (!ContainsCIMName
5968 (supportedProperties.getPropertyNameArray (),
5969 requiredProperties[i]))
5982 QueryExpression IndicationService::_getQueryExpression(
5983 const String& filterQuery,
5984 const String& queryLanguage,
5985 const CIMNamespaceName& ns) const
5987 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
5988 "IndicationService::_getQueryExpression");
5992 RepositoryQueryContext ctx(ns, _cimRepository);
5993 QueryExpression queryExpression(queryLanguage, filterQuery, ctx);
5995 return queryExpression;
5997 catch (QueryParseException& qpe)
5999 String exceptionStr = qpe.getMessage();
6002 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, exceptionStr);
6004 catch (ParseError& pe)
6006 String exceptionStr = pe.getMessage();
6009 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, exceptionStr);
6011 catch (MissingNullTerminator& mnt)
6013 String exceptionStr = mnt.getMessage();
6016 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, exceptionStr);
6020 CIMName IndicationService::_getIndicationClassName (
6021 const QueryExpression& queryExpression,
6022 const CIMNamespaceName& nameSpaceName) const
6024 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
6025 "IndicationService::_getIndicationClassName");
6027 CIMName indicationClassName;
6028 Array<CIMName> indicationSubclasses;
6030 // Get the class paths in the FROM list.
6031 // Note: neither WQL nor CQL support joins, so we can
6032 // assume one class path.
6033 // Note: neither WQL not CQL support wbem-uri for class paths,
6034 // so we can ignore the parts of the path before the class name.
6035 Array<CIMObjectPath> fromPaths = queryExpression.getClassPathList();
6036 indicationClassName = fromPaths[0].getClassName();
6039 // Validate that class is an Indication class
6040 // The Indication Qualifier should exist and have the value True
6042 Boolean validClass = _subscriptionRepository->validateIndicationClassName
6043 (indicationClassName, nameSpaceName);
6048 throw PEGASUS_CIM_EXCEPTION_L(
6049 CIM_ERR_INVALID_PARAMETER,
6051 "IndicationService.IndicationService."
6052 "_MSG_INVALID_CLASSNAME_IN_FROM_PROPERTY",
6053 "The Indication class name $0 is not valid in the FROM clause "
6054 "of $1 $2 property.",
6055 indicationClassName.getString(),
6056 PEGASUS_CLASSNAME_INDFILTER.getString(),
6057 PEGASUS_PROPERTYNAME_QUERY.getString()));
6061 return indicationClassName;
6064 Array<ProviderClassList> IndicationService::_getIndicationProviders (
6065 const QueryExpression& queryExpression,
6066 const CIMNamespaceName& nameSpace,
6067 const CIMName& indicationClassName,
6068 const Array<CIMName>& indicationSubclasses) const
6070 PEG_METHOD_ENTER (TRC_INDICATION_SERVICE,
6071 "IndicationService::_getIndicationProviders");
6073 ProviderClassList provider;
6074 Array<ProviderClassList> indicationProviders;
6075 Array<CIMInstance> providerInstances;
6076 Array<CIMInstance> providerModuleInstances;
6078 CIMPropertyList requiredPropertyList;
6081 // For each indication subclass, get providers
6083 for (Uint32 i = 0, n = indicationSubclasses.size (); i < n; i++)
6085 // Get required property list from filter query (WHERE clause)
6086 // from this indication subclass
6088 requiredPropertyList = _getPropertyList (queryExpression,
6090 indicationSubclasses[i]);
6093 // Get providers that can serve the subscription
6095 providerInstances.clear ();
6096 providerModuleInstances.clear ();
6097 if (_providerRegManager->getIndicationProviders
6099 indicationSubclasses[i],
6100 requiredPropertyList,
6102 providerModuleInstances))
6104 PEGASUS_ASSERT (providerInstances.size () ==
6105 providerModuleInstances.size ());
6107 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
6108 "%u indication provider(s) found for class %s",
6109 providerInstances.size (),
6111 indicationSubclasses[i].getString ().getCString ()));
6114 // Merge into list of ProviderClassList structs
6116 for (Uint32 j = 0, numI = providerInstances.size (); j < numI; j++)
6118 provider.classList.clear ();
6119 Boolean duplicate = false;
6122 // See if indication provider is already in list
6124 for (Uint32 k = 0, numP = indicationProviders.size ();
6125 k < numP && !duplicate; k++)
6127 if ((providerInstances[j].getPath ().identical
6128 (indicationProviders[k].provider.getPath ())) &&
6129 (providerModuleInstances[j].getPath ().identical
6130 (indicationProviders[k].providerModule.getPath ())))
6133 // Indication provider is already in list
6134 // Add subclass to provider's class list
6136 indicationProviders[k].classList.append
6137 (indicationSubclasses[i]);
6145 // Current provider is not yet in list
6146 // Create new list entry
6148 provider.provider = providerInstances[j];
6149 provider.providerModule = providerModuleInstances[j];
6150 provider.classList.append (indicationSubclasses[i]);
6151 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
6152 String remoteInformation;
6153 Boolean isRemote = _cimRepository->isRemoteNameSpace(
6154 nameSpace, remoteInformation);
6155 provider.isRemoteNameSpace = isRemote;
6156 provider.remoteInfo = remoteInformation;
6158 indicationProviders.append(provider);
6160 } // for each indication provider instance
6161 } // if any providers
6162 } // for each indication subclass
6165 return indicationProviders;
6168 CIMPropertyList IndicationService::_getPropertyList(
6169 const QueryExpression& queryExpression,
6170 const CIMNamespaceName& nameSpaceName,
6171 const CIMName& indicationClassName) const
6173 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6174 "IndicationService::_getPropertyList");
6176 CIMPropertyList propertyList;
6178 // Get all the properties referenced in the condition (WHERE clause)
6179 // Note: for CQL, this only returns the properties directly on the
6180 // class name passed in, not any properties on embedded objects.
6184 CIMObjectPath classPath(String::EMPTY,
6186 indicationClassName);
6187 propertyList = queryExpression.getWherePropertyList(classPath);
6189 catch (QueryException& qe)
6191 // The class path was not the FROM class, or a subclass
6192 // of the FROM class.
6193 String exceptionStr = qe.getMessage();
6196 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, exceptionStr);
6199 if (propertyList.isNull())
6202 // Return null property list for all properties
6205 return propertyList;
6209 Array<CIMName> propertyArray;
6211 // Get the property names
6213 propertyArray = propertyList.getPropertyNameArray();
6215 Array<CIMName> indicationClassProperties;
6217 return _checkPropertyList(propertyArray, nameSpaceName,
6218 indicationClassName, indicationClassProperties);
6222 CIMPropertyList IndicationService::_checkPropertyList(
6223 const Array<CIMName>& propertyList,
6224 const CIMNamespaceName& nameSpaceName,
6225 const CIMName& indicationClassName,
6226 Array<CIMName>& indicationClassProperties) const
6228 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6229 "IndicationService::_checkPropertyList");
6232 // Check if list includes all properties in class
6233 // If so, must be set to NULL
6235 CIMClass indicationClass;
6238 // Get the indication class object from the repository
6239 // Specify localOnly=false because superclass properties are needed
6240 // Specify includeQualifiers=false because qualifiers are not needed
6242 indicationClass = _subscriptionRepository->getClass(
6243 nameSpaceName, indicationClassName, false, false, false,
6246 Boolean allProperties = true;
6247 for (Uint32 i = 0; i < indicationClass.getPropertyCount(); i++)
6249 indicationClassProperties.append(
6250 indicationClass.getProperty(i).getName());
6251 if (!ContainsCIMName(propertyList,
6252 indicationClass.getProperty(i).getName()))
6254 allProperties = false;
6261 // Return NULL CIMPropertyList
6264 return CIMPropertyList();
6269 return CIMPropertyList(propertyList);
6273 String IndicationService::_getCondition(
6274 const String& filterQuery) const
6276 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6277 "IndicationService::_getCondition");
6282 // Get condition substring from filter query
6284 if (filterQuery.find(_QUERY_WHERE) != PEG_NOT_FOUND)
6286 condition = filterQuery.subString(filterQuery.find(_QUERY_WHERE) + 6);
6293 void IndicationService::_deleteReferencingSubscriptions(
6294 const CIMNamespaceName& nameSpace,
6295 const CIMName& referenceProperty,
6296 const CIMObjectPath& handler)
6298 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6299 "IndicationService::_deleteReferencingSubscriptions");
6301 Array<CIMInstance> deletedSubscriptions;
6304 // Delete referencing subscriptions from the repository
6306 deletedSubscriptions =
6307 _subscriptionRepository->deleteReferencingSubscriptions(
6308 nameSpace, referenceProperty, handler);
6311 // Send delete request to each provider for each deleted subscription
6313 for (Uint32 i = 0; i < deletedSubscriptions.size(); i++)
6315 Array<ProviderClassList> indicationProviders;
6316 Array<CIMName> indicationSubclasses;
6317 CIMNamespaceName sourceNamespaceName;
6319 indicationProviders = _getDeleteParams(deletedSubscriptions[i],
6320 indicationSubclasses, sourceNamespaceName);
6323 // Send Delete requests
6325 // NOTE: These Delete requests are not associated with a user
6326 // request, so there is no associated authType or userName
6327 // The Creator from the subscription instance is used for userName,
6328 // and authType is not set
6330 CIMInstance instance = deletedSubscriptions[i];
6332 _getCreator(instance, creator);
6335 AcceptLanguageList acceptLangs;
6336 Uint32 propIndex = instance.findProperty(
6337 PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
6338 if (propIndex != PEG_NOT_FOUND)
6340 String acceptLangsString;
6341 instance.getProperty(propIndex).getValue().get(
6343 if (acceptLangsString.size())
6345 acceptLangs = LanguageParser::parseAcceptLanguageHeader(
6349 ContentLanguageList contentLangs;
6350 propIndex = instance.findProperty(
6351 PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
6352 if (propIndex != PEG_NOT_FOUND)
6354 String contentLangsString;
6355 instance.getProperty(propIndex).getValue().get(
6356 contentLangsString);
6357 if (contentLangsString.size())
6359 contentLangs = LanguageParser::parseContentLanguageHeader(
6360 contentLangsString);
6365 _sendAsyncDeleteRequests(
6366 indicationProviders,
6367 sourceNamespaceName,
6368 deletedSubscriptions[i],
6372 indicationSubclasses,
6379 Boolean IndicationService::_isExpired(
6380 const CIMInstance& instance) const
6382 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE, "IndicationService::_isExpired");
6384 Boolean isExpired = true;
6385 Uint64 timeRemaining = 0;
6388 // Get time remaining, if subscription has a duration
6390 if (_getTimeRemaining(instance, timeRemaining))
6392 if (timeRemaining > 0)
6400 // If there is no duration, the subscription has no expiration date
6409 void IndicationService::_deleteExpiredSubscription(
6410 CIMObjectPath& subscription)
6412 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6413 "IndicationService::_deleteExpiredSubscription");
6415 CIMInstance subscriptionInstance;
6418 // Delete instance from repository
6420 subscriptionInstance =
6421 _subscriptionRepository->deleteSubscription(subscription);
6424 // If a valid instance object was returned, the subscription was
6425 // successfully deleted
6427 if (!subscriptionInstance.isUninitialized())
6430 // If subscription was active, send delete requests to providers
6431 // and update hash tables
6433 Uint16 subscriptionState;
6434 CIMValue subscriptionStateValue;
6435 subscriptionStateValue = subscriptionInstance.getProperty(
6436 subscriptionInstance.findProperty(
6437 PEGASUS_PROPERTYNAME_SUBSCRIPTION_STATE)).getValue();
6438 subscriptionStateValue.get(subscriptionState);
6440 if ((subscriptionState == STATE_ENABLED) ||
6441 (subscriptionState == STATE_ENABLEDDEGRADED))
6443 Array<ProviderClassList> indicationProviders;
6444 Array<CIMName> indicationSubclasses;
6445 CIMNamespaceName sourceNamespaceName;
6447 subscriptionInstance.setPath(subscription);
6449 indicationProviders = _getDeleteParams(subscriptionInstance,
6450 indicationSubclasses, sourceNamespaceName);
6453 // Send Delete requests
6455 // NOTE: These Delete requests are not associated with a user
6456 // request, so there is no associated authType or userName
6457 // The Creator from the subscription instance is used for userName,
6458 // and authType is not set
6461 _getCreator(subscriptionInstance, creator);
6464 // Get the language tags that were saved with the subscription
6467 AcceptLanguageList acceptLangs;
6468 Uint32 propIndex = subscriptionInstance.findProperty(
6469 PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS);
6470 if (propIndex != PEG_NOT_FOUND)
6472 String acceptLangsString;
6473 subscriptionInstance.getProperty(propIndex).getValue().get(
6475 if (acceptLangsString.size())
6477 acceptLangs = LanguageParser::parseAcceptLanguageHeader(
6481 ContentLanguageList contentLangs;
6482 propIndex = subscriptionInstance.findProperty(
6483 PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS);
6484 if (propIndex != PEG_NOT_FOUND)
6486 String contentLangsString;
6487 subscriptionInstance.getProperty(propIndex).getValue().get(
6488 contentLangsString);
6489 if (contentLangsString.size())
6491 contentLangs = LanguageParser::parseContentLanguageHeader(
6492 contentLangsString);
6496 subscriptionInstance.setPath(subscription);
6497 _sendAsyncDeleteRequests(indicationProviders,
6498 sourceNamespaceName, subscriptionInstance,
6502 indicationSubclasses,
6509 // The subscription may have already been deleted by another thread
6516 Boolean IndicationService::_getTimeRemaining(
6517 const CIMInstance& instance,
6518 Uint64& timeRemaining) const
6520 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6521 "IndicationService::_getTimeRemaining");
6523 Boolean hasDuration = true;
6527 // Calculate time remaining from subscription
6528 // start time, subscription duration, and current date time
6532 // NOTE: It is assumed that the instance passed to this method is a
6533 // subscription instance, and that the Start Time property exists
6538 // Get Subscription Start Time
6540 CIMValue startTimeValue;
6541 CIMDateTime startTime;
6542 Uint32 startTimeIndex = instance.findProperty(_PROPERTY_STARTTIME);
6543 PEGASUS_ASSERT(startTimeIndex != PEG_NOT_FOUND);
6544 startTimeValue = instance.getProperty(startTimeIndex).getValue();
6545 PEGASUS_ASSERT(!(startTimeValue.isNull()));
6546 startTimeValue.get(startTime);
6549 // Get Subscription Duration
6551 Uint32 durationIndex = instance.findProperty(_PROPERTY_DURATION);
6552 if (durationIndex != PEG_NOT_FOUND)
6554 CIMValue durationValue;
6555 durationValue = instance.getProperty(durationIndex).getValue();
6556 if (durationValue.isNull())
6558 hasDuration = false;
6563 durationValue.get(duration);
6566 // A Start Time set to the _ZERO_INTERVAL_STRING indicates that
6567 // the subscription has not yet been enabled for the first time
6568 // In this case, the time remaining is equal to the Duration
6570 if (startTime.isInterval())
6572 if (startTime.equal(CIMDateTime(_ZERO_INTERVAL_STRING)))
6574 timeRemaining = (Sint64) duration;
6578 // Any interval value other than _ZERO_INTERVAL_STRING
6579 // indicates an invalid Start Time value in the instance
6583 PEGASUS_ASSERT(false);
6590 // Get current date time, and calculate Subscription Time
6593 CIMDateTime currentDateTime = CIMDateTime::getCurrentDateTime();
6595 Sint64 difference = CIMDateTime::getDifference(
6596 startTime, currentDateTime);
6597 PEGASUS_ASSERT(difference >= 0);
6598 if (((Sint64) duration - difference) >= 0)
6600 timeRemaining = (Sint64) duration - difference;
6607 hasDuration = false;
6614 void IndicationService::_setTimeRemaining(
6615 CIMInstance& instance)
6617 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6618 "IndicationService::_setTimeRemaining");
6620 Uint64 timeRemaining = 0;
6621 if (_getTimeRemaining(instance, timeRemaining))
6624 // Add or set the value of the property with the calculated value
6626 if (instance.findProperty(_PROPERTY_TIMEREMAINING) == PEG_NOT_FOUND)
6628 instance.addProperty(
6629 CIMProperty(_PROPERTY_TIMEREMAINING, timeRemaining));
6633 CIMProperty remaining = instance.getProperty(
6634 instance.findProperty(_PROPERTY_TIMEREMAINING));
6635 remaining.setValue(CIMValue(timeRemaining));
6642 void IndicationService::_getCreateParams(
6643 const CIMInstance& subscriptionInstance,
6644 Array<CIMName>& indicationSubclasses,
6645 Array<ProviderClassList>& indicationProviders,
6646 CIMPropertyList& propertyList,
6647 CIMNamespaceName& sourceNameSpace,
6650 String& queryLanguage)
6652 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6653 "IndicationService::_getCreateParams");
6655 CIMName indicationClassName;
6656 condition = String::EMPTY;
6657 query = String::EMPTY;
6658 queryLanguage = String::EMPTY;
6662 // Get filter properties
6664 _subscriptionRepository->getFilterProperties(subscriptionInstance, query,
6665 sourceNameSpace, queryLanguage, filterName);
6668 // Build the query expression from the filter query
6670 QueryExpression queryExpression = _getQueryExpression(query,
6675 // Get indication class name from filter query (FROM clause)
6677 indicationClassName = _getIndicationClassName(queryExpression,
6681 // Get list of subclass names for indication class
6683 indicationSubclasses = _subscriptionRepository->getIndicationSubclasses(
6684 sourceNameSpace, indicationClassName);
6688 // Get indication provider class lists
6690 indicationProviders = _getIndicationProviders(
6693 indicationClassName,
6694 indicationSubclasses);
6696 if (indicationProviders.size() > 0)
6698 condition = _getCondition(query);
6704 void IndicationService::_getCreateParams(
6705 const CIMInstance& subscriptionInstance,
6706 Array<CIMName>& indicationSubclasses,
6707 CIMPropertyList& propertyList,
6708 CIMNamespaceName& sourceNameSpace,
6711 String& queryLanguage)
6713 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6714 "IndicationService::_getCreateParams");
6716 condition = String::EMPTY;
6717 query = String::EMPTY;
6718 queryLanguage = String::EMPTY;
6722 // Get filter properties
6724 _subscriptionRepository->getFilterProperties(subscriptionInstance, query,
6725 sourceNameSpace, queryLanguage, filterName);
6726 QueryExpression queryExpression = _getQueryExpression(
6732 // Get indication class name from filter query (FROM clause)
6734 CIMName indicationClassName =
6735 _getIndicationClassName(queryExpression, sourceNameSpace);
6738 // Get required property list from filter query (WHERE clause)
6740 propertyList = _getPropertyList(queryExpression,
6741 sourceNameSpace, indicationClassName);
6744 // Get condition from filter query (WHERE clause)
6746 condition = _getCondition(query);
6749 // Get list of subclass names for indication class
6751 indicationSubclasses = _subscriptionRepository->getIndicationSubclasses(
6752 sourceNameSpace, indicationClassName);
6757 Array<ProviderClassList> IndicationService::_getDeleteParams(
6758 const CIMInstance& subscriptionInstance,
6759 Array<CIMName>& indicationSubclasses,
6760 CIMNamespaceName& sourceNameSpace)
6762 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6763 "IndicationService::_getDeleteParams");
6766 String queryLanguage;
6768 CIMName indicationClassName;
6769 Array<ProviderClassList> indicationProviders;
6772 // Get filter properties
6774 _subscriptionRepository->getFilterProperties(subscriptionInstance,
6775 filterQuery, sourceNameSpace, queryLanguage, filterName);
6776 QueryExpression queryExpression =
6777 _getQueryExpression(filterQuery, queryLanguage, sourceNameSpace);
6780 // Get indication class name from filter query (FROM clause)
6782 indicationClassName =
6783 _getIndicationClassName(queryExpression, sourceNameSpace);
6786 // Get list of subclass names for indication class
6788 indicationSubclasses = _subscriptionRepository->getIndicationSubclasses(
6789 sourceNameSpace, indicationClassName);
6792 // Get indication provider class lists from Active Subscriptions table
6794 ActiveSubscriptionsTableEntry tableValue;
6795 if (_subscriptionTable->getSubscriptionEntry(
6796 subscriptionInstance.getPath(), tableValue))
6798 indicationProviders = tableValue.providers;
6803 // Subscription not found in Active Subscriptions table
6808 return indicationProviders;
6811 void IndicationService::_sendAsyncCreateRequests(
6812 const Array<ProviderClassList>& indicationProviders,
6813 const CIMNamespaceName& nameSpace,
6814 const CIMPropertyList& propertyList,
6815 const String& condition,
6816 const String& query,
6817 const String& queryLanguage,
6818 const CIMInstance& subscription,
6819 const AcceptLanguageList& acceptLangs,
6820 const ContentLanguageList& contentLangs,
6821 const CIMRequestMessage * origRequest,
6822 const Array<CIMName>& indicationSubclasses,
6823 const String& userName,
6824 const String& authType)
6826 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6827 "IndicationService::_sendAsyncCreateRequests");
6830 Uint16 repeatNotificationPolicy;
6832 // If there are no providers to accept the subscription, just return
6833 if (indicationProviders.size() == 0)
6839 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
6840 _asyncRequestsPending++;
6841 AutoPtr<AtomicInt, DecAtomicInt> counter(&_asyncRequestsPending);
6845 // Get repeat notification policy value from subscription instance
6847 propValue = subscription.getProperty(
6848 subscription.findProperty(
6849 _PROPERTY_REPEATNOTIFICATIONPOLICY)).getValue();
6850 propValue.get(repeatNotificationPolicy);
6852 CIMRequestMessage * aggRequest=0;
6854 if (origRequest == 0)
6857 // Initialize -- no request associated with this create
6864 // Create Instance or Modify Instance
6866 switch (origRequest->getType())
6868 case CIM_CREATE_INSTANCE_REQUEST_MESSAGE:
6870 CIMCreateInstanceRequestMessage * request =
6871 (CIMCreateInstanceRequestMessage *) origRequest;
6872 CIMCreateInstanceRequestMessage * requestCopy =
6873 new CIMCreateInstanceRequestMessage(*request);
6874 aggRequest = requestCopy;
6878 case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
6880 CIMModifyInstanceRequestMessage * request =
6881 (CIMModifyInstanceRequestMessage *) origRequest;
6882 CIMModifyInstanceRequestMessage * requestCopy =
6883 new CIMModifyInstanceRequestMessage(*request);
6884 aggRequest = requestCopy;
6890 PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL1,
6891 "Unexpected origRequest type %s "
6892 "in _sendAsyncCreateRequests",
6893 MessageTypeToString(origRequest->getType())));
6894 PEGASUS_ASSERT(false);
6901 // Create an aggregate object for the create subscription requests
6903 IndicationOperationAggregate * operationAggregate =
6904 new IndicationOperationAggregate(aggRequest, indicationSubclasses);
6905 operationAggregate->setNumberIssued(indicationProviders.size());
6908 // Send Create request to each provider
6910 for (Uint32 i = 0; i < indicationProviders.size(); i++)
6913 // Create the create subscription request
6915 CIMCreateSubscriptionRequestMessage * request =
6916 new CIMCreateSubscriptionRequestMessage(
6917 XmlWriter::getNextMessageId(),
6920 indicationProviders[i].classList,
6922 repeatNotificationPolicy,
6924 QueueIdStack(_providerManager, getQueueId()),
6929 // Store a copy of the request in the operation aggregate instance
6931 CIMCreateSubscriptionRequestMessage * requestCopy =
6932 new CIMCreateSubscriptionRequestMessage(*request);
6933 requestCopy->operationContext.insert(ProviderIdContainer(
6934 indicationProviders[i].providerModule
6935 ,indicationProviders[i].provider
6936 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
6937 ,indicationProviders[i].isRemoteNameSpace
6938 ,indicationProviders[i].remoteInfo
6941 operationAggregate->appendRequest(requestCopy);
6942 request->operationContext.insert(ProviderIdContainer(
6943 indicationProviders[i].providerModule
6944 ,indicationProviders[i].provider
6945 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
6946 ,indicationProviders[i].isRemoteNameSpace
6947 ,indicationProviders[i].remoteInfo
6950 request->operationContext.insert(
6951 SubscriptionInstanceContainer(subscription));
6952 request->operationContext.insert(
6953 SubscriptionFilterConditionContainer(condition,queryLanguage));
6954 request->operationContext.insert(
6955 SubscriptionFilterQueryContainer(query,queryLanguage,nameSpace));
6956 request->operationContext.insert(IdentityContainer(userName));
6957 request->operationContext.set(
6958 ContentLanguageListContainer(contentLangs));
6959 request->operationContext.set(AcceptLanguageListContainer(acceptLangs));
6961 AsyncOpNode * op = this->get_op();
6963 AsyncLegacyOperationStart * async_req =
6964 new AsyncLegacyOperationStart(
6972 IndicationService::_aggregationCallBack,
6974 operationAggregate);
6976 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
6977 // Release AutomicInt if atleast one request is sent for aggregation.
6985 Array<ProviderClassList> IndicationService::_sendWaitCreateRequests(
6986 const Array<ProviderClassList>& indicationProviders,
6987 const CIMNamespaceName& nameSpace,
6988 const CIMPropertyList& propertyList,
6989 const String& condition,
6990 const String& query,
6991 const String& queryLanguage,
6992 const CIMInstance& subscription,
6993 const AcceptLanguageList& acceptLangs,
6994 const ContentLanguageList& contentLangs,
6995 const String& userName,
6996 const String& authType)
6998 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
6999 "IndicationService::_sendWaitCreateRequests");
7002 Uint16 repeatNotificationPolicy;
7003 Array<ProviderClassList> acceptedProviders;
7004 acceptedProviders.clear();
7006 // If there are no providers to accept the subscription, just return
7007 if (indicationProviders.size() == 0)
7010 return acceptedProviders;
7014 // Get repeat notification policy value from subscription instance
7016 propValue = subscription.getProperty(
7017 subscription.findProperty(
7018 _PROPERTY_REPEATNOTIFICATIONPOLICY)).getValue();
7019 propValue.get(repeatNotificationPolicy);
7022 // Send Create request to each provider
7024 for (Uint32 i = 0; i < indicationProviders.size(); i++)
7027 // Create the create subscription request
7029 CIMCreateSubscriptionRequestMessage * request =
7030 new CIMCreateSubscriptionRequestMessage(
7031 XmlWriter::getNextMessageId(),
7034 indicationProviders[i].classList,
7036 repeatNotificationPolicy,
7038 QueueIdStack(_providerManager, getQueueId()),
7043 // Set operation context
7045 request->operationContext.insert(ProviderIdContainer(
7046 indicationProviders[i].providerModule
7047 ,indicationProviders[i].provider
7048 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
7049 ,indicationProviders[i].isRemoteNameSpace
7050 ,indicationProviders[i].remoteInfo
7053 request->operationContext.insert(
7054 SubscriptionInstanceContainer(subscription));
7055 request->operationContext.insert(
7056 SubscriptionFilterConditionContainer(condition,queryLanguage));
7057 request->operationContext.insert(
7058 SubscriptionFilterQueryContainer(query,queryLanguage,nameSpace));
7059 request->operationContext.insert(IdentityContainer(userName));
7060 request->operationContext.set(
7061 ContentLanguageListContainer(contentLangs));
7062 request->operationContext.set(AcceptLanguageListContainer(acceptLangs));
7064 AsyncLegacyOperationStart * asyncRequest =
7065 new AsyncLegacyOperationStart(
7070 AsyncReply * asyncReply = SendWait(asyncRequest);
7072 CIMCreateSubscriptionResponseMessage * response =
7073 reinterpret_cast<CIMCreateSubscriptionResponseMessage *>(
7074 (static_cast<AsyncLegacyOperationResult *>(
7075 asyncReply))->get_result());
7077 if (response->cimException.getCode() == CIM_ERR_SUCCESS)
7079 acceptedProviders.append(indicationProviders[i]);
7080 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
7081 _providerIndicationCountTable.insertEntry(
7082 indicationProviders[i].provider);
7088 // Provider rejected the subscription
7090 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
7091 "Provider (%s) rejected create subscription: %s",
7092 (const char*)indicationProviders[i].provider.getPath()
7093 .toString().getCString(),
7094 (const char*)response->cimException.getMessage().getCString()));
7098 delete asyncRequest;
7100 } // for each indication provider
7103 return acceptedProviders;
7106 void IndicationService::_sendWaitModifyRequests(
7107 const Array<ProviderClassList>& indicationProviders,
7108 const CIMNamespaceName& nameSpace,
7109 const CIMPropertyList& propertyList,
7110 const String& condition,
7111 const String& query,
7112 const String& queryLanguage,
7113 const CIMInstance& subscription,
7114 const AcceptLanguageList& acceptLangs,
7115 const ContentLanguageList& contentLangs,
7116 const String& userName,
7117 const String& authType)
7119 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7120 "IndicationService::_sendWaitModifyRequests");
7123 Uint16 repeatNotificationPolicy;
7125 // If there are no providers to accept the subscription update, just return
7126 if (indicationProviders.size() == 0)
7133 // Get repeat notification policy value from subscription instance
7135 propValue = subscription.getProperty(
7136 subscription.findProperty(
7137 _PROPERTY_REPEATNOTIFICATIONPOLICY)).getValue();
7138 propValue.get(repeatNotificationPolicy);
7141 // Send Modify request to each provider
7143 for (Uint32 i = 0; i < indicationProviders.size(); i++)
7145 CIMModifySubscriptionRequestMessage * request =
7146 new CIMModifySubscriptionRequestMessage(
7147 XmlWriter::getNextMessageId(),
7150 indicationProviders[i].classList,
7152 repeatNotificationPolicy,
7154 QueueIdStack(_providerManager, getQueueId()),
7159 // Set operation context
7161 request->operationContext.insert(ProviderIdContainer(
7162 indicationProviders[i].providerModule
7163 ,indicationProviders[i].provider
7164 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
7165 ,indicationProviders[i].isRemoteNameSpace
7166 ,indicationProviders[i].remoteInfo
7169 request->operationContext.insert(
7170 SubscriptionInstanceContainer(subscription));
7171 request->operationContext.insert(
7172 SubscriptionFilterConditionContainer(condition,queryLanguage));
7173 request->operationContext.insert(
7174 SubscriptionFilterQueryContainer(query,queryLanguage,nameSpace));
7175 request->operationContext.insert(IdentityContainer(userName));
7176 request->operationContext.set(
7177 ContentLanguageListContainer(contentLangs));
7178 request->operationContext.set(AcceptLanguageListContainer(acceptLangs));
7180 AsyncLegacyOperationStart * asyncRequest =
7181 new AsyncLegacyOperationStart(
7186 AsyncReply * asyncReply = SendWait(asyncRequest);
7188 CIMModifySubscriptionResponseMessage * response =
7189 reinterpret_cast<CIMModifySubscriptionResponseMessage *>(
7190 (static_cast<AsyncLegacyOperationResult *>(
7191 asyncReply))->get_result());
7193 if (!(response->cimException.getCode() == CIM_ERR_SUCCESS))
7196 // Provider rejected the subscription
7198 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
7199 "Provider (%s) rejected modify subscription: %s",
7200 (const char*)indicationProviders[i].provider.getPath()
7201 .toString().getCString(),
7202 (const char*)response->cimException.getMessage().getCString()));
7206 delete asyncRequest;
7208 } // for each indication provider
7213 void IndicationService::_sendAsyncDeleteRequests(
7214 const Array<ProviderClassList>& indicationProviders,
7215 const CIMNamespaceName& nameSpace,
7216 const CIMInstance& subscription,
7217 const AcceptLanguageList& acceptLangs,
7218 const ContentLanguageList& contentLangs,
7219 const CIMRequestMessage * origRequest,
7220 const Array<CIMName>& indicationSubclasses,
7221 const String& userName,
7222 const String& authType)
7224 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7225 "IndicationService::_sendAsyncDeleteRequests");
7227 // If there are no providers to delete the subscription, just return
7228 if (indicationProviders.size() == 0)
7234 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
7235 _asyncRequestsPending++;
7236 AutoPtr<AtomicInt, DecAtomicInt> counter(&_asyncRequestsPending);
7240 // Update subscription hash tables
7242 _subscriptionTable->removeSubscription(
7244 indicationSubclasses,
7246 indicationProviders);
7248 CIMRequestMessage * aggRequest = 0;
7250 if (origRequest == 0)
7253 // Delete a referencing or expired subscription -- no request
7254 // associated with this delete
7261 // Delete Instance or Modify Instance
7263 switch (origRequest->getType())
7265 case CIM_DELETE_INSTANCE_REQUEST_MESSAGE:
7267 CIMDeleteInstanceRequestMessage * request =
7268 (CIMDeleteInstanceRequestMessage *) origRequest;
7269 CIMDeleteInstanceRequestMessage * requestCopy =
7270 new CIMDeleteInstanceRequestMessage(*request);
7271 aggRequest = requestCopy;
7275 case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
7277 CIMModifyInstanceRequestMessage * request =
7278 (CIMModifyInstanceRequestMessage *) origRequest;
7279 CIMModifyInstanceRequestMessage * requestCopy =
7280 new CIMModifyInstanceRequestMessage(*request);
7281 aggRequest = requestCopy;
7287 PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL1,
7288 "Unexpected origRequest type %s "
7289 "in _sendAsyncDeleteRequests",
7290 MessageTypeToString(origRequest->getType())));
7291 PEGASUS_ASSERT(false);
7298 // Create an aggregate object for the delete subscription requests
7300 IndicationOperationAggregate * operationAggregate =
7301 new IndicationOperationAggregate(aggRequest, indicationSubclasses);
7302 operationAggregate->setNumberIssued(indicationProviders.size());
7305 // Send Delete request to each provider
7307 for (Uint32 i = 0; i < indicationProviders.size(); i++)
7309 CIMDeleteSubscriptionRequestMessage * request =
7310 new CIMDeleteSubscriptionRequestMessage(
7311 XmlWriter::getNextMessageId(),
7314 indicationProviders[i].classList,
7315 QueueIdStack(_providerManager, getQueueId()),
7320 // Store a copy of the request in the operation aggregate instance
7322 CIMDeleteSubscriptionRequestMessage * requestCopy =
7323 new CIMDeleteSubscriptionRequestMessage(*request);
7324 requestCopy->operationContext.insert(ProviderIdContainer(
7325 indicationProviders[i].providerModule
7326 ,indicationProviders[i].provider
7327 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
7328 ,indicationProviders[i].isRemoteNameSpace
7329 ,indicationProviders[i].remoteInfo
7332 operationAggregate->appendRequest(requestCopy);
7333 request->operationContext.insert(ProviderIdContainer(
7334 indicationProviders[i].providerModule
7335 ,indicationProviders[i].provider
7336 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
7337 ,indicationProviders[i].isRemoteNameSpace
7338 ,indicationProviders[i].remoteInfo
7342 request->operationContext.insert(
7343 SubscriptionInstanceContainer(subscription));
7344 request->operationContext.insert(IdentityContainer(userName));
7345 request->operationContext.set(
7346 ContentLanguageListContainer(contentLangs));
7347 request->operationContext.set(AcceptLanguageListContainer(acceptLangs));
7349 AsyncOpNode * op = this->get_op();
7351 AsyncLegacyOperationStart * async_req =
7352 new AsyncLegacyOperationStart(
7360 IndicationService::_aggregationCallBack,
7362 operationAggregate);
7364 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
7365 // Release AutomicInt if atleast one request is sent for aggregation.
7373 void IndicationService::_sendWaitDeleteRequests(
7374 const Array<ProviderClassList>& indicationProviders,
7375 const CIMNamespaceName& nameSpace,
7376 const CIMInstance& subscription,
7377 const AcceptLanguageList& acceptLangs,
7378 const ContentLanguageList& contentLangs,
7379 const String& userName,
7380 const String& authType)
7382 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7383 "IndicationService::_sendWaitDeleteRequests");
7385 // If there are no providers to delete the subscription, just return
7386 if (indicationProviders.size() == 0)
7393 // Send Delete request to each provider
7395 for (Uint32 i = 0; i < indicationProviders.size(); i++)
7397 CIMDeleteSubscriptionRequestMessage * request =
7398 new CIMDeleteSubscriptionRequestMessage(
7399 XmlWriter::getNextMessageId(),
7402 indicationProviders[i].classList,
7403 QueueIdStack(_providerManager, getQueueId()),
7408 // Set operation context
7410 request->operationContext.insert(ProviderIdContainer(
7411 indicationProviders[i].providerModule
7412 ,indicationProviders[i].provider
7413 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
7414 ,indicationProviders[i].isRemoteNameSpace
7415 ,indicationProviders[i].remoteInfo
7418 request->operationContext.insert(
7419 SubscriptionInstanceContainer(subscription));
7420 request->operationContext.insert(IdentityContainer(userName));
7421 request->operationContext.set(
7422 ContentLanguageListContainer(contentLangs));
7423 request->operationContext.set(AcceptLanguageListContainer(acceptLangs));
7425 AsyncLegacyOperationStart * asyncRequest =
7426 new AsyncLegacyOperationStart(
7431 AsyncReply * asyncReply = SendWait(asyncRequest);
7433 CIMDeleteSubscriptionResponseMessage * response =
7434 reinterpret_cast<CIMDeleteSubscriptionResponseMessage *>(
7435 (static_cast<AsyncLegacyOperationResult *>(
7436 asyncReply))->get_result());
7438 if (!(response->cimException.getCode() == CIM_ERR_SUCCESS))
7441 // Provider rejected the subscription
7443 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
7444 "Provider (%s) rejected delete subscription: %s",
7445 (const char*)indicationProviders[i].provider.getPath()
7446 .toString().getCString(),
7447 (const char*)response->cimException.getMessage().getCString()));
7451 delete asyncRequest;
7453 } // for each indication provider
7458 void IndicationService::_aggregationCallBack(
7461 void * userParameter)
7463 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7464 "IndicationService::_aggregationCallBack");
7466 IndicationService * service = static_cast<IndicationService *>(q);
7468 AsyncRequest * asyncRequest =
7469 static_cast<AsyncRequest *>(op->removeRequest());
7470 AsyncReply * asyncReply = static_cast<AsyncReply *>(op->removeResponse());
7472 IndicationOperationAggregate * operationAggregate =
7473 reinterpret_cast<IndicationOperationAggregate *>(userParameter);
7474 PEGASUS_ASSERT(operationAggregate != 0);
7476 CIMResponseMessage * response = 0;
7477 MessageType msgType = asyncReply->getType();
7478 PEGASUS_ASSERT((msgType == ASYNC_ASYNC_LEGACY_OP_RESULT) ||
7479 (msgType == ASYNC_ASYNC_MODULE_OP_RESULT));
7481 if (msgType == ASYNC_ASYNC_LEGACY_OP_RESULT)
7483 response = reinterpret_cast<CIMResponseMessage *>(
7484 (static_cast<AsyncLegacyOperationResult *>(
7485 asyncReply))->get_result());
7487 else if (msgType == ASYNC_ASYNC_MODULE_OP_RESULT)
7489 response = reinterpret_cast<CIMResponseMessage *>(
7490 (static_cast<AsyncModuleOperationResult *>(
7491 asyncReply))->get_result());
7494 PEGASUS_ASSERT(response != 0);
7496 delete asyncRequest;
7498 service->return_op(op);
7500 Boolean isDoneAggregation = operationAggregate->appendResponse(response);
7501 if (isDoneAggregation)
7503 service->_handleOperationResponseAggregation(operationAggregate);
7504 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
7505 service->_asyncRequestsPending--;
7512 void IndicationService::_handleOperationResponseAggregation(
7513 IndicationOperationAggregate * operationAggregate)
7515 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7516 "IndicationService::_handleOperationResponseAggregation");
7518 switch (operationAggregate->getRequest(0)->getType())
7520 case CIM_CREATE_SUBSCRIPTION_REQUEST_MESSAGE:
7522 _handleCreateResponseAggregation(operationAggregate);
7526 case CIM_DELETE_SUBSCRIPTION_REQUEST_MESSAGE:
7528 _handleDeleteResponseAggregation(operationAggregate);
7534 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
7535 "Unexpected request type %s "
7536 "in _handleOperationResponseAggregation",
7537 MessageTypeToString(
7538 operationAggregate->getRequest(0)->getType())));
7539 PEGASUS_ASSERT(false);
7545 // Requests and responses are deleted in destructor
7547 delete operationAggregate;
7552 void IndicationService::_handleCreateResponseAggregation(
7553 IndicationOperationAggregate * operationAggregate)
7555 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7556 "IndicationService::_handleCreateResponseAggregation");
7558 Array<ProviderClassList> acceptedProviders;
7559 CIMObjectPath instanceRef;
7560 CIMException cimException;
7563 // Examine provider responses
7565 acceptedProviders.clear();
7566 for (Uint32 i = 0; i < operationAggregate->getNumberResponses(); i++)
7569 // Find provider from which response was sent
7571 CIMResponseMessage * response = operationAggregate->getResponse(i);
7572 ProviderClassList provider = operationAggregate->findProvider(
7573 response->messageId);
7574 if (response->cimException.getCode() == CIM_ERR_SUCCESS)
7577 // If response is SUCCESS, provider accepted the subscription
7578 // Add provider to list of providers that accepted subscription
7580 acceptedProviders.append(provider);
7581 #ifdef PEGASUS_ENABLE_INDICATION_COUNT
7582 _providerIndicationCountTable.insertEntry(provider.provider);
7587 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
7588 "Provider (%s) rejected create subscription: %s",
7590 provider.provider.getPath().toString().getCString(),
7591 (const char*)response->cimException.getMessage().getCString()));
7595 CIMCreateSubscriptionRequestMessage * request =
7596 (CIMCreateSubscriptionRequestMessage *)
7597 operationAggregate->getRequest(0);
7599 if (operationAggregate->getOrigType() ==
7600 CIM_CREATE_INSTANCE_REQUEST_MESSAGE)
7602 instanceRef = request->subscriptionInstance.getPath();
7606 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
7607 if (operationAggregate->getOrigRequest() == 0)
7610 // There is no request associated with the aggregation object.
7611 // This request must have been sent during the indication
7612 // service initialization because of timeout specified.
7614 _updateAcceptedSubscription(
7615 request->subscriptionInstance,
7617 operationAggregate->getIndicationSubclasses(),
7618 request->nameSpace);
7622 if (acceptedProviders.size() == 0)
7625 // No providers accepted this subscription
7627 if (operationAggregate->requiresResponse())
7630 // For Create Instance or Modify Instance request, set CIM
7631 // exception for response
7633 cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
7635 "IndicationService.IndicationService._MSG_NOT_ACCEPTED",
7636 "No providers accepted the subscription."));
7642 // At least one provider accepted the subscription
7644 if (operationAggregate->getOrigType() ==
7645 CIM_CREATE_INSTANCE_REQUEST_MESSAGE)
7648 // Create Instance -- create the instance in the repository
7650 CIMCreateInstanceRequestMessage * origRequest =
7651 (CIMCreateInstanceRequestMessage *)
7652 operationAggregate->getOrigRequest();
7654 CIMInstance instance;
7657 instanceRef = _subscriptionRepository->createInstance(
7658 request->subscriptionInstance, origRequest->nameSpace,
7659 ((IdentityContainer)origRequest->operationContext.get
7660 (IdentityContainer::NAME)).getUserName(),
7661 ((AcceptLanguageListContainer)request->operationContext.get
7662 (AcceptLanguageListContainer::NAME)).getLanguages(),
7663 ((ContentLanguageListContainer)request->operationContext.get
7664 (ContentLanguageListContainer::NAME)).getLanguages(),
7666 instanceRef.setNameSpace(
7667 request->subscriptionInstance.getPath().getNameSpace());
7668 instance = _subscriptionRepository->getInstance(
7669 origRequest->nameSpace, instanceRef);
7670 instance.setPath(instanceRef);
7672 catch (CIMException& exception)
7674 cimException = exception;
7676 catch (Exception& exception)
7678 cimException = PEGASUS_CIM_EXCEPTION(
7679 CIM_ERR_FAILED, exception.getMessage());
7682 if (cimException.getCode() == CIM_ERR_SUCCESS)
7685 // Insert entries into the subscription hash tables
7687 _subscriptionTable->insertSubscription(
7690 operationAggregate->getIndicationSubclasses(),
7691 request->nameSpace);
7695 else // CIM_MODIFY_INSTANCE_REQUEST_MESSAGE
7698 PEGASUS_ASSERT(operationAggregate->getOrigType() ==
7699 CIM_MODIFY_INSTANCE_REQUEST_MESSAGE);
7701 // Insert entries into the subscription hash tables
7703 _subscriptionTable->insertSubscription(
7704 request->subscriptionInstance,
7706 operationAggregate->getIndicationSubclasses(),
7707 request->nameSpace);
7711 // If subscription could not be created, cancel create subscription request
7712 // or commit create subscription request if subscription was created.
7713 if (instanceRef.getKeyBindings().size())
7715 if (cimException.getCode() != CIM_ERR_SUCCESS)
7717 _subscriptionRepository->cancelCreateSubscription(instanceRef);
7721 _subscriptionRepository->commitCreateSubscription(instanceRef);
7726 // For Create Instance or Modify Instance request, send response
7728 if (operationAggregate->requiresResponse())
7730 if (operationAggregate->getOrigType() ==
7731 CIM_CREATE_INSTANCE_REQUEST_MESSAGE)
7733 // Note: don't need to set Content-language in the response
7734 CIMCreateInstanceResponseMessage* response =
7735 dynamic_cast<CIMCreateInstanceResponseMessage*>(
7736 operationAggregate->getOrigRequest()->buildResponse());
7737 PEGASUS_ASSERT(response != 0);
7738 response->cimException = cimException;
7739 response->instanceName = instanceRef;
7740 _enqueueResponse(operationAggregate->getOrigRequest(), response);
7743 else // CIM_MODIFY_INSTANCE_REQUEST_MESSAGE
7745 PEGASUS_ASSERT(operationAggregate->getOrigType () ==
7746 CIM_MODIFY_INSTANCE_REQUEST_MESSAGE);
7748 // Note: don't need to set Content-language in the response
7750 CIMResponseMessage * response =
7751 operationAggregate->getOrigRequest()->buildResponse();
7752 response->cimException = cimException;
7753 _enqueueResponse(operationAggregate->getOrigRequest(), response);
7760 void IndicationService::_handleDeleteResponseAggregation(
7761 IndicationOperationAggregate * operationAggregate)
7763 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7764 "IndicationService::_handleDeleteResponseAggregation");
7766 CIMException cimException;
7767 Array<ProviderClassList> checkProviders;
7770 // Examine provider responses
7772 for (Uint32 i = 0; i < operationAggregate->getNumberResponses(); i++)
7775 // Find provider from which response was sent and add to list
7777 CIMResponseMessage * response = operationAggregate->getResponse(i);
7778 ProviderClassList provider = operationAggregate->findProvider(
7779 response->messageId);
7780 checkProviders.append(provider);
7783 // If response is not SUCCESS, provider rejected the delete
7785 if (response->cimException.getCode() != CIM_ERR_SUCCESS)
7788 // Log a trace message
7790 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL2,
7791 "Provider (%s) rejected delete subscription: %s",
7793 provider.provider.getPath().toString().getCString(),
7794 (const char*)response->cimException.getMessage().getCString()));
7799 // For Delete Instance or Modify Instance request, send response
7801 if (operationAggregate->requiresResponse())
7803 CIMResponseMessage * response;
7804 if (operationAggregate->getOrigType() ==
7805 CIM_DELETE_INSTANCE_REQUEST_MESSAGE)
7808 // Note: don't need to set Content-language in the response
7809 response = operationAggregate->getOrigRequest()->buildResponse();
7810 response->cimException = cimException;
7813 else // CIM_MODIFY_INSTANCE_REQUEST_MESSAGE
7815 PEGASUS_ASSERT(operationAggregate->getOrigType() ==
7816 CIM_MODIFY_INSTANCE_REQUEST_MESSAGE);
7818 // Note: don't need to set Content-language in the response
7819 response = operationAggregate->getOrigRequest()->buildResponse();
7820 response->cimException = cimException;
7823 _enqueueResponse(operationAggregate->getOrigRequest(), response);
7829 CIMInstance IndicationService::_createAlertInstance(
7830 const CIMName& alertClassName,
7831 const Array<CIMInstance>& subscriptions)
7833 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7834 "IndicationService::_createAlertInstance");
7836 CIMInstance indicationInstance(alertClassName);
7839 // Add property values for all required properties of CIM_AlertIndication
7841 indicationInstance.addProperty(
7842 CIMProperty(_PROPERTY_ALERTTYPE, CIMValue((Uint16) _TYPE_OTHER)));
7844 // ATTN: what should Other Alert Type value be??
7845 // Currently using Alert class name
7847 indicationInstance.addProperty(
7848 CIMProperty(_PROPERTY_OTHERALERTTYPE, alertClassName.getString()));
7850 indicationInstance.addProperty(
7851 CIMProperty(_PROPERTY_PERCEIVEDSEVERITY,
7852 CIMValue((Uint16) _SEVERITY_WARNING)));
7854 // ATTN: what should Probable Cause value be??
7855 // Currently using Unknown
7857 indicationInstance.addProperty(
7858 CIMProperty(_PROPERTY_PROBABLECAUSE,
7859 CIMValue((Uint16) _CAUSE_UNKNOWN)));
7862 // Add properties specific to each alert class
7863 // ATTN: update once alert classes have been defined
7864 // NB: for _CLASS_NO_PROVIDER_ALERT and _CLASS_PROVIDER_TERMINATED_ALERT,
7865 // one of the properties will be a list of affected subscriptions
7866 // It is for that reason that subscriptions is passed in as a parameter
7868 if (alertClassName.equal(_CLASS_CIMOM_SHUTDOWN_ALERT))
7871 else if (alertClassName.equal(_CLASS_NO_PROVIDER_ALERT))
7874 else if (alertClassName.equal(_CLASS_PROVIDER_TERMINATED_ALERT))
7879 return indicationInstance;
7884 void IndicationService::_sendAlertsCallBack(AsyncOpNode *op,
7888 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7889 "IndicationService::_sendAlertsCallBack");
7891 IndicationService *service =
7892 static_cast<IndicationService *>(q);
7893 CIMInstance *_handler =
7894 reinterpret_cast<CIMInstance *>(parm);
7896 AsyncRequest *asyncRequest = static_cast<AsyncRequest *>(op->get_request());
7897 AsyncReply *asyncReply = static_cast<AsyncReply *>(op->get_response());
7898 CIMRequestMessage *request = reinterpret_cast<CIMRequestMessage *>(
7899 (static_cast<AsyncLegacyOperationStart *>(asyncRequest))->get_action());
7901 CIMHandleIndicationResponseMessage* response =
7902 reinterpret_cast<CIMHandleIndicationResponseMessage *>(
7903 (static_cast<AsyncLegacyOperationResult *>(
7904 asyncReply))->get_result());
7906 PEGASUS_ASSERT(response != 0);
7907 if (response->cimException.getCode() == CIM_ERR_SUCCESS)
7915 // ATTN: Check for return value indicating invalid queue ID
7916 // If received, need to find Handler Manager Service queue ID
7920 // << Mon Jul 15 09:59:16 2002 mdd >> handler is allocated as an element in
7921 // an array, don't delete here.
7925 delete asyncRequest;
7928 service->return_op(op);
7934 void IndicationService::_sendAlerts(
7935 const Array<CIMInstance>& subscriptions,
7936 /* const */ CIMInstance& alertInstance)
7938 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE, "IndicationService::_sendAlerts");
7940 CIMInstance current;
7942 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
7943 "Sending alert: %s",
7944 (const char*)alertInstance.getClassName().getString().getCString()));
7947 // Get list of unique handler instances for all subscriptions in list
7949 for (Uint32 i = 0; i < subscriptions.size(); i++)
7951 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
7952 "Alert subscription: %s",
7953 (const char*)subscriptions[i].getPath().toString().getCString()));
7956 // Get handler instance
7958 current = _subscriptionRepository->getHandler(subscriptions[i]);
7960 // ATTN: For the handlers which do not need subscription instance
7961 // need to check duplicate alter
7964 // Send handle indication request to the handler
7966 CIMHandleIndicationRequestMessage * handler_request =
7967 new CIMHandleIndicationRequestMessage(
7968 XmlWriter::getNextMessageId(),
7969 current.getPath().getNameSpace(),
7973 QueueIdStack(_handlerService, getQueueId()));
7975 AsyncOpNode* op = this->get_op();
7977 AsyncLegacyOperationStart *async_req =
7978 new AsyncLegacyOperationStart(
7986 IndicationService::_sendAlertsCallBack,
7996 void IndicationService::sendSubscriptionInitComplete()
7998 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
7999 "IndicationService::sendSubscriptionInitComplete");
8001 if (_enabledState == _ENABLEDSTATE_DISABLED)
8007 // Create the Subscription Init Complete request
8009 CIMSubscriptionInitCompleteRequestMessage * request =
8010 new CIMSubscriptionInitCompleteRequestMessage(
8011 XmlWriter::getNextMessageId(),
8012 QueueIdStack(_providerManager, getQueueId()));
8015 // Send Subscription Initialization Complete request to provider manager
8016 // Provider Manager calls providers' enableIndications method
8018 AsyncLegacyOperationStart * asyncRequest =
8019 new AsyncLegacyOperationStart(
8024 AutoPtr<AsyncReply> asyncReply(SendWait(asyncRequest));
8026 // Note: the response does not contain interesting data
8028 delete asyncRequest;
8033 Boolean IndicationService::_getCreator(
8034 const CIMInstance& instance,
8035 String& creator) const
8037 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE, "IndicationService::_getCreator");
8039 Uint32 creatorIndex = instance.findProperty(
8040 PEGASUS_PROPERTYNAME_INDSUB_CREATOR);
8041 if (creatorIndex != PEG_NOT_FOUND)
8043 CIMValue creatorValue = instance.getProperty(creatorIndex).getValue();
8044 if (creatorValue.isNull())
8046 PEG_TRACE_CSTRING(TRC_INDICATION_SERVICE,Tracer::LEVEL1,
8047 "Null Subscription Creator property value");
8050 // This is a corrupted/invalid instance
8055 else if ((creatorValue.getType() != CIMTYPE_STRING) ||
8056 (creatorValue.isArray()))
8058 PEG_TRACE((TRC_INDICATION_SERVICE,Tracer::LEVEL1,
8059 "Subscription Creator property value of incorrect type:%s %s",
8060 (creatorValue.isArray()) ? " array of" : " ",
8061 cimTypeToString(creatorValue.getType())));
8064 // This is a corrupted/invalid instance
8071 creatorValue.get(creator);
8076 PEG_TRACE_CSTRING(TRC_INDICATION_SERVICE,Tracer::LEVEL1,
8077 "Missing Subscription Creator property");
8080 // This is a corrupted/invalid instance
8090 Boolean IndicationService::_validateState(
8091 const Uint16 state) const
8094 // Validate the value
8096 if (!Contains(_validStates, state))
8099 // This is a corrupted/invalid instance
8107 void IndicationService::_updatePropertyList(
8109 CIMPropertyList& propertyList,
8110 Boolean& setTimeRemaining,
8111 Boolean& startTimeAdded,
8112 Boolean& durationAdded)
8114 PEG_METHOD_ENTER( TRC_INDICATION_SERVICE,
8115 "IndicationService::_updatePropertyList");
8118 // A null propertyList means all properties
8119 // If the class is Subscription, that includes the Time Remaining property
8121 if (className.equal(PEGASUS_CLASSNAME_INDSUBSCRIPTION) ||
8122 className.equal(PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))
8124 setTimeRemaining = true;
8128 setTimeRemaining = false;
8130 startTimeAdded = false;
8131 durationAdded = false;
8132 if (!propertyList.isNull())
8134 setTimeRemaining = false;
8135 Array<CIMName> properties = propertyList.getPropertyNameArray();
8138 // Add Creator to property list
8140 if (!ContainsCIMName(properties,
8141 PEGASUS_PROPERTYNAME_INDSUB_CREATOR))
8143 properties.append(PEGASUS_PROPERTYNAME_INDSUB_CREATOR);
8146 if (className.equal(PEGASUS_CLASSNAME_INDHANDLER_CIMXML) ||
8147 className.equal(PEGASUS_CLASSNAME_LSTNRDST_CIMXML))
8149 properties.append(PEGASUS_PROPERTYNAME_LSTNRDST_CREATIONTIME);
8153 // If a Subscription and Time Remaining is requested,
8154 // Ensure Subscription Duration and Start Time are in property list
8156 if (className.equal(PEGASUS_CLASSNAME_INDSUBSCRIPTION) ||
8157 className.equal(PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))
8159 if (ContainsCIMName(properties, _PROPERTY_TIMEREMAINING))
8161 setTimeRemaining = true;
8162 if (!ContainsCIMName(properties, _PROPERTY_STARTTIME))
8164 properties.append(_PROPERTY_STARTTIME);
8165 startTimeAdded = true;
8167 if (!ContainsCIMName(properties, _PROPERTY_DURATION))
8169 properties.append(_PROPERTY_DURATION);
8170 durationAdded = true;
8174 propertyList.clear();
8175 propertyList.set(properties);
8181 String IndicationService::_getSubscriptionLogString(CIMInstance& subscription)
8184 // Get Subscription Filter namespace and Name, and Handler namespace and
8188 CIMValue filterValue;
8189 CIMObjectPath filterPath;
8190 CIMNamespaceName filterNS;
8191 Array<CIMKeyBinding> filterKeyBindings;
8192 CIMValue handlerValue;
8193 CIMObjectPath handlerPath;
8194 CIMNamespaceName handlerNS;
8195 Array<CIMKeyBinding> handlerKeyBindings;
8196 filterValue = subscription.getProperty(subscription.findProperty(
8197 PEGASUS_PROPERTYNAME_FILTER)).getValue();
8198 filterValue.get(filterPath);
8201 // Get Filter namespace - if not set in Filter reference property
8202 // value, namespace is the namespace of the subscription
8204 filterNS = filterPath.getNameSpace();
8205 if (filterNS.isNull())
8207 filterNS = subscription.getPath().getNameSpace();
8209 logString.append(filterNS.getString());
8210 logString.append(" ");
8211 filterKeyBindings = filterPath.getKeyBindings();
8212 for (Uint32 i = 0; i < filterKeyBindings.size(); i++)
8214 if (filterKeyBindings[i].getName().equal(PEGASUS_PROPERTYNAME_NAME))
8216 logString.append(filterKeyBindings[i].getValue());
8217 logString.append(", ");
8221 handlerValue = subscription.getProperty(
8222 subscription.findProperty(PEGASUS_PROPERTYNAME_HANDLER)).getValue();
8223 handlerValue.get(handlerPath);
8226 // Get Handler namespace - if not set in Handler reference property
8227 // value, namespace is the namespace of the subscription
8229 handlerNS = handlerPath.getNameSpace();
8230 if (handlerNS.isNull())
8232 handlerNS = subscription.getPath().getNameSpace();
8234 logString.append(handlerNS.getString());
8235 logString.append(" ");
8236 handlerKeyBindings = handlerPath.getKeyBindings();
8237 for (Uint32 j = 0; j < handlerKeyBindings.size(); j++)
8239 if (handlerKeyBindings[j].getName().equal(PEGASUS_PROPERTYNAME_NAME))
8241 logString.append(handlerKeyBindings[j].getValue());
8249 String IndicationService::getProviderLogString(CIMInstance& provider)
8253 logString = provider.getProperty(
8254 provider.findProperty(PEGASUS_PROPERTYNAME_NAME)).getValue().toString();
8259 CIMClass IndicationService::_getIndicationClass(
8260 const CIMInstance& subscriptionInstance)
8262 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
8263 "IndicationService::_getIndicationClass");
8265 CIMNamespaceName sourceNameSpace;
8267 String queryLanguage;
8268 CIMName indicationClassName;
8269 CIMClass indicationClass;
8272 // Get filter properties
8273 _subscriptionRepository->getFilterProperties(subscriptionInstance, query,
8274 sourceNameSpace, queryLanguage, filterName);
8276 // Build the query expression from the filter query
8277 QueryExpression queryExpression = _getQueryExpression(query,
8281 // Get indication class name from filter query
8282 indicationClassName = _getIndicationClassName(
8283 queryExpression, sourceNameSpace);
8286 // Get the indication class object from the repository
8287 // Specify localOnly=false because superclass properties are needed
8288 // Specify includeQualifiers=false because qualifiers are not needed
8290 indicationClass = _subscriptionRepository->getClass(
8291 sourceNameSpace, indicationClassName, false, false, false,
8295 return indicationClass;
8298 void IndicationService::_getRelevantSubscriptions(
8299 const Array<CIMObjectPath> & providedSubscriptionNames,
8300 const CIMName& className,
8301 const CIMNamespaceName& nameSpace,
8302 const CIMInstance& indicationProvider,
8303 Array<CIMInstance>& subscriptions,
8304 Array<String>& subscriptionKeys)
8306 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
8307 "IndicationService::_getRelevantlSubscriptions");
8310 // Retrieves list of enabled subscription instances in the specified
8311 // namespace, where the subscription indication class matches or is a
8312 // superclass of the supported class. A subscription is only included
8313 // in the list if the specified provider accepted the subscription.
8315 _subscriptionTable->getMatchingClassNamespaceSubscriptions(
8323 // If the indication provider included subscriptions in the
8324 // SubscriptionInstanceNamesContainer, the subset of subscriptions
8325 // specified by the indication provider that also appear in the initial
8326 // subscriptions list is returned.
8329 if (providedSubscriptionNames.size() > 0)
8331 for (Uint32 i = 0; i < subscriptions.size(); i++)
8333 if (!Contains(providedSubscriptionNames,
8334 subscriptions[i].getPath()))
8336 subscriptions.remove(i);
8337 subscriptionKeys.remove(i);
8343 PEGASUS_ASSERT(subscriptions.size() == subscriptionKeys.size());
8347 Boolean IndicationService::_subscriptionMatch(
8348 const CIMInstance& subscription,
8349 const CIMInstance& indication,
8350 const CIMPropertyList& supportedPropertyList,
8351 QueryExpression& queryExpr,
8352 const CIMNamespaceName sourceNameSpace)
8354 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
8355 "IndicationService::_subscriptionMatch");
8358 // If supported properties is null (all properties)
8359 // the subscription can be supported
8361 if (!supportedPropertyList.isNull ())
8365 // Get the class paths in the FROM list
8366 // Since neither WQL nor CQL support joins, so we can
8367 // assume one class path.
8368 CIMName indicationClassName =
8369 queryExpr.getClassPathList()[0].getClassName();
8371 if (!_subscriptionRepository->validateIndicationClassName(
8372 indicationClassName, sourceNameSpace))
8375 // Invalid FROM class, the subscription does not match
8382 // Get required property list from filter query (WHERE clause)
8385 // The class should be the class of the indication
8386 // instance, not the FROM class.
8387 // This is needed because CQL can have class scoping operators
8388 // on properties that may not be the same class
8389 // as the FROM class. The required properties
8390 // for an indication are based on indication instance class,
8391 // not the FROM class.
8394 CIMPropertyList requiredPropertyList = _getPropertyList(
8395 queryExpr, sourceNameSpace, indication.getClassName());
8398 // If the subscription requires all properties,
8399 // but supported property list does not include all
8400 // properties, the subscription cannot be supported
8402 if (requiredPropertyList.isNull ())
8405 // Current subscription does not match
8413 // Compare subscription required property list
8414 // with supported property list
8416 for (Uint32 j = 0; j < requiredPropertyList.size (); j++)
8418 if (!ContainsCIMName
8419 (supportedPropertyList.getPropertyNameArray(),
8420 requiredPropertyList[j]))
8423 // Current subscription does not match
8431 catch(const Exception & e)
8433 // This subscription is invalid
8434 PEG_TRACE ((TRC_DISCARDED_DATA, Tracer::LEVEL1,
8435 "Exception caught trying to verify required properties "
8436 "in a subscription are all contained in the list of "
8437 "supported indication properties: %s",
8438 (const char *) e.getMessage ().getCString()));
8442 catch(const exception & e)
8444 // This subscription is invalid
8445 PEG_TRACE ((TRC_DISCARDED_DATA, Tracer::LEVEL1,
8446 "Exception caught trying to verify required properties "
8447 "in a subscription are all contained in the list of "
8448 "supported indication properties: %s", e.what ()));
8454 // This subscription is invalid
8456 PEG_TRACE_CSTRING (TRC_DISCARDED_DATA, Tracer::LEVEL1,
8457 "Unknown exception caught trying to verify "
8458 "required properties in a subscription are all contained "
8459 "in the list of supported indication properties.");
8466 // Check for expired subscription
8470 if (_isExpired(subscription))
8472 // Delete expired subscription
8473 CIMObjectPath path = subscription.getPath ();
8474 _deleteExpiredSubscription (path);
8475 #ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
8476 _sendSubscriptionNotActiveMessagetoHandlerService(path);
8478 PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL3,
8479 "%s Indication Subscription expired",
8480 (const char*)(indication.getClassName().getString().
8486 catch (DateTimeOutOfRangeException&)
8488 PEG_TRACE_CSTRING(TRC_INDICATION_SERVICE, Tracer::LEVEL2,
8489 "Caught DateTimeOutOfRangeException in IndicationService while"
8490 "checking for expired subscription");
8496 // Evaluate whether the filter criteria are met by the generated
8499 if (!queryExpr.evaluate(indication))
8509 Boolean IndicationService::_formatIndication(
8510 CIMInstance& formattedIndication,
8511 QueryExpression& queryExpr,
8512 const Array<CIMName>& providerSupportedProperties,
8513 const Array<CIMName>& indicationClassProperties)
8515 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
8516 "IndicationService::_formatIndication");
8519 // Call QueryExpression::applyProjection to remove properties
8520 // not listed in the SELECT clause. Note: for CQL,
8521 // this will handle properties on embedded objects.
8523 // QueryExpression::applyProjection throws an exception if
8524 // the indication is missing a required property in the SELECT
8525 // clause. Although we have checked for the indication missing
8526 // required properties, it would have not detected missing required
8527 // embedded object properties for CQL. So, we need to catch the
8528 // missing property exception here.
8532 queryExpr.applyProjection(formattedIndication, true);
8534 catch (QueryRuntimePropertyException& re)
8536 // The indication was missing a required property.
8537 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL1,
8538 "Apply Projection error: %s",
8539 (const char*)re.getMessage().getCString()));
8545 // Remove any properties that may be left on the indication
8546 // that are not in the indication class. These are properties
8547 // added by the provider incorrectly. It is possible that
8548 // these properties will remain after applyProjection if the
8549 // SELECT clause happens to have a property name not on the
8550 // indication class, and the indication has that same property.
8551 // Note: If SELECT includes all properties ("*"), it's still
8552 // necessary to check, in case the provider added properties
8553 // not in the indication class.
8555 for (Uint32 j = 0; j < providerSupportedProperties.size(); j++)
8558 formattedIndication.findProperty(providerSupportedProperties[j]);
8559 if (rmIndex != PEG_NOT_FOUND &&
8561 indicationClassProperties, providerSupportedProperties[j]))
8563 formattedIndication.removeProperty(rmIndex);
8571 void IndicationService::_forwardIndToHandler(
8572 const CIMInstance& matchedSubscription,
8573 const CIMInstance& handlerInstance,
8574 const CIMInstance& formattedIndication,
8575 const CIMNamespaceName& namespaceName,
8576 const OperationContext& operationContext)
8578 PEG_METHOD_ENTER(TRC_INDICATION_SERVICE,
8579 "IndicationService::_forwardIndToHandler");
8581 CIMRequestMessage * handler_request =
8582 new CIMHandleIndicationRequestMessage (
8583 XmlWriter::getNextMessageId (),
8586 formattedIndication,
8587 matchedSubscription,
8588 QueueIdStack(_handlerService, getQueueId()),
8592 handler_request->operationContext = operationContext;
8594 AsyncLegacyOperationStart *async_req =
8595 new AsyncLegacyOperationStart(
8600 PEG_TRACE((TRC_INDICATION_SERVICE, Tracer::LEVEL4,
8601 "Sending (SendAsync) Indication to %s "
8602 "via CIMHandleIndicationRequestMessage",
8603 (MessageQueue::lookup(_handlerService) ?
8604 MessageQueue::lookup(_handlerService)->getQueueName() :
8605 "BAD queue name")));
8607 SendForget(async_req);
8612 PEGASUS_NAMESPACE_END