An example of how to process a zipped file in OSB
By MikeMuller on Nov 04, 2011
I recently had a request from a customer for advice on how to process a zipped file sent over HTTP. I looked around for an example but didn't find one. So, after creating one for the customer I figured someone else may come across this scenario and decided to post a generic version here. (NOTE: This example was created using OSB 220.127.116.11)
The premise used for this use case is the requirement to receive a multipart MIME message over HTTP. The message contains a part of type application/zip which is a zipped XML document. This document needs to be unzipped and then routed to a WSDL/SOAP service for some processing. For the example, I created a simple book catalog schema and sample document, as follows:
The approach I took to accomplish the goal consists of two proxy services and a Java class for unzipping the file. Unfortunately, there is no built in function for unzipping, so a Java Callout is required. For this sample, I created a simple Java class named JarReader containing a public static method named processBytes that takes a byte array as input and returns the unzipped contents as a string. The byte array in this case contains the contents of the zipped file. The method implementation assumes that the zipped content is character data and is encoded in the default character set.
The main proxy service, named MultipartZippedFileProxy, receives the multipart message, passes the zipped XML file to a local proxy, named ProcessZippedXMLProxy, for unzipping and then routes the XML to a WSDL/SOAP service. I chose to use a local proxy for doing the unzipping because it made it simpler to type the XML correctly.
The main proxy is defined as follows:
I defined the proxy as a messaging service with Text as its request and response type. When processing multipart messages in OSB, the message parts are accessible in the pipeline via the $attachments built in variable. When handling binary content messages, OSB places the content in an internal repository and provides a handle to this data in the pipeline via a binary content element, for example
This is also true for binary attachments. Another thing to remember with binary content is that when passing the content to another service or a Java callout, you have to pass the binary-content element itself, not the enclosing variable element (such as body above). OSB retrieves the binary content from its internal store and passes it to the Java callout as a byte array.
The main proxy pipeline consists of a pipeline pair and a route node.
In the request stage, the attachment of type "application/zip" is selected from the $attachments variable into the variable $part. The XPath expression for that is $attachments/ctx:attachment[ctx:Content-Type='application/zip']. Note that an assumption is made here that a request message will always have one and only one part of type application/zip. The contents of the attachment are unzipped using a service callout to the local proxy ProcessZippedXMLProxy. This proxy is another messaging service, taking a binary message as input and returning a bookcatalog XML document.
As mentioned previously, the expression used to set the input variable for the callout, $zippedContent, selects the binary content from the attachment body ($part/ctx:body/ctx:binary-content).
The route node of the main proxy replaces the multipart message received with the unzipped XML document and then routes it to the BookCount service, which in this case is just another proxy.
You'll notice that the attachments are explicitly deleted. If this was not done, they would be returned in the response as a multipart message.
The local proxy for processing the zipped file is very simple. It passes the binary input to a Java callout and then sets the callout response to $body which is then returned to the caller. The OSB test console supports testing with attachments. Or, as an alternative, you can use the Apache Commons HTTP Client library in a Java app to build and send a multipart message to the main proxy. See their example named ClientMultipartFormPost.java
The OSB configuration for the complete sample is here.