cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF Documentation > Developing Assertions
Date Thu, 08 Mar 2012 10:05:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CXF20DOC&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Developing+Assertions">Developing
Assertions</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~ashakirin">Andrei
Shakirin</a>
    </h4>
        <br/>
                         <h4>Changes (2)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br>Boolean value at
the end specifies lazy loading strategy.  <br></td></tr>
            <tr><td class="diff-changed-lines" >CXF automatically recognizes the
assertion builder and policy interceptor provider and store them into registries: _AssertionBuilderRegistry_
and _PolicyInterceptorProviderRegistry_. <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">Since
CXF 2.6.0 it is possible to register multiple interceptor providers for single assertion.</span>
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Since
CXF 2.6.0 it is possible to register multiple interceptor providers for single assertion.
<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. Implementing a Policy-Aware
Conduit/Destination <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>There are two steps involved in developing your domain specific assertions,
these are:</p>
<ol>
	<li>Implementing the Assertion and AssertionBuilder interfaces, and registering the
AssertionBuilder with the AssertionBuilderRegistry</li>
	<li>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.</li>
</ol>


<p>Th steps are outlined in some more detail below:</p>

<h2><a name="DevelopingAssertions-ImplementingtheAssertionInterface"></a>Implementing
the Assertion Interface</h2>

<p>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:</p>

<h3><a name="DevelopingAssertions-PrimitiveAssertion"></a>PrimitiveAssertion</h3>

<p>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 <a href="http://www.w3.org/2007/01/addressing/metadata"
class="external-link" rel="nofollow">http://www.w3.org/2007/01/addressing/metadata</a>
are example of this type of assertions. The implementation of the equal and normalize methods
in the class are trivial, and there should be no need to extend this class.</p>

<h3><a name="DevelopingAssertions-NestedPrimitiveAssertion"></a>NestedPrimitiveAssertion</h3>

<p>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.</p>

<h3><a name="DevelopingAssertions-JaxbAssertion"></a>JaxbAssertion</h3>

<p>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.</p>

<h2><a name="DevelopingAssertions-ImplementingandRegisteringtheAssertionBuilderInterface"></a>Implementing
and Registering the AssertionBuilder Interface</h2>

<p>Assertion Builder class for custom assertion should implement <em>AssertionBuilder&lt;T&gt;</em>
interface. The interface type can be <em>Element</em>, <em>XMLStreamReader</em>
or <em>OMElement</em>. <br/>
Interface contains two methods: <em>build()</em> and <em>getKnownElements()</em>.
<br/>
Implementation of <em>build()</em> method should construct Assertion from the
incoming type. It can be <em>PrimitiveAssertion</em> (without attributes or child
elements), NestedPrimitiveAssertion  (without attributes but with nested policy element) and
<em>JaxbAssertion</em> (assertion described by any XML schema).<br/>
<em>getKnownElements()</em> method must return QNames of assertion elements from
which assertion can be built.</p>

<p>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). </p>

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

<p>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.</p>

<h2><a name="DevelopingAssertions-ImplementingaPolicyAwareInterceptor"></a>Implementing
a Policy-Aware Interceptor</h2>

<p>This is the easiest way of providing runtime support for an Assertion. Steps 1. and
2. listed in <a href="/confluence/display/CXF20DOC/WS-Policy+Framework+Overview#WS-PolicyFrameworkOverview-InteractionwiththeFramework">Interaction
with the Framework</a> can usually be coded as follows:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> mycompany.com.interceptors;
<span class="code-keyword">import</span> org.apache.cxf.ws.policy.AssertionInfoMap;

class MyPolicyAwareInterceptor {
   <span class="code-keyword">static</span> <span class="code-keyword">final</span>
QName assertionType = <span class="code-keyword">new</span> QName(<span class="code-quote">"http:<span
class="code-comment">//mycompany.com}"</span>, 
</span>       <span class="code-quote">"MyType"</span>});

   <span class="code-keyword">public</span> void handleMessage(Message message)
{

      <span class="code-comment">// get AssertionInfoMap
</span>       org.apache.cxf.ws.policy.AssertionInfoMap aim = 
           message.get(org.apache.cxf.ws.policy.AssertionInfoMap.class);
       Collection&lt;AssertionInfo ais&gt; = aim.get(assertionType );

       <span class="code-comment">// extract Assertion information
</span>       <span class="code-keyword">for</span> (AssertionInfo ai :
ais) {
           org.apache.neethi.Assertion a = ai.getAssertion();
           MyAssertionType ma = (MyAssertionType)a;
          <span class="code-comment">// digest ....
</span>       }

       <span class="code-comment">// process message ...
</span>            <span class="code-comment">// express support
</span>
       <span class="code-keyword">for</span> (AssertionInfo ai : ais) {
           ai.setAsserted(...);
       }          }
}
</pre>
</div></div>

<p>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:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">

&lt;bean name=<span class="code-quote">"MyPolicyAwareInterceptor"</span> 
      class=<span class="code-quote">"mycompany.com.interceptors.MyPolicyAwareInterceptor"</span>/&gt;

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

<p>All beans of type PolicyInterceptorProvider are automatically registered with the
framework's PolicyInterceptorProviderRegistry.</p>

<p>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:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class MyInterceptorProvider <span
class="code-keyword">extends</span> AbstractPolicyInterceptorProvider {
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> <span class="code-object">long</span>
serialVersionUID = -5248428637449096540L;
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> MyInInterceptor IN_INTERCEPTOR = <span
class="code-keyword">new</span> MyInInterceptor();
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> MyOutInterceptor OUT_INTERCEPTOR = <span
class="code-keyword">new</span> MyOutInterceptor();
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> MyOutFaultInterceptor OUT_FAULT_INTERCEPTOR
= <span class="code-keyword">new</span> MyOutFaultInterceptor();
    
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> Collection&lt;QName&gt; ASSERTION_TYPES;
    <span class="code-keyword">static</span> {
        ASSERTION_TYPES = <span class="code-keyword">new</span> ArrayList&lt;QName&gt;();
        ASSERTION_TYPES.add(<span class="code-keyword">new</span> QName(<span
class="code-quote">"www.mycompany.org"</span>, <span class="code-quote">"myassertion"</span>));
    }

    <span class="code-keyword">public</span> MyInterceptorProvider() {
        <span class="code-keyword">super</span>(ASSERTION_TYPES);
        getInInterceptors().add(IN_INTERCEPTOR);        
        getOutInterceptors().add(OUT_INTERCEPTOR);        
        getOutFaultInterceptors().add(OUT_FAULT_INTERCEPTOR);        
    }
}
</pre>
</div></div>

<p>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:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
org.company.MyInterceptorProvider::<span class="code-keyword">true</span>
org.company.MyAssertionBuilder::<span class="code-keyword">true</span>
</pre>
</div></div>
<p>Boolean value at the end specifies lazy loading strategy. <br/>
CXF automatically recognizes the assertion builder and policy interceptor provider and store
them into registries: <em>AssertionBuilderRegistry</em> and <em>PolicyInterceptorProviderRegistry</em>.
<br/>
Since CXF 2.6.0 it is possible to register multiple interceptor providers for single assertion.</p>

<h2><a name="DevelopingAssertions-ImplementingaPolicyAwareConduit%2FDestination"></a>Implementing
a Policy-Aware Conduit/Destination</h2>

<h3><a name="DevelopingAssertions-Initialisation"></a>Initialisation</h3>
<p>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:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
class MyPolicyAwareConduit {
    <span class="code-keyword">static</span> <span class="code-keyword">final</span>
QName assertionType = <span class="code-keyword">new</span> QName(<span class="code-quote">"http:<span
class="code-comment">//mycompany.com}"</span>, 
</span>        <span class="code-quote">"MyType"</span>});
    ...

    void init() {
        PolicyEngine engine = bus.getExtenation(PolicyEngine.class);
        <span class="code-keyword">if</span> (<span class="code-keyword">null</span>
!= engine &amp;&amp; engine.isEnabled()) {
        EffectiveEndpointPolicy ep = engine.getEndpointPolicy(endpoint, <span class="code-keyword">this</span>);
        Collection&lt;Assertion&gt; as = ep.getChosenAlternative();
        <span class="code-keyword">for</span> (Assertion a : as) {
            <span class="code-keyword">if</span> (assertType.equals(a.getName())
{
                <span class="code-comment">// <span class="code-keyword">do</span>
something with it ...
</span>            }
       }
       ... 
    }
}
</pre>
</div></div>
<p>and similarly for a Destination. </p>

<h3><a name="DevelopingAssertions-PolicyAwareMessageSending"></a>Policy-Aware
Message Sending</h3>

<p>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. </p>

<h3><a name="DevelopingAssertions-ImplementingtheAssertorInterface"></a>Implementing
the Assertor Interface</h3>

<p>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 <a href="/confluence/display/CXF20DOC/How+It+Works#HowItWorks-Verification">Verification</a>
for a description of how this API is used by the verifying policy interceptors in the POST_STREAM
or PRE_INVOKE phases.<br/>
HTTPConduit is an exmaple of a policy aware Conduit. It supports assertions of type HTTPClientPolicy,
which are represented in the runtime as JaxbAssertion&lt;HTTPClientPolicy&gt; objects.
HTTPConduit also has a data member of type HTTPClientPolicy. It implements assertMessage as
follows: for outbound messages, it asserts all JaxbAssertion&lt;HTTPClientPolicy&gt;
 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.<br/>
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.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
class MyPolicyAwareConduit <span class="code-keyword">implements</span> Assertor
{
    <span class="code-keyword">static</span> <span class="code-keyword">final</span>
QName MYTYPE = <span class="code-keyword">new</span> QName(<span class="code-quote">"http:<span
class="code-comment">//mycompany.com}"</span>, 
</span>        <span class="code-quote">"MyType"</span>});

    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
canAssert(QName name) {
        <span class="code-keyword">return</span> MTYPE.equals(name);
    }

    <span class="code-keyword">public</span> void assertMessage(Mesage message)
{
        AssertionInfoMap = message.get(AssertioninfoMap.class);
        ...
    }
}
</pre>
</div></div>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Developing+Assertions">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=51417&revisedVersion=16&originalVersion=15">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Developing+Assertions?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message