WS-Policy - 6.3

Talend ESB Service Developer Guide

EnrichVersion
6.3
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Design and Development
Installation and Upgrade
EnrichPlatform
Talend ESB

Developing Assertions

There are two steps involved in developing your domain specific assertions, these are:

  1. Implementing the Assertion and AssertionBuilder interfaces, and registering the AssertionBuilder with the AssertionBuilderRegistry

  2. Providing runtime support for the Assertion, either in form of an interceptor or inside a conduit or a destination, and registering that support if necessary.

The steps are outlined in more detail below:

Implementing the Assertion Interface

You can chose to implement the Assertion interface from scratch, or decide to use one of the existing Assertion implementations in the cxf-api module, extending them as required:

PrimitiveAssertion

This class represents an assertion without any attributes or child elements (in particular without a nested Policy element). The AnonymousResponses or NonAnonymousResponses assertions in the addressing metadata namespace http://www.w3.org/2007/01/addressing/metadata are examples of this type of assertion. The implementation of the equal and normalize methods in the class are trivial, and there should be no need to extend this class.

NestedPrimitiveAssertion

This class represents an assertion without any attributes, but with one mandatory nested Policy child element. The Addressing assertions in the addressing metadata namespace is an example of this type of assertion. The implementation of the equal and normalize methods are generic, and there should be no need to extend this class.

JaxbAssertion

This class represents an assertion described by an xml schema type that has been mapped to a Java class. The RM assertion as well as the assertions used in the HTTP module are extensions of this class. Although the equal and normalize methods are not abstract, you probably want to overwrite these methods.

Implementing and Registering the AssertionBuilder Interface

Assertion Builder class for custom assertion should implement AssertionBuilder<T> interface. The interface type can be Element, XMLStreamReader or OMElement.

Interface contains two methods: build() and getKnownElements().

Implementation of build() method should construct Assertion from the incoming type. It can be PrimitiveAssertion (without attributes or child elements), NestedPrimitiveAssertion (without attributes but with nested policy element) and JaxbAssertion (assertion described by any XML schema).

getKnownElements() method must return QNames of assertion elements from which assertion can be built.

Implementing the build method of the AssertionBuilder interface is straightforward (in the case of JaxbAssertions you can extend the JaxbAssertionBuilder class, which provides an appropriate JAXB context and some other useful methods).

The implementation of buildCompatible may need some more consideration if your assertion represents an element with attributes and/or child elements.

Registration of your AssertionBuilder with the AssertionBuilderRegistry is easy enough: simply add a bean for your AssertionBuilder to the cxf-* file of your module, or to the application's custom cfg file.

Implementing a Policy-Aware Interceptor

This is the easiest way of providing runtime support for an Assertion. Steps 1. and 2. listed in Interaction with the Framework can usually be coded as follows:

package mycompany.com.interceptors;
import org.apache.cxf.ws.policy.AssertionInfoMap;

class MyPolicyAwareInterceptor {
   static final QName assertionType = new QName("http://mycompany.com}", 
      "MyType"});
   public void handleMessage(Message message) {

      // get AssertionInfoMap
      org.apache.cxf.ws.policy.AssertionInfoMap aim = 
         message.get(org.apache.cxf.ws.policy.AssertionInfoMap.class);
      Collection<AssertionInfo ais> = aim.get(assertionType );

      // extract Assertion information
      for (AssertionInfo ai : ais) {
         org.apache.neethi.Assertion a = ai.getAssertion();
         MyAssertionType ma = (MyAssertionType)a;
         // digest ....
      }

      // process message ...
      // express support

      for (AssertionInfo ai : ais) {
         ai.setAsserted(...);
      }          
   }
}

Sometimes, it may be more convenient to spead the above functionality accross several interceptors, possibly according to chain (in, in fault, out, outfault). In any case, you need to also provide a PolicyInterceptorProvider, and declare a corresponding bean. Either implement one from scratch or use the PolicyInterceptorProviderImpl in the api package and customise it as follows (assuming that one and the same interceptor is used for all paths). The main task of policy interceptor provider is to say which interceptors must be activated for specified policy assertion:

<bean name="MyPolicyAwareInterceptor" 
   class="mycompany.com.interceptors.MyPolicyAwareInterceptor"/>
<bean class="org.apache.cxf.ws.policy.PolicyInterceptorProviderImpl">
   <constructor-arg>
      <!-- the list of assertion types supported 
            by this PolicyInterceptorProvider -->
      <list>
         <bean class="javax.xml.namespace.QName">
            <constructor-arg value="http://mycompany.com}"/>
            <constructor-arg value="MyType"/>
         </bean>
      </list>
   </constructor-arg>
   <property name="inInterceptors">
      <list>
         <ref bean="MyPolicyAwareInterceptor"/>
      </list>
   </property>
   <property name="inFaultInterceptors">
      <list>
         <ref bean="MyPolicyAwareInterceptor"/>
      </list>
   </property>
   <property name="outInterceptors">
      <list>
         <ref bean="MyPolicyAwareInterceptor"/>
   </list>
   </property>
   <property name="outFaultInterceptors">
      <list>
         <ref bean="MyPolicyAwareInterceptor"/>
      </list>
   </property>
</bean>

All beans of type PolicyInterceptorProvider are automatically registered with the framework's PolicyInterceptorProviderRegistry.

It is also possible to implement policy interceptor provider programmatically from scratch. It's constructor gives assertions QNames as argument of super constructor and adds corresponded interceptors using getters:

public class MyInterceptorProvider extends AbstractPolicyInterceptorProvider {
    private static final long serialVersionUID = -5248428637449096540L;
    private static final MyInInterceptor IN_INTERCEPTOR = new MyInInterceptor();
    private static final MyOutInterceptor OUT_INTERCEPTOR = new MyOutInterceptor();
    private static final MyOutFaultInterceptor OUT_FAULT_INTERCEPTOR = new MyOutFaultInterceptor();
     
    private static final Collection<QName> ASSERTION_TYPES;
    static {
        ASSERTION_TYPES = new ArrayList<QName>();
        ASSERTION_TYPES.add(new QName("www.mycompany.org", "myassertion"));
    }
 
    public MyInterceptorProvider() {
        super(ASSERTION_TYPES);
        getInInterceptors().add(IN_INTERCEPTOR);       
        getOutInterceptors().add(OUT_INTERCEPTOR);       
        getOutFaultInterceptors().add(OUT_FAULT_INTERCEPTOR);       
    }
}

Since version 2.5.2, Assertion builder and policy interceptor provider can be registered using CXF bus extension mechanism: just create a file META-INF/cxf/bus-extensions.txt containing the following:

org.company.MyInterceptorProvider::true
org.company.MyAssertionBuilder::true

Boolean value at the end specifies lazy loading strategy.

CXF automatically recognizes the assertion builder and policy interceptor provider and store them into registries: AssertionBuilderRegistry and PolicyInterceptorProviderRegistry.

Since CXF 2.6.0 it is possible to register multiple interceptor providers for single assertion.

Implementing a Policy-Aware Conduit/Destination
Initialization

Conduits/Destinations have access to the EndpointInfo object in their their constructors. Assuming they also have access to the bus, they can at any time in their lifecycle obtain the effective policy for the endpoint as follows:

class MyPolicyAwareConduit {
   static final QName assertionType = new QName("http://mycompany.com}", 
      "MyType"});

   void init() {
      PolicyEngine engine = bus.getExtenation(PolicyEngine.class);
      if (null != engine && engine.isEnabled()) {
      EffectiveEndpointPolicy ep = engine.getEndpointPolicy(endpoint, 
         this);
      Collection<Assertion> as = ep.getChosenAlternative();
      for (Assertion a : as) {
         if (assertType.equals(a.getName()) {
            // do something with it ...
         }
      }
      ... 
   }
   ...
}

and similarly for a Destination.

Policy-Aware Message Sending

Given access to the Message object, a conduit can, in its send method, proceed the same way as an interceptor in handleMessage. It can defer the updating of the assertion status in the AssertionInfo objects until called upon by the PolicyVerificationOutInterceptor, i.e. implement the status update in the assertMessage method. If the status update takes place inside of the send method itself, assertMessage, at least for outbound messages, can be implemented as a no-op.

Implementing the Assertor Interface

With canAssert, the conduit/destination simply informs the framework if it understands a given type of assertions. In assertMessage on the other hand, the conduit/destination expresses support (or the lack thereof) for specific assertion instances. See Verification for a description of how this API is used by the verifying policy interceptors in the POST_STREAM or PRE_INVOKE phases. HTTPConduit is an exmaple of a policy aware Conduit. It supports assertions of type HTTPClientPolicy, which are represented in the runtime as JaxbAssertion<HTTPClientPolicy> objects. HTTPConduit also has a data member of type HTTPClientPolicy. It implements assertMessage as follows: for outbound messages, it asserts all JaxbAssertion<HTTPClientPolicy> that are compatible with this data member. For inboun d messages, all HTTPClientPolicy assertions are asserted regardless their attributes. The rationale for this is that the sematics of the HTTPClientPolicy assertion effectively does not mandate any specific action on the inbound message. Similary, on its inbound path, the HTTPDestination asserts all HTTPServerPolicy assertions that are equal to the HTTPServerPolicy assertion configured for the destination, and all assertions of that type on the outbound path.

class MyPolicyAwareConduit implements Assertor {
   static final QName MYTYPE = new QName("http://mycompany.com}", 
      "MyType"});

   public boolean canAssert(QName name) {
      return MTYPE.equals(name);
   }

   public void assertMessage(Mesage message) {
      AssertionInfoMap = message.get(AssertioninfoMap.class);
      ...
   }
}

How It Works

Retrieval of Policies

Policies are associated with policy subjects. In the web services context, there are four different subjects:

  • Service

  • Endpoint

  • Operation

  • Message

Using WSDL 1.1, the policy-subject association usually takes the form of xml element attachment : A wsp:Policy element (the wsp prefix denotes the http://www.w3.org/2006/07/ws-policy namespace) is attached to a WSDL element such as wsdl:port. Alternatively, a wsp:PolicyReference elements is attached to a wsdl element. In that case, the actual wsp:Policy element can reside outside of the wsdl. Note that subjects do not correspond to wsdl elements directly. Rather, they map to a set of wsdl elements (see below). For example wsdl:port, wsdl:portType and wsdl:binding elements together describe the endpoint as a subject.

Another form of associating policies with policy subjects is external attachment : wsp:PolicyAttachment elements, which can reside in arbitrary locations, explicitly specify the subject(s) they apply to in their AppliesTo child element.

In CXF, elements attached to a wsdl element are available as extensors in the service model representation of that wsdl element. wsp:Policy or wsp:PolicyReference elements can be obtained as extensors of type UnknownExtensibilityElement in which the element name matches that of the wsp:Policy or wsp:PolicyReference element. Note that these attached elements are not parsed when the service model is built. With xml element attachment in WSDL 1.1, given a Message object, wsp:Policy elements attached to the endpoint or message subject can therefore be obtained by navigating the service model starting with the OperationInfo and/or EndpointInfo object stored in the message (or in the exchange).

The location of documents containing PolicyAttachment documents on the other hand needs to be made known to the framework. This can easily be achieved through configuration, see Specifying the Location of External Attachments .

PolicyAttachments are flexible w.r.t. the type of domain expressions. Domain expressions are used to identify entities such as endpoints, operations or messages with which a policy can be associated:

<wsp:PolicyAttachment>
   <wsp:AppliesTo> 
      <x:DomainExpression/> +
   </wsp:AppliesTo>
   (<wsp:Policy>...</wsp:Policy> |
       <wsp:PolicyReference>...</wsp:PolicyReference>)
</wsp:PolicyAttachment>

Currently, CXF supports only domain expressions of type wsa:EndpointReferenceType: They allow to associate the policies or policy references in an attachment with an endpoint (by means of matching the endpoint's address with that in the EndpointReferenceType element). It is not possible however to associate a Policy with an operation or a message this way. Support for other types of domain expressions can be plugged in by implementing the DomainExpressionBuilder interface and adding a corresponding bean to your configuration file (all DomainExpressionBuilder instances loaded that way will automatically register with the DomainExpressionBuilder and thus be considered in the process of parsing PolicyAttachment elements).

Once that the framework knows where to look for wsp:Policy elements, it can parses these elements and creates runtime presentations for them. This is where AssertionBuilders come into play: All child elements of a wsp:Policy element that are not in the wsp namespace are considered to be assertions. The framework will use its AssertionBuilderRegistry to find an AssertionBuilder registered for the element type in question and, if it finds one, proceed to build an Assertion object from that element (or else throw a PolicyException).

Computation of Effective Policies

As mentioned above, policies are associated with policy subjects. With WSDL 1.1, the effective policy for a subject is the aggregation, or the merge , of the policies attached to the wsdl elments representing that subject: The effective policy for a service subject is the merge of all policies applying to the wsdl:service element. The effective policy for an endpoint subject is the merge of all policies applying to the wsdl:port, wsdl:portType and wsdl:binding elements. The effective policy for an operation subject is the merge of all policies applying to the wsdl:portType/wsdl:operation and wsdl:binding/wsdl:operation elements. The effective policy for a (input | output | fault) message subject is the merge of all policies applying to the wsdl:message, (wsdl:portType/wsdl:operation/wsdl:input | wsdl:portType/wsdl:operation/wsdl:output | wsdl:portType/wsdl:operation/wsdl:fault) and (wsdl:binding/wsdl:operation/wsdl:input | wsdl:binding/wsdl:operation/wsdl:output | wsdl:binding/wsdl:operation/wsdl:fault).

Additional aggregation takes place to determine the effective policy of an endpoint: The effective policy for a service is the effective policy for the service subject. The effective policy for an endpoint is the merge of the effective policies for the service subject and the endpoint subject. The effective policy for an operation is the merge of the effective policies for the service subject, the endpoint subject and the operation subject. The effective policy for a (input | output | fault) message is the merge of the effective policies for the service subject, the endpoint subject, the operation subject and the message subject.

Multiple sources can be used to apply policies to the same subject. In the case of an endpoint subject for example, its associated wsdl:port element can have multiple wsp:Policy child elements. Also, a separate document can contain wsp:PolicyAttachment elements in which the AppliesTo children identify the endpoint in question as the target subject. Both the Policies attached to the port element as well as those in the matching PolicyAttachment elements will then contribute to the effective policy of the endpoint subject.

It is also important to keep in mind that the aggregation process described above makes it possible for an effective policy to have multiple assertion elements of the same type in one alternative (although this would not be considered the normal case). Different assertions of the same type within the same alternative do not overwrite each other. In fact, if used inappropriately, they may contradict each other. But it is also possible that they complement each other. Either way, the framework does not remove such duplicates and instead leaves it to the interceptors (or other Assertors) involved in the assertion process to decide if they can meaningfully deal with multiple assertions of the same type.

It is obvious that the above aggregation process can be quite resource intense. Effective policies for messages and endpoints are therefore cached by the framework for future reference. The entity that manages the cache of effective policies is the PolicyEngine.

When computing the effective policy for an endpoint or a message, the framework also chooses one of the effective policy's alternatives. Currently, it choses the first alternative in which all assertions may be supported, either by interceptors (i.e. there is a PolicyInterceptorProvider for the assertion type) or by the conduit/destination (if this implements the Assertor interface and through its canAssert method confirms that it can support the assertion type). However, even if such an alternative can be found, the chosen alternative is not necessarily supported: An interceptor may in principle be able to support a specific type of assertions, but it may not actually be able to support an individual instance of that assertion type.

The choice of alternative, along with the set of interceptors (obtained from the PolicyInterceptorProviders in the PolicyInterceptorProviderRegistry), is cached along with the actual effective message or endpoint policy in the form of an EffectivePolicy or EffectiveEndpointPolicy object. In the case of an effective endpoint policy, interceptors are chosen in such a way that the assertions in the chosen alternative of the effective endpoint policy can be supported, but also any assertion in any alternative of any of the operation and message specific policies. This is necessary in situations where the underlying message is not known, for example on the server inbound path: Once an alternative has been chosen for the effective policy of the server's endpoint we know which assertions must definitely be supported, regardless the underlying message/operation. Additional interceptors that are necessary to support the assertions that only appear in specific operation or input message policies are added pre-emptively. Note that this generally requires interceptors to be coded defensively - good practice anyway but especially so for interceptors returned by PolicyInterceptorProviders!

On-the-fly Provision of Interceptors

The policy framework, when activated (by loading the PolicyEngine and setting its "enabled" attribute to true), installs a couple of interceptors at bus level which execute early on in their respective interceptor chains:

Role

Chain

Phase

Interceptor

Effective Subject Policies Known

Client

Out

SETUP

ClientPolicy-OutInterceptor

Service, Endpoint, Operation, (Input) Message

Client

In

RECEIVE

ClientPolicy-InInterceptor

Service, Endpoint

Client

InFault

RECEIVE

ClientPolicy-InFault-Interceptor

Service, Endpoint

Server

In

RECEIVE

ServerPolicy-InInterceptor

Service, Endpoint

Server

OutFault

SETUP

ServerPolicy-OutFault-Interceptor

Service, Endpoint, Operation, (Fault) Message

Server

Out

SETUP

ServerPolicy-OutInterceptor

Service, Endpoint, Operation, (Out) Message

The main purpose of these policy interceptors is to add further interceptors that are required to support the effective policy of the underlying message - even if that policy is not yet known at the time the policy interceptor executes (because the operation is not yet known at that time). If the effective message policy is known, the assertions of its selected alternative are inserted into the message in the form of an AssertionInfoMap. This is a map, keyed by assertion type name, of collections of AssertionInfo objects, the latter being stateful (asserted/not asserted) representations of Assertion objects. When the effective message policy is not known, not only the assertions for the selected alternative in the effective endpoint policy are included in the AssertionInfoMap, but also all assertions in all alternatives of all of the operation and message specific policies. Not all of these will be asserted at the end of the chain, but that is fine if it turns out the unasserted assertions apply to operation sayHi when in fact the chain has been processing the message for a greetMe request!

Policy Aware Interceptors

Policy-aware interceptors extract the collection of AssertionInfo objects for the assertion types they understand from the AssertionInfoMap in the message. They can then use the wrapped Assertion objects to fine tune their behaviour, possibly exhibiting message specific behaviour. They can also express whether or not they could support these assertions. Given an assertion type that has attributes, and assuming there are two instances of assertions of this type, it is possible that the interceptor can assert one, but not the other. In any case, inability to support all assertions understood by the interceptor does not necessarily indicate a failure. As mentioned above in relation to pre-emptive interceptor installation, it is possible that the ones that cannot be supported do not in fact apply to the underlying message at all. Typically the interceptor would strive at supporting as many of these assertions as possible however, and to do so it may avail of the AssertionBuilder's capability to compute a compatible assertion. For example, by scheduling an acknowledgement to be sent in 3 seconds, an RM interceptor would support both of the following RMAssertions:

<wsrmp:RMAssertion 
   xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
   <wsrmp:AcknowledgementInterval Milliseconds="30000"/>
</wsrmp:RMAssertion>
<wsrmp:RMAssertion 
   xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
   <wsrmp:AcknowledgementInterval Milliseconds="50000"/>
</wsrmp:RMAssertion>
Verification

Another set of interceptors installed by the policy framework is responsible for verifying that one of the alternatives in the effective policy of the underlying message is indeed supported. These interceptors are:

Chain

Phase

Interceptor

Out, OutFault

POST_STREAM

PolicyVerificationOutInterceptor

In

PRE_INVOKE

PolicyVerificationInInterceptor

InFault

PRE_INVOKE

PolicyVerificationInFaultInterceptor

Their behaviour is symmetric on client and server side. On the outbound chain the effective message policy was known by the time the policy interceptor executing in the SETUP phase had inserted the AssertionInfoMap into the message. As the map was built exclusively from the Assertion objects that are part of the chosen alternative of the effective message policy, all of them must be supported. In other words, all of the AssertionInfo objects need to be in the asserted state. If one of them is not, the interceptor throws a Fault (wrapping a PolicyException).

On the inbound paths a little bit more work is necessary: If the message is a fault, we know by now what type of fault it is and what operation it applies to. If the message is not a fault message, knowing the underlying operation we can, from the location of the interceptor (client or server side), infer the message subject (input or output message). Either way, all information is now available to obtain the effective message policy. To check if any of is alternatives is supported, the policy verification interceptors then simply check if for each of its assertions the associated AssertionInfo object in the map is in the asserted state. If no alternative is supported, the interceptor throws a Fault (wrapping a PolicyException).

One thing worth noting is that - both on outbound and inbound chains - there may be assertions that only the conduit or destination can support. Although conduit or destination could access Assertion objects and tailor their behaviour when sending or receiving the current message, it is not knoan at this point whether this "tailoring" actually succeeded for the underlying message, i.e. whether the assertions in questions could actually be supported. For this reason, the policy verification interceptors check if the conduit or destination implements the Assertor interface. It it does, they pass it the Message object so they confirn their support (or the lack thereof) for these assertions. The above described traveral of the AssertionInfo map only takes place after the conduit or destination had a chance to m ake their contribution.

WS-Policy Framework Overview

The WS-Policy framework provides infrastructure and APIs that allow CXF users and developers 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.

The framework consists of a core runtime and APIs that allow developers to plug in support for their own domain assertions:

Core

The core is responsible for:

  • retrieval of policies from different sources (wsdl documents, external documents)

  • computation of effective policies for service, endpoint, operation and message objects

  • on-the-fly provision of interceptors based on the effective policies for a particular message

  • verification that one of the effective policy's alternatives is indeed supported.

Policy operations such as merge and normalization (but not intersection) are based on Apache Neethi .

APIs
AssertionBuilder

The AssertionBuilder API is a concept from Neethi, slightly modified to avoid the dependency on the Axis object model, and extended to include support for domain specific behaviour of intersection and comparison.

public interface AssertionBuilder {
   // build an Assertion object from a given DOM element
   Assertion build(Element element);
   // return the schema type names of assertions understood by this builder
   Collection<QName> getSupportedTypes();
   // return an Assertion object that is 
   // compatible with the specified assertions
   Assertion buildCompatible(Assertion a, Assertion b);
}

AssertionBuilder implementations are loaded dynamically and are automatically registered with the AssertionBuilderRegistry, which is available as a Bus extension. Currently, CXF supports AssertionBuilder and Assertion implementations for the following assertion types:

{http://schemas.xmlsoap.org/ws/2005/02/rm/policy}RMAssertion
{http://www.w3.org/2007/01/addressing/metadata}Addressing
{http://www.w3.org/2007/01/addressing/metadata}AnonymousResponses
{http://www.w3.org/2007/01/addressing/metadata}NonAnonymousResponses
{http://cxf.apache.org/transports/http/configuration}client
{http://cxf.apache.org/transports/http/configuration}server

along with the WS-SecurityPolicy defined assertions.

They are all based on generic Assertion implementations (PrimitiveAssertion, NestedPrimitiveAssertion, JaxbAssertion) that developers can parameterize or extend when developing their own assertions, see Developing Assertions .

PolicyInterceptorProvider

This API is used to automatically engage interceptors required to support domain specific assertions at runtime, thus simplifying interceptor configuration a lot.

public interface PolicyInterceptorProvider extends InterceptorProvider {
   // return the schema types of the asssertions that can be supported
   Collection<QName> getAssertionTypes()
}

Currently, CXF supports PolicyInterceptorProvider implementations for the following assertion types:

{http://schemas.xmlsoap.org/ws/2005/02/rm/policy}RMAssertion
{http://www.w3.org/2007/01/addressing/metadata}Addressing
{http://www.w3.org/2007/01/addressing/metadata}AnonymousResponses
{http://www.w3.org/2007/01/addressing/metadata}NonAnonymousResponses

along with the WS-SecurityPolicy defined assertions.

In addition, the framework offers an API to refine domain expression(s) (xml elements describing policy subjects within a policy scope) in policy attachments. There is currently only one implementation for EndpointReferenceType domain expressions (matching over the address). Another implementation, using XPath expressions, is in work.

Interaction with the Framework

Components interact with the policy framework mainly in order to:

  1. retrieve the assertions pertaining to the underlying message (at least the ones known to the component) so the component can operate on the message accordingly

  2. confirm that the assertions pertaining to the underlying message are indeed supported.

Like most other CXF features, the policy framework is itself largely interceptor based. Thus, most interaction with the framework is indirect through the Message object: Policy interceptors make AssertionInfo objects (stateful representations of assertions) available to subsequently executing, policy-aware interceptors by inserting them into the Message object. Extracting the AssertionInfo objects from the Message allows interceptors to perform steps 1. and 2. above:

import org.apache.neethi.Assertion;

public class AssertionInfo {
   ...
   public boolean isAsserted() {...}
   public void setAsserted(boolean asserted) {...}
   public Assertion getAssertion() {...}
}

The WS-Addressing and WS-RM interceptors are examples for this style of intercation.

Somtimes, Conduits and destinations also want to assert their capabilities. But they cannot normally wait for Assertion information being made available to them via the Message object: Conduits may exhibit message specific behaviour (for example, apply message specific receive timeouts), but decisions made during the initialization phase may limit their capability to do so. And Destinations cannot normally exhibit message or operation specific behaviour at all. But both may still be able to support assertions in the effective endpoint's policy.

Their interaction with the policy framework therefore typically involves the PolicyEngine through which they obtain the effective policy for the underlying endpoint (for step 1.):

public interface PolicyEngine {
   ...
   EndpointPolicy getClientEndpointPolicy(EndpointInfo ei, 
      Conduit conduit);    
   EndpointPolicy getServerEndpointPolicy(EndpointInfo ei, 
      Destination destination); 
}

public interface EndpointPolicy {
   ...
   Policy getPolicy(); 
   Collection<Assertion> getChosenAlternative();
}

To perform step 2. they implement the Assertor interface (namely its assertMessage method):

public class Assertor {
   ...
   public boolean canAssert(QName name);
   public void assertMessage(Message message);
}

An example for policy aware conduits and destinations in CXF are the HTTP conduit and destination. They do support assertions of element type HTTPClientPolicy and HTTPServerPolicy respectively.