Previously the developer was responsible for setting up the client side handler chain. This has proven problematic as the code is rather cumbersome and it's easy to make a mistake. Here's an example of what the client code used to look like:
import org.jboss.jbossts.txbridge.outbound.JaxWSTxOutboundBridgeHandler;
import org.jboss.jbossts.txbridge.outbound.JaxWSHeaderContextProcessor;
...
MyService client = service.getPort(portName, MyService.class);
BindingProvider bindingProvider = (BindingProvider) client;
List handlers = new ArrayList();
handlers.add(new JaxWSTxOutboundBridgeHandler());
handlers.add(new JaxWSHeaderContextProcessor());
bindingProvider.getBinding().setHandlerChain(handlers);
import org.jboss.jbossts.txbridge.outbound.JaxWSHeaderContextProcessor;
...
MyService client = service.getPort(portName, MyService.class);
BindingProvider bindingProvider = (BindingProvider) client;
List handlers = new ArrayList();
handlers.add(new JaxWSTxOutboundBridgeHandler());
handlers.add(new JaxWSHeaderContextProcessor());
bindingProvider.getBinding().setHandlerChain(handlers);
In this example, the application has begun a JTA transaction and is now invoking a Web service. The service supports WS-AT, and the developer would like the JTA transaction to be distributed to this service. Therefore, the developer carefully constructs a client side handler chain and ensures that the bridging handler is invoked before the XTS handler. Get this order wrong and the bridging will fail. This code is required for every Web service port that needs to propagate a WS-AT or WS-BA transaction.
We still support the above way of writing clients and the behaviour of XTS in that case has not changed. However, we now have some additional ways to enable a distributed transaction over Web services.
Enable Globally
You can now enable transaction propagation for all Web service calls that are invoked within a JTA, WS-AT or WS-BA transaction. This is done with the 'defaultContextPropagation' property in the XTS subsystem config of the standalone-xts.xml.<subsystem xmlns="urn:jboss:domain:xts:1.0">
<xts-environment url="..." />
<default-context-propagation enabled="true" />
</subsystem>
As this is enabled by default (for standalone-xts.xml), calls to all Web services that support WS-AT or WS-BA will automatically receive the transaction context allowing them to participate in the distributed transaction.
The transaction context is simply ignored if the service does not support WS-AT or WS-BA. This is done by setting MustUnderstand=”false” on the 'CoordinationContext' SOAP header. Unfortunately, this may cause issues when invoking WS-AT or WS-BA enabled Web services on other vendors’ application servers. This is because the WS-Coordination specification states that MustUnderstand must be set to true. If you are affected by this issue, you will need to explicitly enable the transaction propagation as described in the next section.
There is a slight overhead associated with having an unused WS-AT transaction in place. We intend to investigate this as part of https://issues.jboss.org/browse/JBTM-1515
Enable/Disable per Web service port
The default context propagation policy can also be overridden on a per Web Service port basis. This allows the developer to easily state which Web Service clients must and must-not propagate the transaction context.In the following example, the developer states that the current JTA transaction must be distributed over the Web Service calls on this port:
import org.jboss.jbossts.txbridge.outbound.JTAOverWSATFeature;
...
MyService client = service.getPort(portName, MyService.class, new JTAOverWSATFeature());
...
MyService client = service.getPort(portName, MyService.class, new JTAOverWSATFeature());
This is done through the standard JAX-WS WebServiceFeature facility. A JAX-WS WebServiceFeature allows meta-information to be added to a port that describe cross-cutting behaviour, such as logging, security or compression. In our case we use the 'JTAOverWSATFeature' to state that any JTA (or WS-AT) transaction should be distributed via calls on this client. Calls to this service will fail if the Web service does not support WS-AT or WS-BA (in this case, XTS sets MustUnderstand=true on the 'CoordinationContext' SOAP header as the developer has explicitly stated that it is required).
The developer may also state that the transaction must-not be distributed over calls to this Web service. This is done by setting the 'JTAOverWSATFeature' feature to disabled:
import org.jboss.jbossts.txbridge.outbound.JTAOverWSATFeature;
...
MyService client = service.getPort(portName, MyService.class, new JTAOverWSATFeature(false));
...
MyService client = service.getPort(portName, MyService.class, new JTAOverWSATFeature(false));
The use of 'JTAOverWSATFeature' overrides whatever default context propagation is set to in the standalone-xts.xml.