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 Wed, 07 Mar 2012 17:16: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 (3)</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" >h2. Implementing and Registering the
AssertionBuilder Interface <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Assertion
Builder class for custom assertion should implement _AssertionBuilder&lt;T&gt;_ interface.
The interface type can be _Element_, _XMLStreamReader_ or _OMElement_.  <br>Interface
contains two methods: _build()_ and _getKnownElements()_.  <br>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). <br>_getKnownElements()_
method must return QNames of assertion elements from which assertion can be built. <br>
<br></td></tr>
            <tr><td class="diff-unchanged" >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).  <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >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 <span class="diff-changed-words">paths)<span class="diff-added-chars"style="background-color:
#dfd;">. The main task of policy interceptor provider is to say which interceptors must
be activated for specified policy assertion</span>:</span> <br></td></tr>
            <tr><td class="diff-unchanged" >{code:xml} <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >All beans of type PolicyInterceptorProvider
are automatically registered with the framework&#39;s PolicyInterceptorProviderRegistry.
<br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">It
is also possible to implement policy interceptor provider programmatically. It&#39;s constructor
gives assertions QNames as argument of super constructor and adds corresponded interceptors
using getters: <br> <br>{code} <br>public class AuthorizationInterceptorProvider
extends AbstractPolicyInterceptorProvider { <br>    private static final long serialVersionUID
= -5248428637449096540L; <br>    private static final AuthorizationInInterceptor IN_AUTHZ_INTERCEPTOR
= new AuthorizationInInterceptor(); <br>    private static final AuthorizationInInterceptor
OUT_AUTHZ_INTERCEPTOR = new AuthorizationOutInterceptor(); <br> <br>    private
static final Collection&lt;QName&gt; ASSERTION_TYPES; <br>    static { <br>
       ASSERTION_TYPES = new ArrayList&lt;QName&gt;(); <br>        ASSERTION_TYPES.add(AuthorizationConstants.AUTHORIZATION_ASSERTION);
<br>    } <br> <br>    public AuthorizationInterceptorProvider() { <br>
       super(ASSERTION_TYPES); <br>        getInInterceptors().add(IN_AUTHZ_INTERCEPTOR);
        <br>        getOutInterceptors().add(OUT_AUTHZ_INTERCEPTOR);         <br>
   } <br>} <br>{code} <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. Implementing a Policy-Aware Conduit/Destination
<br> <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. 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 AuthorizationInterceptorProvider
<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> AuthorizationInInterceptor IN_AUTHZ_INTERCEPTOR
= <span class="code-keyword">new</span> AuthorizationInInterceptor();
    <span class="code-keyword">private</span> <span class="code-keyword">static</span>
<span class="code-keyword">final</span> AuthorizationInInterceptor OUT_AUTHZ_INTERCEPTOR
= <span class="code-keyword">new</span> AuthorizationOutInterceptor();
    
    <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(AuthorizationConstants.AUTHORIZATION_ASSERTION);
    }

    <span class="code-keyword">public</span> AuthorizationInterceptorProvider()
{
        <span class="code-keyword">super</span>(ASSERTION_TYPES);
        getInInterceptors().add(IN_AUTHZ_INTERCEPTOR);        
        getOutInterceptors().add(OUT_AUTHZ_INTERCEPTOR);        
    }
}
</pre>
</div></div>

<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=13&originalVersion=12">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