JBoss Community Archive (Read Only)

JBoss AS 7.2

Reliable Messaging

JBoss Web Services inherits full WS-Reliable Messaging capabilities from the underlying Apache CXF implementation. At the time of writing, Apache CXF provides support for the WS-Reliable Messaging 1.0 (February 2005) version of the specification.

Enabling WS-Reliable Messaging

WS-Reliable Messaging is implemented internally in Apache CXF through a set of interceptors that deal with the low level requirements of the reliable messaging protocol. In order for enabling WS-Reliable Messaging, users need to either:

  • consume a WSDL contract that specifies proper WS-Reliable Messaging policies / assertions

  • manually add / configure the reliable messaging interceptors

  • specify the reliable messaging policies in an optional CXF Spring XML descriptor

  • specify the Apache CXF reliable messaging feature in an optional CXF Spring XML descriptor

The former approach relies on the Apache CXF WS-Policy engine and is the only portable one. The other approaches are Apache CXF proprietary ones, however they allow for fine-grained configuration of protocol aspects that are not covered by the WS-Reliable Messaging Policy. More details are available in the Apache CXF documentation.

Example

In this example we configure WS-Reliable Messaging endpoint and client through the WS-Policy support.

Endpoint

We go with a contract-first approach, so we start by creating a proper WSDL contract, containing the WS-Reliable Messaging and WS-Addressing policies (the latter is a requirement of the former):

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="SimpleService" targetNamespace="http://www.jboss.org/jbossws/ws-extensions/wsrm"
  xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/wsrm" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:wsp="http://www.w3.org/2006/07/ws-policy">

  <wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/wsrm"
  attributeFormDefault="unqualified" elementFormDefault="unqualified"
  targetNamespace="http://www.jboss.org/jbossws/ws-extensions/wsrm">
<xsd:element name="ping" type="tns:ping"/>
<xsd:complexType name="ping">
<xsd:sequence/>
</xsd:complexType>
<xsd:element name="echo" type="tns:echo"/>
<xsd:complexType name="echo">
<xsd:sequence>
<xsd:element minOccurs="0" name="arg0" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="echoResponse" type="tns:echoResponse"/>
<xsd:complexType name="echoResponse">
<xsd:sequence>
<xsd:element minOccurs="0" name="return" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
  </wsdl:types>
  <wsdl:message name="echoResponse">
    <wsdl:part name="parameters" element="tns:echoResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="echo">
    <wsdl:part name="parameters" element="tns:echo">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="ping">
    <wsdl:part name="parameters" element="tns:ping">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="SimpleService">
    <wsdl:operation name="ping">
      <wsdl:input name="ping" message="tns:ping">
    </wsdl:input>
    </wsdl:operation>
    <wsdl:operation name="echo">
      <wsdl:input name="echo" message="tns:echo">
    </wsdl:input>
      <wsdl:output name="echoResponse" message="tns:echoResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="SimpleServiceSoapBinding" type="tns:SimpleService">
    <wsp:Policy>
      <!-- WS-Addressing and basic WS-Reliable Messaging policy assertions -->
      <wswa:UsingAddressing xmlns:wswa="http://www.w3.org/2006/05/addressing/wsdl"/>
      <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"/>
      <!-- --------------------------------------------------------------- -->
    </wsp:Policy>
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="ping">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="ping">
        <soap:body use="literal"/>
      </wsdl:input>
    </wsdl:operation>
    <wsdl:operation name="echo">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="echo">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="echoResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="SimpleService">
    <wsdl:port name="SimpleServicePort" binding="tns:SimpleServiceSoapBinding">
      <soap:address location="http://localhost:8080/jaxws-samples-wsrm-api"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Then we use the wsconsume tool to generate both standard JAX-WS client and endpoint.

We provide a basic JAX-WS implementation for the endpoint, nothing special in it:

package org.jboss.test.ws.jaxws.samples.wsrm.service;

import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
(
   name = "SimpleService",
   serviceName = "SimpleService",
   wsdlLocation = "WEB-INF/wsdl/SimpleService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsrm"
)
public class SimpleServiceImpl
{
   @Oneway
   @WebMethod
   public void ping()
   {
      System.out.println("ping()");
   }

   @WebMethod
   public String echo(String s)
   {
      System.out.println("echo(" + s + ")");
      return s;
   }
}

Finally we package the generated POJO endpoint together with a basic web.xml the usual way and deploy to the application server. The webservices stack automatically detects the policies and enables WS-Reliable Messaging.

Client

The endpoint advertises his RM capabilities (and requirements) through the published WSDL and the client is required to also enable WS-RM for successfully exchanging messages with the server.

So a regular JAX WS client is enough if the user does not need to tune any specific detail of the RM subsystem.

QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService");
URL wsdlURL = new URL("http://localhost:8080/jaxws-samples-wsrm-api?wsdl");
Service service = Service.create(wsdlURL, serviceName);
proxy = (SimpleService)service.getPort(SimpleService.class);
proxy.echo("Hello World!");

Additional configuration

Fine-grained tuning of WS-Reliable Messaging engine requires setting up proper RM features in the Bus using a Spring XML descriptor; here is an example:

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:cxf="http://cxf.apache.org/core"
  xmlns:wsa="http://cxf.apache.org/ws/addressing"
  xmlns:http="http://cxf.apache.org/transports/http/configuration"
  xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
  xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
  xsi:schemaLocation="
    http://cxf.apache.org/core
    http://cxf.apache.org/schemas/core.xsd
    http://cxf.apache.org/transports/http/configuration
    http://cxf.apache.org/schemas/configuration/http-conf.xsd
    http://schemas.xmlsoap.org/ws/2005/02/rm/policy
    http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd
    http://cxf.apache.org/ws/rm/manager
    http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

  <cxf:bus>
    <cxf:features>
      <cxf:logging/>
      <wsa:addressing/>
      <wsrm-mgr:reliableMessaging>
        <wsrm-policy:RMAssertion>
          <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>
          <wsrm-policy:AcknowledgementInterval Milliseconds="2000"/>
        </wsrm-policy:RMAssertion>
        <wsrm-mgr:destinationPolicy>
          <wsrm-mgr:acksPolicy intraMessageThreshold="0" />
        </wsrm-mgr:destinationPolicy>
      </wsrm-mgr:reliableMessaging>
    </cxf:features>
  </cxf:bus>
</beans

The client needs to pick up the bus configuration such as below:

package org.jboss.test.ws.jaxws.samples.wsrm.client;

import java.net.URL;
import java.io.File;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory;
import org.jboss.test.ws.jaxws.samples.wsrm.generated.SimpleService;

public final class SimpleServiceTestCase
{
   private static final String serviceURL = "http://localhost:8080/jaxws-samples-wsrm/SimpleService";

   public static void main(String[] args) throws Exception
   {
      URL cxfConfig = new File("resources/jaxws/samples/wsrm/cxf.xml").toURL();
      Bus bus = new JBossWSBusFactory().createBus(cxfConfig);
      try
      {
          BusFactory.setThreadDefaultBus(bus);

          // create service
          QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService");
          URL wsdlURL = new URL(serviceURL + "?wsdl");
          Service service = Service.create(wsdlURL, serviceName);
          SimpleService proxy = (SimpleService)service.getPort(SimpleService.class);

          // invoke methods
          proxy.echo("Hello World!");
      }
      finally
      {
          // shutdown bus
          bus.shutdown(true);
      }
   }
}
JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:28:29 UTC, last content change 2012-02-15 14:00:21 UTC.