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

Advertisements

SOA Tips ‘n’ Tricks – Being Mothballed

Folks, I’ve recently taken on a new role working with IBM customers on Dojo (and if that interests you, I’ve launched a great new blog I’m very excited about at dojotipsntricks.com, so please go check that out), so there aren’t likely to be any new posts on this blog. However, I’ll leave it in place for some time – hopefully there’s still some useful content on here for those working with WebSphere ESB, Process Server, and the other things I’ve written about over the past few years. Thanks for your attention!

Application Development for IBM WebSphere Process Server and Enterprise Service Bus 7.0

I was recently given a copy of the new book Application Development for IBM WebSphere Process Server 7 and Enterprise Service Bus 7 to review. In general, I’m very impressed. The authors do a good job of explaining general SOA concepts, and the components of the respective IBM products which are used in implementing these concepts, right down to the nitty-gritty of how to implement a sample scenario (with thorough walk-through steps and screenshots). They cover both the key concepts of mediation flows and BPEL-based business processes. The book is light on a few subjects (it doesn’t really discuss the WebSphere Adapters, for example, and the chapter on deployment is a bit light – see the Production Topologies Redbook for more detail), and the hints ‘n’ tips chapter seems messy, but generally, it seems excellent for a beginner trying to learn these products.

(In the interests of disclosure, I received only a free copy of the book for this review).

DynaCache Cache Replication with WebSphere Process Server and ESB

As I blogged about previously, there is a useful technique which involves inserting Java components into SCA modules to cache the results of services using the DynaCache mechanism of WebSphere Application Server. See Gabriel Telerman’s excellent article for more information.

However, if you deploy applications using this technique across a WebSphere cluster, which is fairly typical of a production WebSphere environment, you’ll most likely want to look into WebSphere cache replication (using DRS – the data replication service). This means that rather than having an independent caches on each cluster member (i.e. each server), you’ll have caches that replicate data between each other when it is invalidated or updated in the cache.

This is documented in detail towards the bottom of this InfoCenter page, but broadly speaking you’ll want to modify the properties of the object cache you’re already using. In the article referenced above, the default cache services/cache/distributedmap is used, but to extend this with replication across a cluster, it’s probably appropriate to create your own object cache first if you haven’t already. You then need to specify a “replication domain” for that cache (you’ll need to create one if you don’t already have one), and the replication type. Often “Push only” is suitable for most performance requirements – this pushes new cache entries across the cluster when they are created, modified, or invalidated.

Some other points to be aware of:

  • The Data Replication Service doesn’t always start up straight away on server startup – sometimes it will take a few minutes.
  • It’s primarily intended for internal IBM use, but you may find that the tracing string com.ibm.ws.cache.*=all is useful for figuring out what’s going on inside the cache if it’s not behaving as you expect. It will show cache hits, misses, and replication.

WebSphere Business Process Management v7 Production Topologies Draft Redbook Available

This post is a bit of a personal plug, but I’ve just returned from a Redbook Residency writing the book WebSphere Business Process Management (BPM) V7 Production Topologies Redbook, which illustrates how to set up various BPM products for production, including WebSphere Process Server. It’s a fully updated version of the previous book in the series, which was for V6.2 of the BPM products. The book is now available in draft, so please feel free to take a look – you can send feedback via the feedback e-mail address on that page. I’d also encourage you to rate the book, especially if you think it’s good!

Overriding a Web Service Endpoint in WebSphere ESB

When working with Mediation Flows in WebSphere ESB, and you have a Web Service import defined that connects out to an external Web Service, you might want to override the default endpoint. Here’s a (not exhaustive) list of ways to do that (the numbers in brackets indicate the version that the feature is available from):

  • (6.0.2+) The most flexible and long-term way: integrate with the Web Services Registry and Repository product by using the Endpoint Lookup mediation primitive. This allows you to dynamically look up service endpoints (i.e. URLs), by retrieving them from the registry based on criteria you set. The primitive, in some modes, automatically sets the /headers/SMOHeader/Target/address section of the Service Message Object (SMO), which exploits the dynamic callout capability in WebSphere ESB to override the default endpoint when the callout is performed. In other modes, multiple endpoints might be retrieved, so you would to select the appropriate one and populate that section manually.
  • (7.0+) Use the new UDDI Endpoint Lookup primitive, which works in a very similar way to the regular Endpoint Lookup primitive, but instead looks up endpoints from a UDDI registry.
  • (6.0.2+) Use the dynamic callout facilities of WebSphere ESB directly by populating the /headers/SMOHeader/Target/address section of the SMO directly. You could do this by writing your own logic in a custom mediation, for example, or you could populate it with a hardcoded value using a Message Element Setter.
  • (6.0.1+) Override the endpoint statically in the admin console after deploying the application. To do this, you’d first locate the relevant SCA module deployed in the admin console, then select the import binding you are interested in:
    Then, you can modify the endpoint accordingly:

    This might be useful if you are deploying different copies of your mediation flow to different servers, and wanted to use different endpoints in each case. Note that the methods above, which use dynamic endpoint support, will override whatever you set here, so this is only useful if you aren’t using dynamic endpoint support.

(Note: this tip applies equally to WebSphere Process Server)

Understanding SOAP Action in Mediation Modules

Questions often arise around the SOAPAction header used during Web Service interactions. Despite the name, this is an HTTP header (not a SOAP header) that is sometimes transmitted with SOAP messages to give extra information to the consumer of the service (i.e. the server) about the intention of the Web Service request. The SOAP specification describes the SOAPAction header, but although it gives some examples, leaves the exact usage open to interpretation.

Inside Mediation Modules, the header is used according to these rules:

  • If a SOAPAction header is set in the inbound SOAP request (through a Web Service export), its value will be placed into the /headers/SMOHeader/Action stanza of the Service Message Object (which is used inside the mediation flow to represent the request). Otherwise, the value in /headers/SMOHeader/Action is not set.
  • When an outbound SOAP request is performed (through a dynamic callout, not through a Web Service import), the value placed in /headers/SMOHeader/Action will be used if it is present (so you could set this value, with a Message Element Setter, for example, if you want it to be overridden). Otherwise, it is set to the namespace of your WSDL file, concatenated with the operation name being used – which is a convention frequently used for the contents of SOAPAction: e.g. http://myhost/mynamespace/myoperation.
  • When an outbound SOAP request is performed (through a Web Service import), a soapAction attribute might be specified in the <wsdl:operation>/<soap:operation> section of the Web Service Port WSDL attached to the import. If so, that value will be used as the SOAP Action.

Thanks for Matt Roberts and Jens Engelke for the help with this tip.