Since I knew what the SOAP payloads look like (the SOAP body content), what I really wanted to do was just build this XML and pass it to an endpoint. It would also be nice if this endpoint dynamically set the SOAP message headers, extracted the SOAP body from the response and applied the response transformers (and perhaps got me a beer.)
I didn't see an obvious way to do with the CXF transport, so I took a stab at implementing such a transport myself. I had used SAAJ in a web-services proxy project I worked on last year and it seemed like a good fit. As such, I present the SAAJ-Transport. You can currently use it to pass arbitrary XML that is used as the SOAP body in messages sent to a SOAP endpoint. The endpoint handles constructing the SOAP message for you, adding the headers and extracting the SOAP body from the response (it won't get you a beer...yet.) Here's an example using a chaining-router to send a SOAP message and send the response to a VM endpoint.
<outbound>
<chaining-router>
<saaj:outbound-endpoint address="${service.url}" synchronous="true">
<transformers>
<transformer ref="templateToRequest"/>
<mulexml:xml-to-dom-transformer returnClass="org.w3c.dom.Document"/>
<saaj:document-to-soap-message-transformer/>
<saaj:mime-header-transformer key="Cookie" value="#[header:SERVICE_SOAP_SESSION_ID]"/>
</transformers>
</saaj:outbound-endpoint>
<vm:outbound-endpoint path="service.dispatcher">
<transformers>
<saaj:soapbody-to-document-transformer/>
<mulexml:dom-to-xml-transformer returnClass="java.lang.String"/>
</transformers>
</vm:outbound-endpoint>
</chaining-router>
</outbound>
The "document-to-soap-message-transformer" takes an org.w3c.dom.Document, transforms it to a SAAJ SOAPMessage and uses SAAJ to invoke the web-service. The mime-header-transformer adds a MIME header to the message (in this case a Cookie). Existing properties on the MuleMessage will be added the the SOAP header. When the response is received, the transport will extract out the SOAPBody and return it as the synchronous response, as well as set any SOAP headers as properties on the MuleMessage. In this case, the response is transformed back to a Document, then to a String, then finally passed out on the VM endpoint.
I'm hoping next week to get full documentation and examples up on the MuleForge page. I'm also planning to work on receiver functionality. This would allow you to receive SOAP messages on an inbound-endpoint and have their bodies extracted, headers set as Mule properties, etc. I'm still working on getting the distribution together. For now you'll need to checkout the source and use "mvn clean package" to build the jar or "mvn clean install" to get them into your local repository.
2 comments:
Couldn't this be done with a CXF outbound endpoint?
<cxf:outbound-endpoint address="..." proxy="true"/>
That will take whatever messsage you send it and embed it in a soap envelope. Just make sure it's XML of some sort.
I don't think this will add all message properties as soap headers, but it does add the correlation properties in as headers. You could always write a CXF interceptor to do that too.
Ah, good call Dan...I missed proxying on outbound CXF endpoints. Will this extract the XML payload from the response as well, or is that still wrapped in the SOAP envelope?
Post a Comment