Monday, March 25, 2013

API Improvements for WS-AT and REST-AT

In this post I’ll introduce some API changes we are doing to improve the way developers use WS-AT and REST-AT.

I’m a strong believer that the internal architecture of your application, and the means by which client’s communicate with it, are two orthogonal issues. You wouldn’t want to have to change the internals of your application, just because you need to change the way clients invoke your service.

We think you should be able to develop your applications using a common Transactions API. You should then be able to invoke remote services over whatever transport is appropriate and automatically have the transaction distributed. Furthermore, you shouldn’t be restricted to having all participants use the same transport.

There really is only one option for a Java “common Transactions API” - it’s JTA. JTA is well supported in Java EE application servers and it is well understood by developers. Furthermore, there are many applications out there already using JTA.

This is what we are moving towards with each milestone release of Narayana 5.0.0. With milestone two we made it very simple for a pure JTA client to invoke a JTA application over Web Services in a distributed transaction. Take a look at the following example:

Client


@Stateless
public class OrderClient {

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public void orderItem(String item, String address, double amount) {

    AccountService as = //Lookup AccountService WS client
    WarehouseService ws = //Lookup WarehouseService WS client

    ws.shipItem(item, address);
    as.invoiceCustomer(address, amount);
  }
}


Here the client is using a regular Stateless Session Bean. The method ‘orderItem’ is invoked in a JTA transaction that is committed if the method succeeds and rolled back if it fails.

The calls to the Warehouse and Account services automatically use WS-AT to distribute the JTA transaction. The middleware knows to do this because a JTA transaction was present when the Web Service call was invoked.

Transaction propagation can be configured, but that’s the subject of another blog post (stay tuned).

Service


@Transactional //Currently required, will be removed soon https://issues.jboss.org/browse/JBTM-1468
@Stateless
//JAX-WS annotations omitted for brevity
public class WarehouseServiceImpl implements WarehouseService {

    @PersistenceContext
    protected EntityManager em;

    @WebMethod
    public void shipItem(String item, String address) {
        // Use the Entity Manager to 
        // add an item and shipping address to DB
    }
}

Again the service is implemented as a simple Stateless Session bean that just happens to be offered as a Web Service. Here the application is using JTA to make a database update. The middleware automatically handles the mapping between the incoming WS-AT transaction and the JTA transaction.

What About Other Transports?

With milestone two we already support transparent propagation over Web Services (via WS-AT), Corba (via JTS) and JBoss Remoting. We hope to have REST-AT support in a subsequent milestone release (see JBTM-1468).

Getting Started

Hopefully you are now eager to try this out. The best place to look is at this quickstart, which demonstrates the new API in action.


Acknowledgements

I'd like to say a big thank you to Alessio Soldano and the JBossWS team. They provided a lot of advice and also added new features to the JBossWS SPI to support this feature.

No comments: