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 > How It Works
Date Wed, 07 Mar 2012 16:23: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/How+It+Works">How
It Works</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" >| Server| Out | SETUP| ServerPolicyOutInterceptor
| Service, Endpoint, Operation, (Out) Message | <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">You
can see how it designed on the following figure: <br>!WS-policies.jpg! <br> <br></td></tr>
            <tr><td class="diff-unchanged" >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). <br></td></tr>
            <tr><td class="diff-unchanged" >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.
 <br>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! <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Briefly,
policy interceptors make following steps: <br># Check message property _PolicyConstants.POLICY_OVERRIDE_.
<br># If _PolicyConstants.POLICY_OVERRIDE_ contains policy, it will be taken for further
processing. <br># If property is empty, policy will be asked from ServiceModel. Here
CXF loads policies attached to WSDL or provided via Spring configuration.  <br># If
any policy on step 2 or step 3 is found, _EffectivePolicy_ will be created. Appropriate WS-policies
will be merged for the current message and built into Neethi _Policy_ object. <br>#
All interceptors registered for result policy assertions will be added to message interceptor
chain. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. Policy Aware Interceptors
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="HowItWorks-RetrievalofPolicies"></a>Retrieval of Policies</h2>

<p>Policies are associated with policy subjects. In the web services context, there
are four different subjects:</p>
<ul>
	<li>Service</li>
	<li>Endpoint</li>
	<li>Operation</li>
	<li>Message</li>
</ul>


<p>Using WSDL 1.1, the policy-subject association usually takes the form of <b>xml
element attachment</b>: A wsp:Policy element (the wsp prefix denotes the <a href="http://www.w3.org/2006/07/ws-policy"
class="external-link" rel="nofollow">http://www.w3.org/2006/07/ws-policy</a> 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. <br/>
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.</p>

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

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

<p>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 <a href="/confluence/display/CXF20DOC/WSPConfiguration#WSPConfiguration-SpecifyingtheLocationofExternalAttachments">Specifying
the Location of External Attachments</a>.</p>

<p>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:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;wsp:PolicyAttachment&gt;
    &lt;wsp:AppliesTo&gt; 
        &lt;x:DomainExpression/&gt; +
    &lt;/wsp:AppliesTo&gt;
    (&lt;wsp:Policy&gt;...&lt;/wsp:Policy&gt; | 
          &lt;wsp:PolicyReference&gt;...&lt;/wsp:PolicyReference&gt;)
&lt;/wsp:PolicyAttachment&gt;
</pre>
</div></div>
<p>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.<br/>
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).</p>

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

<h2><a name="HowItWorks-ComputationofEffectivePolicies"></a>Computation
of Effective Policies</h2>

<p>As mentioned above, policies are associated with policy subjects. With WSDL 1.1,
the effective policy for a subject is the aggregation, or the <b>merge</b>, of
the policies attached to the wsdl elments representing that subject: <br/>
The effective policy for a service subject is the merge of all policies applying to the wsdl:service
element.<br/>
The effective policy for an endpoint subject is the merge of all policies applying to the
wsdl:port, wsdl:portType and wsdl:binding elements.<br/>
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.<br/>
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).</p>

<p>Additional aggregation takes place to determine the effective policy of an endpoint:
<br/>
The effective policy for a service is the effective policy for the service subject.<br/>
The effective policy for an endpoint is the merge of the effective policies for the service
subject and the endpoint subject.<br/>
The effective policy for an operation is the merge of the effective policies for the service
subject, the endpoint subject and the operation subject.<br/>
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.</p>

<p><img class="emoticon" src="/confluence/images/icons/emoticons/information.gif"
height="16" width="16" align="absmiddle" alt="" border="0"/> <b>Multiple sources</b>
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.</p>

<p><img class="emoticon" src="/confluence/images/icons/emoticons/information.gif"
height="16" width="16" align="absmiddle" alt="" border="0"/> It is also important to keep
in mind that the aggregation process described above makes it possible for an effective policy
to have <b>multiple assertion elements of the same type in one alternative</b>
(although this would not be considered the normal case). Different assertions of the same
type within the same alternative do <b><em>not</em></b> 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 framewwork 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.</p>

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

<p>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 <b><em>may</em></b> 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.</p>

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

<h2><a name="HowItWorks-OntheflyProvisionofInterceptors"></a>On-the-fly
Provision of Interceptors</h2>

<p>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:</p>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Role </th>
<th class='confluenceTh'> Chain</th>
<th class='confluenceTh'> Phase </th>
<th class='confluenceTh'> Interceptor </th>
<th class='confluenceTh'> Effective Subject Policies Known </th>
</tr>
<tr>
<td class='confluenceTd'> Client </td>
<td class='confluenceTd'> Out </td>
<td class='confluenceTd'> SETUP </td>
<td class='confluenceTd'> ClientPolicyOutInterceptor </td>
<td class='confluenceTd'> Service, Endpoint, Operation, (Input) Message </td>
</tr>
<tr>
<td class='confluenceTd'> Client </td>
<td class='confluenceTd'> In </td>
<td class='confluenceTd'> RECEIVE </td>
<td class='confluenceTd'> ClientPolicyInInterceptor </td>
<td class='confluenceTd'> Service, Endpoint </td>
</tr>
<tr>
<td class='confluenceTd'> Client </td>
<td class='confluenceTd'> InFault </td>
<td class='confluenceTd'> RECEIVE </td>
<td class='confluenceTd'> ClientPolicyInFaultInterceptor </td>
<td class='confluenceTd'> Service, Endpoint </td>
</tr>
<tr>
<td class='confluenceTd'> Server</td>
<td class='confluenceTd'> In </td>
<td class='confluenceTd'> RECEIVE </td>
<td class='confluenceTd'> ServerPolicyInInterceptor </td>
<td class='confluenceTd'> Service, Endpoint </td>
</tr>
<tr>
<td class='confluenceTd'> Server</td>
<td class='confluenceTd'> OutFault </td>
<td class='confluenceTd'> SETUP</td>
<td class='confluenceTd'> ServerPolicyOutFaultInterceptor </td>
<td class='confluenceTd'> Service, Endpoint, Operation, (Fault) Message </td>
</tr>
<tr>
<td class='confluenceTd'> Server</td>
<td class='confluenceTd'> Out </td>
<td class='confluenceTd'> SETUP</td>
<td class='confluenceTd'> ServerPolicyOutInterceptor </td>
<td class='confluenceTd'> Service, Endpoint, Operation, (Out) Message </td>
</tr>
</tbody></table>
</div>


<p>You can see how it designed on the following figure:<br/>
<span class="error">Unable to render embedded object: File (WS-policies.jpg) not found.</span></p>

<p>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).<br/>
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. <br/>
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!<br/>
Briefly, policy interceptors make following steps:</p>
<ol>
	<li>Check message property <em>PolicyConstants.POLICY_OVERRIDE</em>.</li>
	<li>If <em>PolicyConstants.POLICY_OVERRIDE</em> contains policy, it will
be taken for further processing.</li>
	<li>If property is empty, policy will be asked from ServiceModel. Here CXF loads policies
attached to WSDL or provided via Spring configuration.</li>
	<li>If any policy on step 2 or step 3 is found, <em>EffectivePolicy</em>
will be created. Appropriate WS-policies will be merged for the current message and built
into Neethi <em>Policy</em> object.</li>
	<li>All interceptors registered for result policy assertions will be added to message
interceptor chain.</li>
</ol>


<h2><a name="HowItWorks-PolicyAwareInterceptors"></a>Policy Aware Interceptors</h2>

<p>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. <br/>
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. <br/>
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:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;wsrmp:RMAssertion <span class="code-keyword">xmlns:wsrmp</span>=<span
class="code-quote">"http://schemas.xmlsoap.org/ws/2005/02/rm/policy"</span>&gt;</span>
    <span class="code-tag">&lt;wsrmp:AcknowledgementInterval Milliseconds=<span
class="code-quote">"30000"</span>/&gt;</span>
<span class="code-tag">&lt;/wsrmp:RMAssertion&gt;</span>
<span class="code-tag">&lt;wsrmp:RMAssertion <span class="code-keyword">xmlns:wsrmp</span>=<span
class="code-quote">"http://schemas.xmlsoap.org/ws/2005/02/rm/policy"</span>&gt;</span>
    <span class="code-tag">&lt;wsrmp:AcknowledgementInterval Milliseconds=<span
class="code-quote">"50000"</span>/&gt;</span>
<span class="code-tag">&lt;/wsrmp:RMAssertion&gt;</span>
</pre>
</div></div>

<h2><a name="HowItWorks-Verification"></a>Verification</h2>

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

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Chain</th>
<th class='confluenceTh'> Phase </th>
<th class='confluenceTh'> Interceptor </th>
</tr>
<tr>
<td class='confluenceTd'> Out, OutFault </td>
<td class='confluenceTd'> POST_STREAM </td>
<td class='confluenceTd'> PolicyVerificationOutInterceptor </td>
</tr>
<tr>
<td class='confluenceTd'> In </td>
<td class='confluenceTd'> PRE_INVOKE </td>
<td class='confluenceTd'> PolicyVerificationInInterceptor </td>
</tr>
<tr>
<td class='confluenceTd'> InFault </td>
<td class='confluenceTd'> PRE_INVOKE </td>
<td class='confluenceTd'> PolicyVerificationInFaultInterceptor </td>
</tr>
</tbody></table>
</div>


<p>Their behaviour is symmetric on client and server side. <br/>
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). </p>

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

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





    </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/How+It+Works">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=51375&revisedVersion=14&originalVersion=13">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/How+It+Works?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message