|
Page Edited :
CXF20DOC :
Developing Assertions
Developing Assertions has been edited by Andrea Smyth (Apr 13, 2007). Content:There are two steps involved in developing your domain specific assertions, these are:
Th steps are outlined in some more detail below: Implementing the Assertion InterfaceYou 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: PrimitiveAssertionThis 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 NestedPrimitiveAssertionThis 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. JaxbAssertionThis 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 InterfaceImplementing 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 InterceptorThis 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): <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. Implementing a Policy-Aware Conduit/DestinationInitialisationConduits/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 SendingGiven 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 InterfaceWith 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. 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); ... } } |
Unsubscribe or edit your notifications preferences
