Capturing HTTP Status Code on One-Way Web Service Operations

I am working on a project using WID/WPS/WESB v6.2.0.2 and was asked recently if a mediation flow could capture HTTP response codes from a back-end web service one-way operation.

Naturally my advice was that if an operation describes neither response nor faults, the client is not expected to care about what happens after the request is posted to the service.

Nonetheless, I set about providing a solution, which I would class as a ‘trick’, and hence worthy of a first post in this appropriately named blog.

In summary, the trick consists in calling the web service using an import with HTTP bindings using SOAP/HTTP data serialisation format and basically lying on the import interface. Shameless, but effective.

So, let me show you the trick in more detail.

Lets pretend we have a CustomerService with an addCustomer one-way operation that accepts a Customer as input. Go ahead and create a library named LB_Customer, an interface named CustomerService and a DataObject called Customer.

Then create a module called CustomerService with a Java SCA component just logging the Customer attributes and a web services export. I chose SOAP1.1/HTTP using JAX-RPC. Well, I had no choice. This is the standard in this project.

So, here’s the assembly:

Here’s the CustomerService interface:

And here’s the Customer data type:

Oh, and the very simple Java component code:

You can go ahead, deploy and test. We’re done with the pretence and we can move on to the real trick.

Now create a mediation module, call it MM_CustomerService and do not make the library a dependency. Within this mediation project create your own copy of the Customer data type and the CustomerService interface, but make the addCustomer operation request-response and create a new Response data type.

Here’s the mediation’s private CustomerService interface:

And here’s the Response data type, also private to the mediation:

The private Customer data type is an exact copy of the one in the library used by the target service.

At this point it might be worth showing you my business integration view, so you can check all your bits and pieces are in the right place:

Now comes the hack. You have to make sure the CustomerService interface which is part of the MM_CustomerService mediation project has the same namespace as the one in the library. So go ahead and change it. Go to the interface properties and change the namespace to http://LB_Customer/CustomerService. I told you there was some lying involved.

Now you can assign this interface to your mediation flow component, both as an interface and a reference. Then drop an import into the assembly, wire it to the mediation flow component’s reference and accept the creation of a matching interface on the import.

Right-click on the import and select Generate Binding…-> HTTP Binding. You will have to provide the endpoint URL. You can copy it from the binding tab on the properties for the web services export on the CustomerService assembly.

Here’s a screenshot of the complete assembly:

Go to the properties for the HttpImport, Binding tab, and select SOAP (HTTP) as the default data format. You will need to check the box to show deprecated data formats.

Here’s how you select the data binding:

And here’s the main Binding Properties tab:

Finally go to the Method bindings tab, select the addCustomer bound method and change the HTTP method from GET to POST.

Now let’s implement the mediation flow.

The request flow is a doddle. We simply let the message pass through:

The response flow requires a couple of XML transformations for the out and fail terminals:

The two transformations operate at message root level and map the StatusCode and ReasonPhrase from the smo HTTPHeader to the response body:

You can build, and deploy the two modules now.

Then test the mediation flow component. I’m assuming you’re more than familiar with the integration test client.

What happened?

On this first run I can see in the Events pane that we invoked the http import and that the response fail terminal was fired, routing the response flow to the MapFail xml transform. You can also see the response values. HTTP status code 500

So this is rather good news! Yes, something is not quite right yet but it proves that we are doing what we are supposed to. Capturing HTTP response codes for a service which is, in WSDL/SOAP terms, one-way.

If you have a Console view to hand, you can flounder around for an explanation to this minor frustration, but I’d rather just save you time and show you the relevant log section:

So, it looks like we are missing a SOAPAction header.

I’m still in fits about understanding the purpose of this header. But I understand that there must be a SOAPAction HTTP header for this to work.

So, go back to the properties for the HTTP Import and add an HTTP header named SOAPAction. I used a single white space for its value as there must be a value present.

Now rebuild, republish and retest.

Sweet! We get a 200 OK and we can see in the log the target service doing the sysouts!

And one last thing you may want to do is to stop the CustomerServiceApp (on the Servers view) and retest. You will get the anticipated 404 Not Found:

That’s it, hope you enjoyed this magic trick and feel free to contribute comments and observations, particularly if you get a chance to try something similar on v7.

ttfn

Changing a SOAP Endpoint on an Outgoing Message using JAX-WS

This tip comes from Arancha Ocana Diaz-Ufano, who did all the hard work to figure it out!

In WebSphere ESB, there are many ways of changing the endpoint of a SOAP message outbound from a mediation flow, and the normal way is to use the dynamic endpoint support.  To be clear, this is recommended way.

However, there is another technique, and that’s to use a JAX-WS handler (assuming you’re using a JAX-WS Web Services binding) on the outbound message. This might be useful if, for example, you absolutely cannot modify a mediation flow that’s been given to you, you cannot modify the endpoint at administration time (for example, from the administration console), or you want to do the override in a generic fashion across a large number of mediation flows.

The key is knowing the magic incantation to put in your JAX-WS handler. And here it is:

mySOAPMessageContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://myhost:9080/MyEndPoint");

Thanks again to Arancha for allowing us to publish this tip.

WS-Addressing Headers in WebSphere ESB v6.2

I wrote previously about how WS-Addressing headers could be accessed in a WebSphere ESB mediation flow, by writing a JAX-RPC handler to intercept them and insert them into a custom SOAP header.

However, in WebSphere ESB 6.2, this is much easier – these headers will now automatically appear as part of the ServiceMessageObject at /headers/WSAHeader. They are effectively read-only; any changes that you make will not affect outgoing messages.

Monitoring SOAP messages in WebSphere Integration Developer

If you are developing a module or mediation module with web services bindings you may be interested in monitoring the SOAP message(s) received at an export or sent from an import. To find out how to do this, read the rest of this post.
Read more of this post

Overridding a Web Services Endpoint at Runtime in WebSphere ESB 6.0.1

Let’s say that you’ve developed a mediation module for WebSphere ESB 6.0.1 that contains a Web Services import (SOAP/HTTP). You’ve exported it from WebSphere Integration Developer (WID) as a .ear, but you realise, after deploying your application onto your runtime server, that you need it to point at a different Web Services endpoint (perhaps a different server). Here’s how you change it:

  1. Go to the administrative console for your server.
  2. Select ‘Applications/Enterprise Applications’.
  3. Select the application (mediation module) that contains the import in question.
  4. Select ‘EJB Modules’.
  5. Select the EJB module from the list (there will be only one).
  6. Select ‘Web services client bindings’.
  7. Under ‘Port Information’, click ‘Edit…’.
  8. In the ‘Overridden Endpoint URL’ box, you should see the current endpoint – as defined in WID. Change that to the URL you want, click OK, save your changes and restart your server.

Protocol Transformation

This recently published Developerworks article gives an excellent overview of WebSphere ESB, as well as providing a detailed tutorial on protocol transformation, using the example of transforming a SOAP/HTTP service request into a SOAP/JMS one, as well as explaining how to use the Test Client facility in WebSphere Integration Developer. Worth taking a look if you’re new to the ESB concept or want a primer on WebSphere ESB.

Follow

Get every new post delivered to your Inbox.

Join 116 other followers