//%2004//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation, The Open Group. // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //============================================================================== // // Author: Chip Vincent (cvincent@us.ibm.com) // // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company // (carolann_graves@hp.com) // Dave Rosckes (rosckes@us.ibm.com) // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com) // Adrian Schuur (schuur@de.ibm.com) // Seema Gupta (gseema@in.ibm.com) for PEP135 // Brian G. Campbell, EMC (campbell_brian@emc.com) - PEP140/phase2 // //%///////////////////////////////////////////////////////////////////////////// #ifndef Pegasus_OperationResponseHandler_h #define Pegasus_OperationResponseHandler_h #include #include #include #include #include #include // l10n #include #include #include #include #include #include #include #include #include PEGASUS_NAMESPACE_BEGIN class PEGASUS_PPM_LINKAGE OperationResponseHandler { friend class SimpleResponseHandler; public: OperationResponseHandler(CIMRequestMessage * request, CIMResponseMessage * response); virtual ~OperationResponseHandler(void); CIMRequestMessage * getRequest(void) const { return(_request); } CIMResponseMessage * getResponse(void) const { return(_response); } virtual void setStatus(const Uint32 code, const String & message = String::EMPTY) { _response->cimException = PEGASUS_CIM_EXCEPTION(CIMStatusCode(code), message); } virtual void setStatus(const Uint32 code, const ContentLanguages & langs, const String & message = String::EMPTY) { _response->cimException = PEGASUS_CIM_EXCEPTION_LANG( langs, CIMStatusCode(code), message); } protected: // the default for all derived handlers. Some handlers may not apply // async behavior because their callers cannot handle partial responses. virtual Boolean isAsync() const { return true; } // send (deliver) asynchronously virtual void send(Boolean isComplete); // transfer any objects from handler to response. this does not clear() virtual void transfer() {} // validate whatever is necessary before the transfer virtual void validate() {} virtual String getClass() const { return String ("OperationResponseHandler"); } Uint32 getResponseObjectTotal() const { return _responseObjectTotal; } // there can be many objects per message (or none at all - i.e complete()) Uint32 getResponseMessageTotal() const { return _responseMessageTotal; } Uint32 getResponseObjectThreshold() const { return _responseObjectThreshold; } CIMRequestMessage * _request; CIMResponseMessage * _response; private: Uint32 _responseObjectTotal; Uint32 _responseMessageTotal; Uint32 _responseObjectThreshold; }; /* ------------------------------------------------------------------------- */ /* operation specific response handlers */ /* ------------------------------------------------------------------------- */ #define PEGASUS_RESPONSE_HANDLER_DERIVED_CONSTRUCT(c, b) \ c ## ResponseHandler(CIM ## c ## RequestMessage *request, \ CIM ## c ## ResponseMessage *response) \ : OperationResponseHandler(request, response) {} #define PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(c, b) \ PEGASUS_RESPONSE_HANDLER_DERIVED_CONSTRUCT(c, b) \ virtual String getClass() const { return String (#c "ResponseHandler"); } class GetInstanceResponseHandler: public OperationResponseHandler, public SimpleInstanceResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(GetInstance, SimpleInstance); virtual void transfer() { if (size() > 0) { CIMGetInstanceResponseMessage &msg = *static_cast(getResponse()); msg.cimInstance = getObjects()[0]; } } virtual void validate() { if (getResponseObjectTotal() == 0) { // error? provider claims success, // but did not deliver an instance. setStatus(CIM_ERR_NOT_FOUND); } } }; class EnumerateInstancesResponseHandler : public OperationResponseHandler, public SimpleInstanceResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(EnumerateInstances, SimpleInstance); virtual void transfer() { CIMEnumerateInstancesResponseMessage &msg = *static_cast(getResponse()); msg.cimNamedInstances = getObjects(); } }; class EnumerateInstanceNamesResponseHandler : public OperationResponseHandler, public SimpleObjectPathResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(EnumerateInstanceNames, SimpleObjectPath); virtual void transfer() { CIMEnumerateInstanceNamesResponseMessage &msg = *static_cast(getResponse()); msg.instanceNames = getObjects(); } }; class CreateInstanceResponseHandler : public OperationResponseHandler, public SimpleObjectPathResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(CreateInstance, SimpleObjectPath); // ATTN: is it an error to not return instance name? #if 0 virtual void validate() { if (getResponseObjectTotal() == 0) setStatus(CIM_ERR_NOT_FOUND); } #endif virtual void transfer() { if (size() > 0) { CIMCreateInstanceResponseMessage &msg = *static_cast(getResponse()); msg.instanceName = getObjects()[0]; } } }; class ModifyInstanceResponseHandler : public OperationResponseHandler, public SimpleResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(ModifyInstance, Simple); }; class DeleteInstanceResponseHandler : public OperationResponseHandler, public SimpleResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(DeleteInstance, Simple); }; class GetPropertyResponseHandler : public OperationResponseHandler, public SimpleValueResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(GetProperty, SimpleValue); virtual void transfer() { if (size() > 0) { CIMGetPropertyResponseMessage &msg = *static_cast(getResponse()); msg.value = getObjects()[0]; } } virtual void validate() { // error? provider claims success, // but did not deliver an instance. if (getResponseObjectTotal() == 0) setStatus(CIM_ERR_NOT_FOUND); } }; class SetPropertyResponseHandler : public OperationResponseHandler, public SimpleResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(SetProperty, Simple); }; class ExecQueryResponseHandler : public OperationResponseHandler, public SimpleInstance2ObjectResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(ExecQuery, SimpleInstance2Object); virtual void transfer() { CIMExecQueryResponseMessage &msg = * static_cast(getResponse()); msg.cimObjects = getObjects(); } // this handler will not send async but sync virtual Boolean isAsync() const { return false; } }; class AssociatorsResponseHandler : public OperationResponseHandler, public SimpleObjectResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(Associators, SimpleObject); virtual void transfer() { CIMAssociatorsResponseMessage &msg = *static_cast(getResponse()); msg.cimObjects = getObjects(); } }; class AssociatorNamesResponseHandler : public OperationResponseHandler, public SimpleObjectPathResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(AssociatorNames, SimpleObjectPath); virtual void transfer() { CIMAssociatorNamesResponseMessage &msg = *static_cast(getResponse()); msg.objectNames = getObjects(); } }; class ReferencesResponseHandler : public OperationResponseHandler, public SimpleObjectResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(References, SimpleObject); virtual void transfer() { CIMReferencesResponseMessage &msg = *static_cast(getResponse()); msg.cimObjects = getObjects(); } }; class ReferenceNamesResponseHandler : public OperationResponseHandler, public SimpleObjectPathResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(ReferenceNames, SimpleObjectPath); virtual void transfer() { CIMReferenceNamesResponseMessage &msg = *static_cast(getResponse()); msg.objectNames = getObjects(); } }; class InvokeMethodResponseHandler : public OperationResponseHandler, public SimpleMethodResultResponseHandler { public: PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(InvokeMethod, SimpleMethodResult); virtual void transfer() { CIMInvokeMethodResponseMessage &msg = *static_cast(getResponse()); msg.outParameters = getParamValues(); // ATTN-RK-20020903: Is it legal for the return value to be null? // if not, then the check must be done here since deliver() works off the // virtual size, which refers to out parameters! msg.retValue = getReturnValue(); } }; typedef void (*PEGASUS_INDICATION_CALLBACK)(CIMProcessIndicationRequestMessage*); class EnableIndicationsResponseHandler : public OperationResponseHandler, public SimpleIndicationResponseHandler { public: // our own contructor is used, not the default one in the macro #undef PEGASUS_RESPONSE_HANDLER_DERIVED_CONSTRUCT #define PEGASUS_RESPONSE_HANDLER_DERIVED_CONSTRUCT(c,b) PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(EnableIndications, SimpleIndication); EnableIndicationsResponseHandler (CIMEnableIndicationsRequestMessage * request, CIMEnableIndicationsResponseMessage * response, CIMInstance & provider, PEGASUS_INDICATION_CALLBACK indicationCallback) : OperationResponseHandler(request, response), _request_copy(*request), _response_copy(*response), _indicationCallback(indicationCallback) { _provider = provider; } // this handler will not send async but sync virtual Boolean isAsync() const { return false; } virtual void deliver(const CIMIndication & cimIndication) { OperationContext context; Array subscriptionInstanceNames; context.insert(SubscriptionInstanceNamesContainer(subscriptionInstanceNames)); deliver(context, cimIndication); } virtual void deliver(const OperationContext & context, const CIMIndication & cimIndication) { // ATTN: temporarily convert indication to instance CIMInstance cimInstance(cimIndication); // // Get list of subscription instance names from context // Array subscriptionInstanceNames; try { SubscriptionInstanceNamesContainer container = context.get (SubscriptionInstanceNamesContainer::NAME); subscriptionInstanceNames = container.getInstanceNames(); } catch (Exception&) { subscriptionInstanceNames.clear(); } // l10n ContentLanguages contentLangs; try { // Get the Content-Language for this indication. The provider // does not have to add specify a language for the indication. ContentLanguageListContainer langContainer = context.get (ContentLanguageListContainer::NAME); contentLangs = langContainer.getLanguages(); } catch (Exception&) { // The provider did not explicitly set a Content-Language for // the indication. Fall back to the lang set in this object. contentLangs = getLanguages(); } // l10n -end // create message // l10n CIMProcessIndicationRequestMessage * request = new CIMProcessIndicationRequestMessage( XmlWriter::getNextMessageId(), cimInstance.getPath().getNameSpace(), cimInstance, subscriptionInstanceNames, _provider, QueueIdStack()); // Must be filled in by the callback function request->operationContext = context; try { request->operationContext.set(ContentLanguageListContainer(contentLangs)); } catch(const Exception &) { request->operationContext.insert(ContentLanguageListContainer(contentLangs)); } _indicationCallback(request); } virtual void deliver(const Array & cimIndications) { OperationContext context; deliver(context, cimIndications); } virtual void deliver(const OperationContext & context, const Array & cimIndications) { for(Uint32 i = 0, n = cimIndications.size(); i < n; i++) { deliver(context, cimIndications[i]); } } private: CIMEnableIndicationsRequestMessage _request_copy; CIMEnableIndicationsResponseMessage _response_copy; PEGASUS_INDICATION_CALLBACK _indicationCallback; }; #undef PEGASUS_RESPONSE_HANDLER_DERIVED_INIT PEGASUS_NAMESPACE_END #endif