Friday, March 1, 2013

Writing a SOAP message preview tool

Previous post introduced a new tree view of request parameters for invoking an endpoint. Here I'd like to show an example of a practical usage of such addition to Wise core: a customized SOAP message preview tool.
There're few scenarios in which a user needs to know how a SOAP message for invoking a given WSDL operation will look like. Computing that can be easy or difficult, depending on the complexity of the contract (number of schemas, wsdl style, etc.), that's why resorting to leveraging tools is actually a good idea ;-)

Using Wise, we start by building a WSDynamicClient instance consuming our target wsdl and selecting the WSMethod to use (here we already knew the service, port and operation names):
then it's time to create an ElementBuilder as follows:
please note we're setting the request flag (given we're building the tree for request parameters) and we disable default value generation for leaf elements (as we want to provide custom default values and do not want elements from schema sequences to default to null).
The builder is used to build up the request trees (one for each method parameter):
the populateElement method is where we customize the tree according to our scenario needs:
as you can see, we don't want null elements [A], we set default values for leaves [B], we add one element for each array/collection [C] and run a single cycle of lazy element expansion [D] (cyclic element type references in the schemas are converted into lazy load elements in the tree).
In this case, the default values are set in quite a dirty way in getDefaultValue(Class cl), basically we check provided class and return a "?" for String, zero for any numerical type, "1970-01-01T00:00:00.000Z" for XMLGregorianCalendar and an empty string otherwise.
Once the tree is available, getting the actual parameter objects to perform the invocation with is a matter of calling toObject() on each tree root element:
And finally, the message preview is written to a provided output stream as follows:
That's all!
You can have a look at the whole code in the MessagePreviewIntegrationTest I've recently added to the current Wise core 2.0.1-SNAPSHOT. Any feedback / comment is welcome!

And if you're wondering how this is currently implemented, well, you know Wise basically uses JAXWS tooling from JBossWS to generate a compliant ws client; the Wise model is built by parsing the generated client and the tree view is derived from the model. The message preview flow is pretty similar to the invocation one, except a special jaxws handler is installed in the client in order for writing down the SOAP message generated by the internal ws stack (Apache CXF here); the handler also stops the handler chain execution so that no message actually goes to wire and Wise early return the message preview.

As previously explained, delegating to a fully compliant WS stack here, ensure correctness of the messages, even of their preview ;-)

No comments: