Monday, January 18, 2010

How to write a custom message receiver for WSF/CPP

When you have to go beyond the supported interface of a ServiceSkeleton when implementing a service, you can use a custom message receiver to achieve that functionality.  For example, recently we encountered such scenario where the unparsed soap enveloped body has to be accessed for some custom logic. But when implementing a service using ServiceSkeleton interface, you would always ended up getting the first child of the soap body as an argument.

In that kind of a situation, the best option would be to implement a custom message receiver. WSF/CPP now provides a very convenient API for implementing a message receiver. 

For implementing a custom message receiver, WSF/CPP provides a class named MessageReceiver. What a user has to do is to extend from this and implement the abstract method invokeBusinessLogicSync which will receive inflow message context and outflow message context as arguments. Then you have the full control over the processing of the message received by the message receiver.

Next add the macro WSF_MESSAGE_RECEIVER_INIT and pass the message receiver class name as the argument.

Next compile the written code as a shared library and place it in <WSFCPP_REPO>\lib directory. When implementing a service which would be invoked using this custom message receiver, set the name of the shared library as the “messageReceiver” parameter for each operation. For example, if the shared library name is “CustomMsgRecv

<operation name=”Op1”><messageReceiver class=”CustomMsgRecv”/></operation>

Here is the example message receiver code.

/* CustomMsgRecv.h */

#include <MessageReceiver.h>

class CustomMsgRecv : public wso2wsf::MessageReceiver
{
public:
WSF_EXTERN bool WSF_CALL
invokeBusinessLogicSync(wso2wsf::MessageContext *inMsgCtx,
wso2wsf::MessageContext* outMsgCtx);
CustomMsgRecv(void);
~CustomMsgRecv(void);
};


/** CustomMsgRecv.cpp */



#include "CustomMsgRecv.h"
#include <MessageReceiver.h>

using namespace wso2wsf;

WSF_MESSAGE_RECEIVER_INIT(CustomMsgRecv)

CustomMsgRecv::CustomMsgRecv(void)
{
}

CustomMsgRecv::~CustomMsgRecv(void)
{
}

WSF_EXTERN bool WSF_CALL
CustomMsgRecv::invokeBusinessLogicSync(wso2wsf::MessageContext *inMsgCtx,
wso2wsf::MessageContext *outMsgCtx)
{
/** Add Your Logic Here */
}