« October 2006 | Main | March 2007 »

February 2007 Archives

February 1, 2007

Porting JAX-WS applications across web services toolkits

One of the proposed benefits of a specification like JAX-WS or JAX-RPC is that you can easily move your application code from an existing web-services toolkit to another - the specification-compliant APIs used in one toolkit should be compatible with those of another toolkit.

I recently put this idea to the test when I migrated a load of ObjectWeb Celtix application code to CXF. For those that don't know, Celtix, the open source ESB that originally resided at ObjectWeb, moved to Apache last year, merging with the XFire project to become CXF. CXF has an substantially different runtime to ObjectWeb Celtix, and can be considered an entirely different toolkit.

By the way, IONA's "Celtix Enterprise" product contains CXF as its JAX-WS core runtime. Just for clarity, I use the terms "Objectweb Celtix" and "Celtix Enterprise" instead of "Celtix" on its own, to distinguish between the original ObjectWeb project and the IONA offering based on CXF.

So - how did I get on? The porting turned out to be much easier than I thought: JAX-WS does have its advantages. As you'd expect, however, my porting effort was not uneventful. Here are some areas to look out for if you're attempting something similar.

Packaging, building and environment

The development environment changed (slightly) from ObjectWeb Celtix to CXF; for example, instead of a CELTIX_HOME environment variable you should set CXF_HOME. Also, an obvious difference is that the classpath has changed significantly: you need to modify your Ant files so that the new JARs are picked up.

Some other not-so-obvious issues arise: I went looking for some XML Schema definitions for configuration beans in CXF and couldn't find them under the CXF installation directory; it turns out that these schema are all held in a JAR file in the CXF distribution.

Toolkit specific APIs

While the JAX-WS specification covers the bulk of the APIs for implementing your service and creating an endpoint, every toolkit typically supplies its own APIs to do additional things such as configuration, registration of handlers, etc. ObjectWeb Celtix had the concept of a Bus, implemented by the class org.objectweb.Celtix.Bus. CXF also has a Bus concept; however, the CXF Bus is is located in a different class (org.apache.cxf.Bus) and has a different API for instance creation.

If your application relies heavily on toolkit-specific APIs then you will have to take this into account when you being a porting or migration activity

Implementation glitches

I was surprised to find some implementation differences on the interpretation of the specification. Thankfully, these were small and easily fixed; however, the experience has pointed out that there's no substitute for testing.

For example, if you call the JAX-WS getPort() API on a client side service object then, in CXF, you must specify the target namespace of the WSDL contract as the namespace of the port name, like this:

HelloWorld helloWorld = helloWorldService.getPort(
    new QName("http://www.my/wsdl/target/namespace",     
    "SOAPOverHTTPEndpoint"),
    HelloWorld.class );

In Celtix you could leave the namespace of the port name as an empty string "". If you do this in CXF then the call to getPort() will fail. It turns out that this latter behaviour (in CXF) is more in keeping with the JAX-WS specification (see Section 4.2.3 of the JAX-WS Specification).

Based on my experience, I put some notes on the "Celtix Migration Page" in the CXF user guide. If I come up with any other migration issues then I'll submit them there to keep them in the one place.

Getting people started with Web Services

One of my responsibilities as Principal Consultant in IONA Technologies is developing training material for our Web Services offerings - some time ago we realised that the best people to write training material are people who are using the products day-in, day-out on customer sites on real customer projects. Given my previous existance as a lecturer in National University of Ireland, Maynooth I was keen to lend my efforts to our training program.

So - what should a basic web services training course contain? When I started contributing to our Celtix, Artix and Axis developer-training material I took a really pragmatic approach: what does a developer need to know to be effective after a 3 or 4 day course? Here's some guiding principles I came up with - if you're teaching yourself web services, or even writing your own training material, then you might use these principals to focus your activities.

  • Understand WSDL and XSD. You can't design web services without an understanding of WSDL and XML Schema. Believe me, I've tried; even when you adopt a "code-first" approach you end up getting dogged down if you don't understand the fundamentals. Any web services course worth its salt should teach XML schema, show to use WSDL for RPC (both in RPC style and Wrapped-doc-literal), and show how to use WSDL for document-style message.
  • Start Simple. There's nothing like "Hello, World!" to demonstrate the absolute bare minimum of a web services application: how to write a client, create a proxy to a service, invoke, recieve on the far end, and implement back-end code. I'm a big fan of getting the "bread-and-butter" right; if I know that students understand "Hello, World!" then we can move swiftly on to the more advanced material that's so much more rewarding.
  • Build a Real Service. While there is nothing quite like "Hello, World" to get the basics right, students need to build something more complex to flex their new web services muscles. In my training courses I build a web service for receiving a sufficiently complex data structure (an Invoice). I find it pushes understanding of both XML and the mappings to the designated programming language.
  • Teach Best Practise from the Start. This may sound obvious, but so often I've come across software exercises, code samples and WSDL/XSD contracts that make me cringe. If you're going to give an example, then give a good example, and make sure if conforms to accepted best practise. If, on the first formal introduction to a subject, students are submitted to sloppy work, they may inject this sloppiness into their own work. Remember, they may not know any better, but you as an instructor should.
  • Teach the Development Environment. At some point students will go back to their day jobs and build and implement their own services. If they're going to do this then they've got to fully understand the development environment; this includes environment variables, third-party tooling, kit installation, and build/make systems. Don't try to to hide these details by providing a sandbox environment where everying has been set up under the covers: engage your students in setting up and configuring their own environment correctly.
  • Teach Students to Help Themselves. There's only so much you can cover in a course; eventually students are going to encounter some problem after the course and will get stuck. It's important to teach techniques to get them unstuck, for example, how to configure and turn up logging, or view messages on the wire. And on that point, when it comes to configuration, make sure they know the fundamentals of configuring the web services toolkit, and then where to go for more information. The last thing any student wants is a lengthy, yawning, shopping list of configuration variables - leave that to documentation.
  • Teach Security. I like to think that any service worth its salt needs some element of security, even if just at the level of secure transport, like HTTPS, and simple username/password authentication schemes via HTTP Basic Authentication or Web Services Security Extensions (WSSE). Implementing a service with a straightforward username-password authentication scheme is fun, and it can spark off discussion about more complex security considerations.

We've put these principals to the test in our Artix and Celtix and Web Services Bootcamp standard material, and our student feedback has been terrific. When students get this fundamental material, they're ready to devour more advanced web services topics, like reliable messaging, transactions, routing, replication and session-managment strategies. Most importantly, though, with the basics in place, they're ready to get to work designing, building and deploying web services.

February 8, 2007

Rapid SOA service test and simulation with Artix

In any production distributed system, testing is crucial: services don't make it into the production environment unless they've passed rigorous tests in unit, system, and user-acceptance environments. Running services in non-production environments is typically easy if you have all the deployment artifacts close to hand, and a bed of appropriate sample data to fuel testing - generally, in any solid development environment, this is going to be the case.

Many services, however, do not live in isolation: the implementation of their business logic may require other services further down-stream. So, in order to test your service, you've got to deploy the down-stream services as well. Sometimes, however, you don't have access to the back-end service deployment artifacts, so you can't deploy an instance of this service in your test environment.

I worked recently with a customer who had exactly this problem: their system depended on a third-party service for which no test environment was readily available. As a result, they could not test their own service in a timely fashion; instead, they had to negotiate a "testing window" with the third-party, and run all their tests within this testing window. The delays in making these test windows available were seriously impacting this customers ability to roll-out new releases of their product, holding up their design, test and development process.

So - how does Artix solve this problem? Using Artix it's possible to rapidly build and deploy a service simulator (or "stub") that can be deployed in a test environment, allowing you to continue with the testing of your core systems. Using Artix allows you to pursue a number of different "Service Simulation" strategies:

  • Randomized Service Simulator.Using Artix's code generation tooling, a service implementation can be generated, compiled and deployed in minutes that generates randomized responses to incoming requests. This is a great way to ensure that connectivity between your software and the stub is being exercised, and can assist in performance and stability testing. One draw back of this approach is that, if your own system performs data validation, then the random values returned may be inappropriate.
  • Black-box Service Simulator.Using the Artix "Universal Test Harness" framework, you can define a set of pre-canned responses, providing rules on when each response should be used. For example, if a valdateCreditCardNo() operation arrives with a well-known test string such as "1234-1234-1234-1234", then return a response that indicates a successful validation.

    Black-box stubs can be built in a matter of hours, and are suitable for stateless services where all the information required to return a valid response is present in the incoming message. The approach is called "black-box" because it treates the service as a black box and does not attempt to simulate internal business logic of the service.



  • White-box Service Simulator. There are times when black-box approaches (outlined above) are not rich enough to simulate the required behaviour. For example, consider an interaction where a test client invokes getCustomerDetails(String id), updateCustomerDetails(String id, Details d) and then getCustomerDetails(String id). A typical client-side test would expect that the second call to getCustomerDetails() would return a different response from the original call, where the customer's details have been updated accordingly.

    Recall that the black-box approach is good for simulation of stateless services; here, the service is stateful: it must rememember the customer's details across different invocations. This use-case requires white-box simulation, where code is implementated that simulates some of the service's internal business logic. Artix provide a set of productivity tools, through its tight integration with Eclipse, that allow such services to be rapidly constructed within a day or two.


  • The simulation approach you should use is goind to depend on the semantics of the service, and the kind behaviour you want to simulate.

February 27, 2007

Micro-orchestration: using the Celtix Router as an application container

Usually when I think of JAX-WS application development I like to think in terms of the classic contract-first development model: generate your stubs from the WSDL file using wsdl2java, then implement your endpoint in Java. The endpoint can then be deployed from a standalone server mainline, or any of the containers supported by Celtix such as ServiceMix (JBI) or Spring. I was happily surprised recently when an inventive customer recently suggested an interesting alternative. They proposed the following (non-obvious) development scenario: why not design your application as a route and deploy in the Celtix router?

The idea is beautiful in its simplicity: write your application logic as a set of Plain Old Java Objects (POJOs), and then use the Celtix Router (based on the Mule container) to string them all together. At the start of the route, deploy a Celtix listener, based on a formal WSDL contract: the router can listen for requests, unmarshall incoming data to Java objects (using JAX-B), and then forward these objects to your business logic. The router will let you chain a whole set of POJOs, allowing you to design your application as a pipeline of modular and reusable POJO-based business components. And, at the end of the chain, you can let Celtix consume the POJO results and marshal them back onto the wire, either as a synchronous response to the original invocation, or onward to another remote service in an asynchronous application.

I worked with the customer to put together a POC, and we're building on this POC towards a production-ready deployment.

Ultimately, this approach allows you to design applications as mini orchestrations, providing the flexibility of an orchestration engine without the penalty of remote message invocations between each component. I like it.

About February 2007

This page contains all entries posted to SOS in February 2007. They are listed from oldest to newest.

October 2006 is the previous archive.

March 2007 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.31