In my last post, I mentioned how one could leverage SOAP along with WS-Addressing to implement the return address pattern in ØMQ (known in the JMS world as ReplyTo and in the MSMQ world as ResponseQueue). In this post, I’ll go into more detail by giving a code example using CXF’s ØMQ transport.
Below is a WSDL that is similar in many respects to the WSDL of the previous post:
Like the other WSDL, this one declares that the service has an operation named sayHi. It states that ØMQ is to be used for transporting the SOAP messages (line 29). Moreover, it declares the service and consumer communication parameters: zmq:address; zmq:serviceConfig; zmq:clientConfig (lines 43-45). Unlike the other WSDL, the socket types are push for the client and pull for the service. This means that communication between the client and service is one-way and therefore the client won’t receive a reply, at least not on the same channel. Remember, since we’re implementing return address, the service sends its reply onto a different channel.
This is the shell command I entered for generating the SEI and proxy classes:
The -asyncMethods switch tells CXF’s wsdl2java to generate, in the SEI, for each Web Service operation an asynchronous method in addition to a synchronous one. In the consumer implementation, I use the generated SEI:
doOperation() sequence of events is as follows:
- Publishes the endpoint that processes the service’s async reply (line 10).
- Creates a client that has WS-Addressing enabled (lines 13-14).
- Adds the ReplyTo element to the request’s SOAP header (lines 17-18). The element contains the callback URL that the service will read in order to know to whom it should deliver its response and how it should deliver it.
- Calls asynchronously the SEI method sayHiAsync() (line 21). If the consumer invokes the synchronous method (i.e., sayHi()) instead of the async one, the consumer would block indefinitely after sending out the request because it will wait for a reply that it will never receive.
The callback terminates the program as soon as it processes the reply.
I re-run wsdl2java to generate another SEI but using the following arguments:
I use the SEI generated from the above command to implement the service:
Nothing special about GreeterImpl.java except the @Addressing annotation. This annotation is required for CXF to process the request’s WS-Addressing headers.
Main.java triggers the server and consumer into action:
The complete application is on GitHub. The instructions for running the demo are almost identical to the ones of the previous post. First enter the following Maven command from the project’s root directory:
Then run the demo using the java command:
You should then get the following output: