Saturday, September 18, 2010

Zero Copy pass through in WSO2 ESB

There have been some confusion on Zero Copy pass through scenario (we call that Binary Relay) implementation at WSO2 ESB. Let me try to clarify that.

To implement Binary Relay, we use Axis2 architecture. Axis2 works only with SOAPEnvelope as the input to its pipeline, but users can add Formatters and builders against different content types. Job of a Builder is to build a SOAP envelope from anything (e.g. HTTP SOAP Message, from fast XML, from Jason message etc.) and pass it in to Axis2 pipeline, and job of a Formatter is to take a envelope and write it out in any expected form (write it as a text message, to fast XML, to Jason message etc).

To implement Binary Relay, we wrote a builder, that takes the input stream and and hides it inside a fake SOAP message without reading it, and wrote a formatter that takes the input stream and writes it directly to a output stream. (of course, we take a small buffer and use that to move data between two streams).

Now if you want to understand how it works, best way is to look at the code.

When you look at the code, it is important to note following. Pass through works only if no one access the content of the message. However, there are many cases where user wants to cache (e.g. logging or any other intermediate use), and we detect that and handles it. If you look at BinaryRelayBuilder.java, you will see that we create a DataHandler, hides the input stream inside the DataHandler, and passes it in. To understand how we stream the data, you should look StreamingOnRequestDataSource.java. There, if that is the last use, we just take the input stream and stream it.

If you just look at BinaryRelayBuilder.java, readAllFromInputSteam(..) method can be misleading, and the real code that does the streaming is at StreamingOnRequestDataSource.java. We do cache. But that is ONLY IF something tried to access the SOAP body, and if nothing reads the SOAP body, it is zero copy, as we pass over the input stream as it is to next code.