Thursday, June 2, 2016

Implementing Hamcrest custom matcher using java dynamic proxy

Motivation

I was reading the article New Tricks with Dynamic Proxies in Java 8 from Dominic Fox and I thought that could be interesting to implement the code as he suggests.

Source code

The source code used in this post can be found at my GitHub repository:

https://github.com/mroger/hamcrest-proxy-matcher

Model

The Person model class is a very simple POJO to demonstrate the use of the proxy matcher and can be seen below.


The test

The test method we're interested in uses a custom matcher implemented using dynamic proxy.

The aPerson() method creates a proxy for PersonMatcher and returns its fluent interface as seen below. The interface declares the methods used to setup the matcher.


The custom matcher


The idea behind this custom matcher proxy is to intercept all the calls to the PersonMatcher interface and provide their implementation on the fly. The custom matcher's users will only have to comply to one little rule: PersonMatcher  interface methods have to start with "with".

The first methods called on PersonMatcher will be the ones defined by the interface. In  the invoke method, those method names and arguments are put in the map for later processing. You can see it below.


Then, Hamcrest calls the custom matcher's matches() method and the proxy intercepts it, using the method names previously stored in the map to extract values from the actual object using reflection and comparing them with the also previously stored values. Note that the "with" prefix is removed from method names to obtain the fields names that, in conjunction with expected and actual values, are used to assemble expectedDescription and mismatchDescription, printed in the last two phases in Hamcrest´s life cycle.




Lastly, if any of the values doesn't match, then Hamcrest also calls the Matcher's describeTo() and describeMismatch() method, to give the custom matcher a chance to explain, as a formatted description, what values diverge, using descriptions stored previously.

As we can see, using dynamic proxy is a great way to create semantics and DSLs for your tests. It also helps to avoid tedious implementations.

Wanna share your thoughts? I´d like very much to know your opinions about this and if it helped you in any way.

Sunday, May 29, 2016

JAX-WS client and server SOAP handler

Motivation

I've found this interesting series of articles form Mkyong where he briefly explains how to write and configure SOAP handlers for client and server JAX-WS Webservices.

Then I've added some features: dependency management via Maven for client and server projects; a helper class to configure client's SOAP handler so it's possible to rebuild endpoint using wsimport any time is needed; and for last, I configured client's Maven POM file to run wsimport during generate-sources phase.

You can find these client and server in my GitHub repository. Clone them using the command:

git clone https://github.com/mroger/jaxws-in-out-interceptor.git

Service

The service runs over a Jetty web container. You can run it with the command (in the hello-server folder):

$ mvn clean jetty:run

You can check the service running, putting this URL in your browser:

http://localhost:8080/SimpleWebService

And to check the WSDL, put this URL:

http://localhost:8080/SimpleWebService?wsdl

This service is very simple. It just send the string "Hello, <name>" over the network, given that the client has sent the expected IP address.
The service class is annotated with @HandlerChain(file="handler-chain.xml") which points to a handler class declaration. This xml file can be found in the src/main/resources folder.

What is cool about this handler is that with it you can intercept the inbound or outbound messages and enrich, validate or decorate them.


Client

The client also has a handler attached to it, intercepting inbound and outbound messages.

In Mkyong's example, the handler is injected via annotation. But the annotation is put over the Webservice class and I wanted it generated automatically at every build. So I took a different approach:

To configure a handler, I implemented HandlerResolver as seen in this article. Then I just added the HandlerResolver to the Webservice class, as seen below.

As seen in client's Maven POM file, all client's Webservice classes are generated  during generate-sources phase.

Conclusion

Using handlers in JAX-WS Webservices is a great and clean way to handle inbound and outbound SOAP messages.