Friday, September 7, 2012

Sending attachment: MTOM / XOP vs SWA and inline attachment

So you want to send a large binary/files via web services. This blog will describe why MTOM (Message Transmission Optimization Mechanism) / XOP (XML-binary Optimized Packaging) is better than inline-attachment and SWA.

Inline base64 attachment
The binary content as an inline element inside the SOAP message:
<Envelope>
 <Body>
  <sendImage>
   <filename>mybeautifulwife.jpg</filename>
   <image>.... JPEG image base64 .....</image>
  </sendImage>
 </Body>
</Envelope> 
We need to convert the binary to base64 since we use XML. The problem with this method is that the base64 representation will expand the size of the message, so it's not an effecient method.

SOA with attachment (SWA)
Using MIME message (originally for SMTP email protocol), the SOAP message becomes the first MIME content and the attachments are in the following MIME contents:
type=text/xml;
start="<rootpathID>"
Content-Length: ...
--_MIME_boundary_
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <rootpathID >
<soapenv:Envelope>
 <soapenv:Body>
  <sendImage>
    < filename>mooiemarjo.jpg</filename>
    <image href="cid:imgID"/>
  </sendImage>
 </soapenv:Body>
</soapenv:Envelope>
--_MIME_boundary_
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
Content-ID: <imgID>
...JPEG image bytes...
--_MIME_boundary_--
The problems with SWA:
• it's break the SOAP web service model: the SOAP message being XML
interoperability problems (e.g. different implementations of message-level security)



MTOM/XOP standard as a better solution:
• Similar to SWA approach: using MIME messages
• interoperability: the MIME attachment contents logically become inline contents within XML document so it's easy to handle these contents with standard approach (e.g. XSL transformation, standard security treatment using WS-Security for encryption/signature, WS-RM for QoS)
interoperability with different web service clients thanks to MTOM policy declaration in the wsdl which is understood by different vendors (I have tested in .Net, Java.)
optimized (e.g. compressed in Weblogic framework)
Content-Type: Multipart/Related;
boundary=_MIME_boundary_;
type= application/xop+xml;
start="<rootpathID>"
Content-Length: ...
--_MIME_boundary_
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <rootpathID >
<soapenv:Envelope>
 <soapenv:Body>
  <sendImage>
    < filename>mooiemarjo.jpg</filename>
    <image>
     <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
      xmlns:xmlmime="://www.w3.org/2004/11/xmlmime"
      xmlmime:contentType="image/jpeg" href="cid:imgID"/>
    </image>
  </sendImage>
 </soapenv:Body>
</soapenv:Envelope>
--_MIME_boundary_
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
Content-ID: <imgID>
...JPEG image bytes...
--_MIME_boundary_--
Note that the MIME content type is application/xop+xml and we use to include the attachment content.




How: server side (JAX-WS in Weblogic)
use @MTOM annotation or mtom.xml policy

How: client side (JAX-WS in Weblogic)

Pass MTOMFeature() as argument:
MtomService port = service.getMailServicePort(new MTOMFeature());

Using SOAPUI as a test client


MTOM attachment via SOAPUI, 3 steps:
1. Set Enable MTOM = true in the request properties
2. Upload the attachment (e.g.. A3.pdf), notice the contentID
3. Set the MTOM contentID in the xml request



Improving your MTOM service:
• Security: validation & sanitation (against code injection), limit the attachment/body size (againts DOS attack), content scan (against virus)
• adding reliability with guaranteed delivery queue as the front end of the proxy

If you're an Oracle OSB fans
In OSB you can use also email-transport, but using a Java webservice with JavamailAPI offers more configuration flexibility (e.g. unicode support, custom content handlers, etc) and better performance (throughput). A good book about how to use email-transport in OSB: OSB Development Cookbook by Schmutz et.al.

Javamail tips
Html & Unicode support in the Javamail API (Java library to send mails to the SMTP servers):
messageBodyPart.setContent(thecontent, "text/plain; charset= UTF-8");

Source: Steve's blogs http://soa-java.blogspot.com/

Any comments are welcome :)


References:

Developing Web Services with Apache CXF and Axis2 by Tong
MTOM using open source Java (Axis2 & CXF): using document-wrap or RPC style and DataHandler.


Programming Advanced Features of JAX-WS Web Services for Oracle WebLogic Server
http://docs.oracle.com/cd/E17904_01/web.1111/e13734/mtom.htm#i281179

MTOM using JAX-WS (with example code)
http://www.mkyong.com/webservices/jax-ws/jax-ws-attachment-with-mtom/

No comments: