(file) Return to OperationResponseHandler.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManager2

File: [Pegasus] / pegasus / src / Pegasus / ProviderManager2 / OperationResponseHandler.h (download)
Revision: 1.9, Mon Oct 25 17:26:00 2004 UTC (19 years, 8 months ago) by brian.campbell
Branch: MAIN
CVS Tags: PEP213_SIZE_OPTIMIZATIONS, CHUNKTESTDONE_PEP140
Changes since 1.8: +279 -366 lines
PEP#: 140
TITLE: HTTP chunked transfer encoding support/phase 2
DESCRIPTION: see title

//%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 <Pegasus/Common/Config.h>
#include <Pegasus/Server/Linkage.h>
#include <Pegasus/Common/CIMMessage.h>
#include <Pegasus/Common/MessageQueueService.h>
#include <Pegasus/Common/Constants.h>
#include <Pegasus/Common/ContentLanguages.h>  // l10n

#include <Pegasus/Common/CIMClass.h>
#include <Pegasus/Common/CIMInstance.h>
#include <Pegasus/Common/CIMIndication.h>
#include <Pegasus/Common/CIMValue.h>

#include <Pegasus/Common/ResponseHandler.h>
#include <Pegasus/Common/Logger.h>
#include <Pegasus/Common/XmlWriter.h>

#include <Pegasus/ProviderManager2/SimpleResponseHandler.h>
#include <Pegasus/ProviderManager2/Linkage.h>

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 const String& getClass() const
	  { 
			static const String n("OperationResponseHandler");
			return n;
		}

   	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 const String& getClass() const                                        \
{ static const String n(#c "ResponseHandler"); return n; }

class GetInstanceResponseHandler:  public OperationResponseHandler, public SimpleInstanceResponseHandler
{
public:
	PEGASUS_RESPONSE_HANDLER_DERIVED_INIT(GetInstance, SimpleInstance);

	virtual void transfer()
	{
		if (size() > 0)
		{
			CIMGetInstanceResponseMessage &msg = 
				*static_cast<CIMGetInstanceResponseMessage *>(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<CIMEnumerateInstancesResponseMessage *>(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<CIMEnumerateInstanceNamesResponseMessage *>(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<CIMCreateInstanceResponseMessage *>(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<CIMGetPropertyResponseMessage *>(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<CIMExecQueryResponseMessage *>(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<CIMAssociatorsResponseMessage *>(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<CIMAssociatorNamesResponseMessage *>(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<CIMReferencesResponseMessage *>(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<CIMReferenceNamesResponseMessage *>(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<CIMInvokeMethodResponseMessage *>(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<CIMObjectPath> 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<CIMObjectPath> 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<CIMIndication> & cimIndications)
	{
		OperationContext context;
		
		deliver(context, cimIndications);
	}
	
	virtual void deliver(const OperationContext & context, const Array<CIMIndication> & 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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2