.NET Service Logic Caching using WSE

While discussing the production service logic deployment I mentioned in my previous post, I thought that it'd be nice to apply the idea of dynamic service logic deployment for caching purposes. That is, not caching of SOAP documents but of the service logic. This could be useful in mobile computing scenarios where an application that sends messages to a Web Service may be allowed to do so even when disconnected. Of course a number of assumptions will have to be made, like the hosting environment, whether the service logic can operate without any backend infrastructures, the component/library dependencies, etc. However, there are efforts in the systems management space where the description of such requirements can be described.

The idea is that the original service can control, based on policy for example, whether the service logic could be cached. In the responses of the messages it receives, it includes a header with caching-related information. The original requestor can safely ignore this information if it doesn't wish to cache the service.

One could say that the concept is close to Microsoft's one-click deployment but for the Web Services space and this wouldn't be far from the truth.

So, this was the idea which I set out to investigate using WSE and .NET. It turned out that it was remarkable easy (apart from a few implementation problems that were related to the way WSE processes SOAP envelopes... at the end, I didn't manage to change the destination address of a SOAP envelope from within an output filter which was my original design).

Here's how the protocol works...

A sender sends a message of the form:

<soap:Envelope
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsa:Action>process:message</wsa:Action>
<wsa:MessageID>uuid:1046c13a-01f6-4827-8a90-ed9e159a96b5</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>soap.tcp://localhost:10001/echo</wsa:To>
</soap:Header>
<soap:Body>
<msg xmlns="http://tempuri.org/">hello</msg>
</soap:Body>
</soap:Envelope>

The receiving service replies with the message bellow.

<soap:Envelope
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsa:Action>process:message</wsa:Action>
<wsa:MessageID>uuid:f26a190e-ad7f-4f34-b8a5-f7cb75782a17</wsa:MessageID>
<wsa:RelatesTo>uuid:1046c13a-01f6-4827-8a90-ed9e159a96b5</wsa:RelatesTo>
<wsa:To>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:To>
<sld:CanBeCached xmlns:sld="uk:ac:neresc:sld">
<sld:CodeStoreServiceEpr>
<wsa:Address>soap.tcp://localhost:10000/codestore</wsa:Address>
</sld:CodeStoreServiceEpr>
<sld:ServiceEpr>
<wsa:Address>soap.tcp://localhost:10001/echo</wsa:Address>
</sld:ServiceEpr>
<sld:CodeId>a1841844-e889-4379-9ba2-74a67d233ba6</sld:CodeId>
<sld:Requirements>.NET-1.1</sld:Requirements>
</sld:CanBeCached>
</soap:Header>
<soap:Body>
<Echo>
<msg xmlns="http://tempuri.org/">hello</msg>
</Echo>
</soap:Body>
</soap:Envelope

The Service Logic Deployment output filter introduces an additional header indicating that the service logic for that service is cacheable and providing some additional information (like the endpoint of the service providing access to the deployable files, the runtime requirements, etc.).

The WSE input filter at the recipient of the above message finds the header and requests for the files from the code store using a message like the one bellow.

<soap:Envelope
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsa:Action>process:message</wsa:Action>
<wsa:MessageID>uuid:61046a73-477a-4bd8-b041-bf527cdf6843</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>soap.tcp://localhost:10002/codecache</wsa:Address>
</wsa:ReplyTo>
<wsa:To>soap.tcp://localhost:10000/codestore</wsa:To>
</soap:Header>
<soap:Body>
<sld:CodeRequest xmlns:sld="uk:ac:neresc:sld">
<sld:CodeId>a1841844-e889-4379-9ba2-74a67d233ba6</sld:CodeId>
</sld:CodeRequest>
</soap:Body>
</soap:Envelope>

Once the reply to this message is received (with a set of elements containing base64-encoding versions of the files), the service is activated at the consumer's Service Logic Cache. Any outgoing messages to that service will be redirected to the local version.

Of course the service logic doesn't really have to be the same as the one that is deployed at the original endpoint. It may be a customised version that is aware of the fact that it's going to be cached and, hence, allow for offline operations. It could, for example, store locally any information passed to it and automatically communicate that data back to the original service when the connection to the network is re-established. This allows for the cached service logic to deal with the offline status in an application depended manner since the service provider is now able to push logic to the device (security policy permitting of course).

It's been fun.