Chapter 21. Enabling Reliable Messaging

Abstract

Apache CXF supports WS-Reliable Messaging(WS-RM). This chapter explains how to enable and configure WS-RM in Apache CXF.

21.1. Introduction to WS-RM

Overview

WS-ReliableMessaging (WS-RM) is a protocol that ensures the reliable delivery of messages in a distributed environment. It enables messages to be delivered reliably between distributed applications in the presence of software, system, or network failures.

For example, WS-RM can be used to ensure that the correct messages have been delivered across a network exactly once, and in the correct order.

How WS-RM works

WS-RM ensures the reliable delivery of messages between a source and a destination endpoint. The source is the initial sender of the message and the destination is the ultimate receiver, as shown in Figure 21.1, “Web Services Reliable Messaging”.

Figure 21.1. Web Services Reliable Messaging

reliable message exchange

The flow of WS-RM messages can be described as follows:

  1. The RM source sends a CreateSequence protocol message to the RM destination. This contains a reference for the endpoint that receives acknowledgements (the wsrm:AcksTo endpoint).
  2. The RM destination sends a CreateSequenceResponse protocol message back to the RM source. This message contains the sequence ID for the RM sequence session.
  3. The RM source adds an RM Sequence header to each message sent by the application source. This header contains the sequence ID and a unique message ID.
  4. The RM source transmits each message to the RM destination.
  5. The RM destination acknowledges the receipt of the message from the RM source by sending messages that contain the RM SequenceAcknowledgement header.
  6. The RM destination delivers the message to the application destination in an exactly-once-in-order fashion.
  7. The RM source retransmits a message that it has not yet received an acknowledgement.

    The first retransmission attempt is made after a base retransmission interval. Successive retransmission attempts are made, by default, at exponential back-off intervals or, alternatively, at fixed intervals. For more details, see Section 21.5, “Configuring WS-RM”.

This entire process occurs symmetrically for both the request and the response message; that is, in the case of the response message, the server acts as the RM source and the client acts as the RM destination.

WS-RM delivery assurances

WS-RM guarantees reliable message delivery in a distributed environment, regardless of the transport protocol used. Either the source or the destination endpoint logs an error if reliable delivery can not be assured.

Supported specifications

Apache CXF supports the following versions of the WS-RM specification:

WS-ReliableMessaging 1.0

(Default) Corresponds to the February 2005 submission version, which is now out of date. For reasons of backward compatibility, however, this version is used as the default.

Version 1.0 of WS-RM uses the following namespace:

http://schemas.xmlsoap.org/ws/2005/02/rm/

This version of WS-RM can be used with either of the following WS-Addressing versions:

http://schemas.xmlsoap.org/ws/2004/08/addressing (default)
http://www.w3.org/2005/08/addressing

Strictly speaking, in order to comply with the February 2005 submission version of WS-RM, you ought to use the first of these WS-Addressing versions (which is the default in Apache CXF). But most other Web service implementations have switched to the more recent WS-Addressing specification, so Apache CXF allows you to choose the WS-A version, to facilitate interoperability (see Section 21.4, “Runtime Control”).

WS-ReliableMessaging 1.1/1.2

Corresponds to the official 1.1/1.2 Web Services Reliable Messaging specification.

Versions 1.1 and 1.2 of WS-RM uses the following namespace:

http://docs.oasis-open.org/ws-rx/wsrm/200702

The 1.1 and 1.2 versions of WS-RM use the following WS-Addressing version:

http://www.w3.org/2005/08/addressing

Selecting the WS-RM version

You can select which WS-RM specification version to use, as follows:

Server side
On the provider side, Apache CXF adapts to whichever version of WS-ReliableMessaging is used by the client and responds appropriately.
Client side
On the client side, the WS-RM version is determined either by the namespace that you use in the client configuration (see Section 21.5, “Configuring WS-RM”) or by overriding the WS-RM version at run time, using the runtime control options (see Section 21.4, “Runtime Control”).

21.2. WS-RM Interceptors

Overview

In Apache CXF, WS-RM functionality is implemented as interceptors. The Apache CXF runtime uses interceptors to intercept and work with the raw messages that are being sent and received. When a transport receives a message, it creates a message object and sends that message through an interceptor chain. If the application’s interceptor chain includes the WS-RM interceptors, the application can participate in reliable messaging sessions. The WS-RM interceptors handle the collection and aggregation of the message chunks. They also handle all of the acknowledgement and retransmission logic.

Apache CXF WS-RM Interceptors

The Apache CXF WS-RM implementation consists of four interceptors, which are described in Table 21.1, “Apache CXF WS-ReliableMessaging Interceptors”.

Table 21.1. Apache CXF WS-ReliableMessaging Interceptors

InterceptorDescription

org.apache.cxf.ws.rm.RMOutInterceptor

Deals with the logical aspects of providing reliability guarantees for outgoing messages.

Responsible for sending the CreateSequence requests and waiting for their CreateSequenceResponse responses.

Also responsible for aggregating the sequence properties—ID and message number—for an application message.

org.apache.cxf.ws.rm.RMInInterceptor

Responsible for intercepting and processing RM protocol messages and SequenceAcknowledgement messages that are piggybacked on application messages.

org.apache.cxf.ws.rm.RMCaptureInInterceptor

Caching incoming messages for persistent storage.

org.apache.cxf.ws.rm.RMDeliveryInterceptor

Assuring InOrder delivery of messages to the application.

org.apache.cxf.ws.rm.soap.RMSoapInterceptor

Responsible for encoding and decoding the reliability properties as SOAP headers.

org.apache.cxf.ws.rm.RetransmissionInterceptor

Responsible for creating copies of application messages for future resending.

Enabling WS-RM

The presence of the WS-RM interceptors on the interceptor chains ensures that WS-RM protocol messages are exchanged when necessary. For example, when intercepting the first application message on the outbound interceptor chain, the RMOutInterceptor sends a CreateSequence request and waits to process the original application message until it receives the CreateSequenceResponse response. In addition, the WS-RM interceptors add the sequence headers to the application messages and, on the destination side, extract them from the messages. It is not necessary to make any changes to your application code to make the exchange of messages reliable.

For more information on how to enable WS-RM, see Section 21.3, “Enabling WS-RM”.

Configuring WS-RM Attributes

You control sequence demarcation and other aspects of the reliable exchange through configuration. For example, by default Apache CXF attempts to maximize the lifetime of a sequence, thus reducing the overhead incurred by the out-of-band WS-RM protocol messages. To enforce the use of a separate sequence per application message configure the WS-RM source’s sequence termination policy (setting the maximum sequence length to 1).

For more information on configuring WS-RM behavior, see Section 21.5, “Configuring WS-RM”.

21.3. Enabling WS-RM

Overview

To enable reliable messaging, the WS-RM interceptors must be added to the interceptor chains for both inbound and outbound messages and faults. Because the WS-RM interceptors use WS-Addressing, the WS-Addressing interceptors must also be present on the interceptor chains.

You can ensure the presence of these interceptors in one of two ways:

  • Explicitly, by adding them to the dispatch chains using Spring beans
  • Implicitly, using WS-Policy assertions, which cause the Apache CXF runtime to transparently add the interceptors on your behalf.

Spring beans: explicitly adding interceptors

To enable WS-RM add the WS-RM and WS-Addressing interceptors to the Apache CXF bus, or to a consumer or service endpoint using Spring bean configuration. This is the approach taken in the WS-RM sample that is found in the InstallDir/samples/ws_rm directory. The configuration file, ws-rm.cxf, shows the WS-RM and WS-Addressing interceptors being added one-by-one as Spring beans (see Example 21.1, “Enabling WS-RM Using Spring Beans”).

Example 21.1. Enabling WS-RM Using Spring Beans

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/
   beans http://www.springframework.org/schema/beans/spring-beans.xsd">
   <bean id="mapAggregator" class="org.apache.cxf.ws.addressing.MAPAggregator"/>
   <bean id="mapCodec" class="org.apache.cxf.ws.addressing.soap.MAPCodec"/>
   <bean id="rmLogicalOut" class="org.apache.cxf.ws.rm.RMOutInterceptor">
        <property name="bus" ref="cxf"/>
   </bean>
   <bean id="rmLogicalIn" class="org.apache.cxf.ws.rm.RMInInterceptor">
        <property name="bus" ref="cxf"/>
   </bean>
   <bean id="rmCodec" class="org.apache.cxf.ws.rm.soap.RMSoapInterceptor"/>
   <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl">
        <property name="inInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalIn"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
        <property name="inFaultInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalIn"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
        <property name="outInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalOut"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
        <property name="outFaultInterceptors">
            <list>
                <ref bean="mapAggregator">
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalOut"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
    </bean>
</beans>

The code shown in Example 21.1, “Enabling WS-RM Using Spring Beans” can be explained as follows:

A Apache CXF configuration file is a Spring XML file. You must include an opening Spring beans element that declares the namespaces and schema files for the child elements that are encapsulated by the beans element.

Configures each of the WS-Addressing interceptors—MAPAggregator and MAPCodec. For more information on WS-Addressing, see Chapter 20, Deploying WS-Addressing.

Configures each of the WS-RM interceptors—RMOutInterceptor, RMInInterceptor, and RMSoapInterceptor.

Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for inbound messages.

Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for inbound faults.

Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for outbound messages.

Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for outbound faults.

WS-Policy framework: implicitly adding interceptors

The WS-Policy framework provides the infrastructure and APIs that allow you to use WS-Policy. It is compliant with the November 2006 draft publications of the Web Services Policy 1.5—Framework and Web Services Policy 1.5—Attachment specifications.

To enable WS-RM using the Apache CXF WS-Policy framework, do the following:

  1. Add the policy feature to your client and server endpoint. Example 21.2, “Configuring WS-RM using WS-Policy” shows a reference bean nested within a jaxws:feature element. The reference bean specifies the AddressingPolicy, which is defined as a separate element within the same configuration file.

    Example 21.2. Configuring WS-RM using WS-Policy

    <jaxws:client>
        <jaxws:features>
          <ref bean="AddressingPolicy"/>
        </jaxws:features>
    </jaxws:client>
    <wsp:Policy wsu:Id="AddressingPolicy" xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
        <wsam:Addressing>
          <wsp:Policy>
            <wsam:NonAnonymousResponses/>
          </wsp:Policy>
        </wsam:Addressing>
    </wsp:Policy>
  2. Add a reliable messaging policy to the wsdl:service element—or any other WSDL element that can be used as an attachment point for policy or policy reference elements—to your WSDL file, as shown in Example 21.3, “Adding an RM Policy to Your WSDL File”.

    Example 21.3. Adding an RM Policy to Your WSDL File

    <wsp:Policy wsu:Id="RM"
       xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
            <wsp:Policy/>
        </wsam:Addressing>
        <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
            <wsrmp:BaseRetransmissionInterval Milliseconds="10000"/>
        </wsrmp:RMAssertion>
    </wsp:Policy>
    ...
    <wsdl:service name="ReliableGreeterService">
        <wsdl:port binding="tns:GreeterSOAPBinding" name="GreeterPort">
            <soap:address location="http://localhost:9020/SoapContext/GreeterPort"/>
            <wsp:PolicyReference URI="#RM" xmlns:wsp="http://www.w3.org/2006/07/ws-policy"/>
        </wsdl:port>
    </wsdl:service>

21.4. Runtime Control

Overview

Several message context property values can be set in client code to control WS-RM at runtime, with key values defined by public constants in the org.apache.cxf.ws.rm.RMManager class.

Runtime control options

The following table lists the keys defined by the org.apache.cxf.ws.rm.RMManager class.

KeyDescription

WSRM_VERSION_PROPERTY

String WS-RM version namespace (http://schemas.xmlsoap.org/ws/2005/02/rm/ or http://docs.oasis-open.org/ws-rx/wsrm/200702).

WSRM_WSA_VERSION_PROPERTY

String WS-Addressing version namespace (http://schemas.xmlsoap.org/ws/2004/08/addressing or http://www.w3.org/2005/08/addressing) - this property is ignored unless you’re using the http://schemas.xmlsoap.org/ws/2005/02/rm/ RM namespace).

WSRM_LAST_MESSAGE_PROPERTY

Boolean value true to tell the WS-RM code that the last message is being sent, allowing the code to close the WS-RM sequence and release resources (as of the 3.0.0 version of CXF, the WS-RM will close the RM sequence by default, when you close your client).

WSRM_INACTIVITY_TIMEOUT_PROPERTY

Long inactivity timeout in milliseconds.

WSRM_RETRANSMISSION_INTERVAL_PROPERTY

Long base retransmission interval in milliseconds.

WSRM_EXPONENTIAL_BACKOFF_PROPERTY

Boolean exponential back-off flag.

WSRM_ACKNOWLEDGEMENT_INTERVAL_PROPERTY

Long acknowledgement interval in milliseconds.

Controlling WS-RM through JMX

You can also monitor and control many aspects of WS-RM using the JMX Management features of Apache CXF. The full list of JMX operations is defined by org.apache.cxf.ws.rm.ManagedRMManager and org.apache.cxf.ws.rm.ManagedRMEndpoint, but these operations include viewing the current RM state down to the individual message level. You can also use JXM to close or terminate a WS-RM sequence, and to receive notification of when previously-sent messages are acknowledged by the remote RM endpoint.

Example of JMX control

For example, if you have the JMX server enabled in your client configuration, you could use the following code to track the last acknowledgement number received:

// Java
private static class AcknowledgementListener implements NotificationListener {
    private volatile long lastAcknowledgement;

    @Override
    public void handleNotification(Notification notification, Object handback) {
        if (notification instanceof AcknowledgementNotification) {
            AcknowledgementNotification ack = (AcknowledgementNotification)notification;
            lastAcknowledgement = ack.getMessageNumber();
        }
    }

    // initialize client
...
    // attach to JMX bean for notifications
    //  NOTE: you must have sent at least one message to initialize RM before executing this code
    Endpoint ep = ClientProxy.getClient(client).getEndpoint();
    InstrumentationManager im = bus.getExtension(InstrumentationManager.class);
    MBeanServer mbs = im.getMBeanServer();
    RMManager clientManager = bus.getExtension(RMManager.class);
    ObjectName name = RMUtils.getManagedObjectName(clientManager, ep);
    System.out.println("Looking for endpoint name " + name);
    AcknowledgementListener listener = new AcknowledgementListener();
    mbs.addNotificationListener(name, listener, null, null);

    // send messages using RM with acknowledgement status reported to listener
...

21.5. Configuring WS-RM

21.5.1. Configuring Apache CXF-Specific WS-RM Attributes

Overview

To configure the Apache CXF-specific attributes, use the rmManager Spring bean. Add the following to your configuration file:

Example 21.4, “Configuring Apache CXF-Specific WS-RM Attributes” shows a simple example.

Example 21.4. Configuring Apache CXF-Specific WS-RM Attributes

&lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://cxf.apache.org/ws/rm/manager http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd"&gt;
...
&lt;wsrm-mgr:rmManager&gt;
&lt;!--
  ...Your configuration goes here
--&gt;
&lt;/wsrm-mgr:rmManager&gt;

Children of the rmManager Spring bean

Table 21.2, “Children of the rmManager Spring Bean” shows the child elements of the rmManager Spring bean, defined in the http://cxf.apache.org/ws/rm/manager namespace.

Table 21.2. Children of the rmManager Spring Bean

ElementDescription

RMAssertion

An element of type RMAssertion

deliveryAssurance

An element of type DeliveryAssuranceType that describes the delivery assurance that should apply

sourcePolicy

An element of type SourcePolicyType that allows you to configure details of the RM source

destinationPolicy

An element of type DestinationPolicyType that allows you to configure details of the RM destination

Example

For an example, see the section called “Maximum unacknowledged messages threshold”.

21.5.2. Configuring Standard WS-RM Policy Attributes

Overview

You can configure standard WS-RM policy attributes in one of the following ways:

WS-Policy RMAssertion Children

Table 21.3, “Children of the WS-Policy RMAssertion Element” shows the elements defined in the http://schemas.xmlsoap.org/ws/2005/02/rm/policy namespace:

Table 21.3. Children of the WS-Policy RMAssertion Element

NameDescription

InactivityTimeout

Specifies the amount of time that must pass without receiving a message before an endpoint can consider an RM sequence to have been terminated due to inactivity.

BaseRetransmissionInterval

Sets the interval within which an acknowledgement must be received by the RM Source for a given message. If an acknowledgement is not received within the time set by the BaseRetransmissionInterval, the RM Source will retransmit the message.

ExponentialBackoff

Indicates the retransmission interval will be adjusted using the commonly known exponential backoff algorithm (Tanenbaum).

For more information, see Computer Networks, Andrew S. Tanenbaum, Prentice Hall PTR, 2003.

AcknowledgementInterval

In WS-RM, acknowledgements are sent on return messages or sent stand-alone. If a return message is not available to send an acknowledgement, an RM Destination can wait for up to the acknowledgement interval before sending a stand-alone acknowledgement. If there are no unacknowledged messages, the RM Destination can choose not to send an acknowledgement.

More detailed reference information

For more detailed reference information, including descriptions of each element’s sub-elements and attributes, please refer to http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd.

RMAssertion in rmManager Spring bean

You can configure standard WS-RM policy attributes by adding an RMAssertion within a Apache CXF rmManager Spring bean. This is the best approach if you want to keep all of your WS-RM configuration in the same configuration file; that is, if you want to configure Apache CXF-specific attributes and standard WS-RM policy attributes in the same file.

For example, the configuration in Example 21.5, “Configuring WS-RM Attributes Using an RMAssertion in an rmManager Spring Bean” shows:

  • A standard WS-RM policy attribute, BaseRetransmissionInterval, configured using an RMAssertion within an rmManager Spring bean.
  • An Apache CXF-specific RM attribute, intraMessageThreshold, configured in the same configuration file.

Example 21.5. Configuring WS-RM Attributes Using an RMAssertion in an rmManager Spring Bean

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
       xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>
    </wsrm-policy:RMAssertion>
    <wsrm-mgr:destinationPolicy>
        <wsrm-mgr:acksPolicy intraMessageThreshold="0" />
    </wsrm-mgr:destinationPolicy>
</wsrm-mgr:rmManager>
</beans>

Policy within a feature

You can configure standard WS-RM policy attributes within features, as shown in Example 21.6, “Configuring WS-RM Attributes as a Policy within a Feature”.

Example 21.6. Configuring WS-RM Attributes as a Policy within a Feature

<xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:wsa="http://cxf.apache.org/ws/addressing"
        xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="
http://www.w3.org/2006/07/ws-policy http://www.w3.org/2006/07/ws-policy.xsd
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schema/ws/addressing.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <jaxws:endpoint name="{http://cxf.apache.org/greeter_control}GreeterPort" createdFromAPI="true">
        <jaxws:features>
               <wsp:Policy>
                   <wsrm:RMAssertion xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
                     <wsrm:AcknowledgementInterval Milliseconds="200" />
                   </wsrm:RMAssertion>
                   <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                       <wsp:Policy>
                            <wsam:NonAnonymousResponses/>
                       </wsp:Policy>
                   </wsam:Addressing>
              </wsp:Policy>
        </jaxws:features>
    </jaxws:endpoint>
</beans>

WSDL file

If you use the WS-Policy framework to enable WS-RM, you can configure standard WS-RM policy attributes in a WSDL file. This is a good approach if you want your service to interoperate and use WS-RM seamlessly with consumers deployed to other policy-aware Web services stacks.

For an example, see the section called “WS-Policy framework: implicitly adding interceptors” where the base retransmission interval is configured in the WSDL file.

External attachment

You can configure standard WS-RM policy attributes in an external attachment file. This is a good approach if you cannot, or do not want to, change your WSDL file.

Example 21.7, “Configuring WS-RM in an External Attachment” shows an external attachment that enables both WS-A and WS-RM (base retransmission interval of 30 seconds) for a specific EPR.

Example 21.7. Configuring WS-RM in an External Attachment

<attachments xmlns:wsp="http://www.w3.org/2006/07/ws-policy" xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsp:PolicyAttachment>
        <wsp:AppliesTo>
           <wsa:EndpointReference>
                <wsa:Address>http://localhost:9020/SoapContext/GreeterPort</wsa:Address>
            </wsa:EndpointReference>
        </wsp:AppliesTo>
        <wsp:Policy>
            <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                <wsp:Policy/>
            </wsam:Addressing>
            <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
                <wsrmp:BaseRetransmissionInterval Milliseconds="30000"/>
            </wsrmp:RMAssertion>
        </wsp:Policy>
    </wsp:PolicyAttachment>
</attachments>/

21.5.3. WS-RM Configuration Use Cases

Overview

This subsection focuses on configuring WS-RM attributes from a use case point of view. Where an attribute is a standard WS-RM policy attribute, defined in the http://schemas.xmlsoap.org/ws/2005/02/rm/policy/ namespace, only the example of setting it in an RMAssertion within an rmManager Spring bean is shown. For details of how to set such attributes as a policy within a feature; in a WSDL file, or in an external attachment, see Section 21.5.2, “Configuring Standard WS-RM Policy Attributes”.

The following use cases are covered:

Base retransmission interval

The BaseRetransmissionInterval element specifies the interval at which an RM source retransmits a message that has not yet been acknowledged. It is defined in the http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd schema file. The default value is 3000 milliseconds.

Example 21.8, “Setting the WS-RM Base Retransmission Interval” shows how to set the WS-RM base retransmission interval.

Example 21.8. Setting the WS-RM Base Retransmission Interval

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>

Exponential backoff for retransmission

The ExponentialBackoff element determines if successive retransmission attempts for an unacknowledged message are performed at exponential intervals.

The presence of the ExponentialBackoff element enables this feature. An exponential backoff ratio of 2 is used by default. ExponentialBackoff is a flag. When the element is present, exponential backoff is enabled. When the element is absent, exponential backoff is disabled. No value is required.

Example 21.9, “Setting the WS-RM Exponential Backoff Property” shows how to set the WS-RM exponential backoff for retransmission.

Example 21.9. Setting the WS-RM Exponential Backoff Property

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:ExponentialBackoff/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>

Acknowledgement interval

The AcknowledgementInterval element specifies the interval at which the WS-RM destination sends asynchronous acknowledgements. These are in addition to the synchronous acknowledgements that it sends on receipt of an incoming message. The default asynchronous acknowledgement interval is 0 milliseconds. This means that if the AcknowledgementInterval is not configured to a specific value, acknowledgements are sent immediately (that is, at the first available opportunity).

Asynchronous acknowledgements are sent by the RM destination only if both of the following conditions are met:

  • The RM destination is using a non-anonymous wsrm:acksTo endpoint.
  • The opportunity to piggyback an acknowledgement on a response message does not occur before the expiry of the acknowledgement interval.

Example 21.10, “Setting the WS-RM Acknowledgement Interval” shows how to set the WS-RM acknowledgement interval.

Example 21.10. Setting the WS-RM Acknowledgement Interval

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:AcknowledgementInterval Milliseconds="2000"/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>

Maximum unacknowledged messages threshold

The maxUnacknowledged attribute sets the maximum number of unacknowledged messages that can accrue per sequence before the sequence is terminated.

Example 21.11, “Setting the WS-RM Maximum Unacknowledged Message Threshold” shows how to set the WS-RM maximum unacknowledged messages threshold.

Example 21.11. Setting the WS-RM Maximum Unacknowledged Message Threshold

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:sourcePolicy>
        <wsrm-mgr:sequenceTerminationPolicy maxUnacknowledged="20" />
    </wsrm-mgr:sourcePolicy>
</wsrm-mgr:reliableMessaging>
</beans>

Maximum length of an RM sequence

The maxLength attribute sets the maximum length of a WS-RM sequence. The default value is 0, which means that the length of a WS-RM sequence is unbound.

When this attribute is set, the RM endpoint creates a new RM sequence when the limit is reached, and after receiving all of the acknowledgements for the previously sent messages. The new message is sent using a newsequence.

Example 21.12, “Setting the Maximum Length of a WS-RM Message Sequence” shows how to set the maximum length of an RM sequence.

Example 21.12. Setting the Maximum Length of a WS-RM Message Sequence

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:sourcePolicy>
        <wsrm-mgr:sequenceTerminationPolicy maxLength="100" />
    </wsrm-mgr:sourcePolicy>
</wsrm-mgr:reliableMessaging>
</beans>

Message delivery assurance policies

You can configure the RM destination to use the following delivery assurance policies:

  • AtMostOnce — The RM destination delivers the messages to the application destination only once. If a message is delivered more than once an error is raised. It is possible that some messages in a sequence may not be delivered.
  • AtLeastOnce — The RM destination delivers the messages to the application destination at least once. Every message sent will be delivered or an error will be raised. Some messages might be delivered more than once.
  • InOrder — The RM destination delivers the messages to the application destination in the order that they are sent. This delivery assurance can be combined with the AtMostOnce or AtLeastOnce assurances.

Example 21.13, “Setting the WS-RM Message Delivery Assurance Policy” shows how to set the WS-RM message delivery assurance.

Example 21.13. Setting the WS-RM Message Delivery Assurance Policy

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:deliveryAssurance>
        <wsrm-mgr:AtLeastOnce />
    </wsrm-mgr:deliveryAssurance>
</wsrm-mgr:reliableMessaging>
</beans>

21.6. Configuring WS-RM Persistence

Overview

The Apache CXF WS-RM features already described in this chapter provide reliability for cases such as network failures. WS-RM persistence provides reliability across other types of failure such as an RM source or an RM destination crash.

WS-RM persistence involves storing the state of the various RM endpoints in persistent storage. This enables the endpoints to continue sending and receiving messages when they are reincarnated.

Apache CXF enables WS-RM persistence in a configuration file. The default WS-RM persistence store is JDBC-based. For convenience, Apache CXF includes Derby for out-of-the-box deployment. In addition, the persistent store is also exposed using a Java API. To implement your own persistence mechanism, you can implement one using this API with your preferred DB.

Important

WS-RM persistence is supported for oneway calls only, and it is disabled by default.

How it works

Apache CXF WS-RM persistence works as follows:

  • At the RM source endpoint, an outgoing message is persisted before transmission. It is evicted from the persistent store after the acknowledgement is received.
  • After a recovery from crash, it recovers the persisted messages and retransmits until all the messages have been acknowledged. At that point, the RM sequence is closed.
  • At the RM destination endpoint, an incoming message is persisted, and upon a successful store, the acknowledgement is sent. When a message is successfully dispatched, it is evicted from the persistent store.
  • After a recovery from a crash, it recovers the persisted messages and dispatches them. It also brings the RM sequence to a state where new messages are accepted, acknowledged, and delivered.

Enabling WS-persistence

To enable WS-RM persistence, you must specify the object implementing the persistent store for WS-RM. You can develop your own or you can use the JDBC based store that comes with Apache CXF.

The configuration shown in Example 21.14, “Configuration for the Default WS-RM Persistence Store” enables the JDBC-based store that comes with Apache CXF.

Example 21.14. Configuration for the Default WS-RM Persistence Store

<bean id="RMTxStore" class="org.apache.cxf.ws.rm.persistence.jdbc.RMTxStore"/>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <property name="store" ref="RMTxStore"/>
</wsrm-mgr:rmManager>

Configuring WS-persistence

The JDBC-based store that comes with Apache CXF supports the properties shown in Table 21.4, “JDBC Store Properties”.

Table 21.4. JDBC Store Properties

Attribute NameTypeDefault Setting

driverClassName

String

org.apache.derby.jdbc.EmbeddedDriver

userName

String

null

passWord

String

null

url

String

jdbc:derby:rmdb;create=true

The configuration shown in Example 21.15, “Configuring the JDBC Store for WS-RM Persistence” enables the JDBC-based store that comes with Apache CXF, while setting the driverClassName and url to non-default values.

Example 21.15. Configuring the JDBC Store for WS-RM Persistence

<bean id="RMTxStore" class="org.apache.cxf.ws.rm.persistence.jdbc.RMTxStore">
    <property name="driverClassName" value="com.acme.jdbc.Driver"/>
    <property name="url" value="jdbc:acme:rmdb;create=true"/>
</bean>