cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrea Smyth <andrea.sm...@iona.com>
Subject Re: Ideas for a WS-Policy Framework for CXF
Date Thu, 18 Jan 2007 13:18:44 GMT
Dan Diephouse wrote:

> What are you envisioning the AssertionBuilder API looking like?

The AssertionBuilder API is a concept from Neethi (slightly modified 
below as):

public interface AssertionBuilder {
    // build an Assertion object from a given xml element
    Assertion build(Element element);
   // return the schema type names of assertions understood by this builder
   Collection<QName> getSupportedTypes();
}
Concrete AssertionBuilder instances are loaded by the <Spring container> 
and register themselves with the AssertionBuilderRegistry, which is a 
Bus extension.

In addition to this, we need something like:

public interface Assertor {
   // return the subset of assertions that this assertor can assert
    List<Assertion> assert(List<Assertion> candidates);
}

this would be used in  the PolicyVerificationInterceptor to check which 
of the assertions have been asserted in order to decide if any of the 
policy alternatives of the effective policy is supported.
Interceptors like the RM interceptor would implement this, but also 
perhaps some transports.

And:

public interface AssertionInterceptorProvider extends InterceptorProvider {
}

As with AssertionBuilders, concrete AssertionInterceptorProviders are 
loaded by the <Spring container> and register themselves with the 
AssertionInterceptorProviderRegistry, is a Bus extension.
This API would be used by the PolicyEvaluationInterceptor to dynamically 
add interceptors according to the needs of the effective policy (client 
side) or according to the potential needs (server side - as I mentioned 
earlier we cannot determine the effective policy until after the 
operation has been determined).

All APIs must be made available in the api module.

Andrea.

>
> Regarding your suggestion of iterating back over interceptors, would that
> imply an API like so?
>
> Interceptor.setAssertions(Message, AssertionContext) ?
>
> Which would basically put whatever assertions are met into the
> AssertionContext - i.e. Addressing was used or MTOM was used.
>
> I could also envision an approach where we lookup the assertion mager and
> set which assertion is met. i.e.
>
> bus.get(AssertionContext.class).assert(usingAddressing);
>
> Not sure if thats at all what you had in mind though.
>
> - Dan
>
> On 1/15/07, Andrea Smyth <andrea.smyth@iona.com> wrote:
>
>>
>> Glynn, Eoghan wrote:
>>
>> >
>> >
>> >
>> >
>> >>-----Original Message-----
>> >>From: Andrea Smyth [mailto:andrea.smyth@iona.com]
>> >>Sent: 15 January 2007 09:21
>> >>To: cxf-dev@incubator.apache.org
>> >>Subject: Ideas for a WS-Policy Framework for CXF
>> >>
>> >>I have written up some ideas on a WS-Policy implementation
>> >>for CXF on the wiki:
>> >>http://cwiki.apache.org/confluence/display/CXF/WS-Policy+Framework
>> >>Any feedback appreciated.
>> >>
>> >>
>> >
>> >Hi Andrea,
>> >
>> >A couple of thoughts on this ...
>> >
>> >On the issue of the server-side assertion verification, can we
>> >distinguish two different classes of assertion:
>> >
>> >1. Assertions that are manifest from the gross incoming transport-level
>> >packets, without requiring any introspection of the actual message
>> >payload, and may even be enforceable prior to the payload being
>> >available to the receiver ... e.g. asserting that the socket-level 
>> comms
>> >are encrypted with a key strength of at least 128 bits, which could be
>> >enforced via a TLS handshake, in advance of any message data being 
>> sent.
>> >
>> >2. Assertions that are only manifest after introspection of the message
>> >payload ... e.g. asserting that addressing is used, in the sense that
>> >WS-A headers are present in the incoming message.
>> >
>> >Can we impose the restriction that ONLY assertions in class #2 may be
>> >set per-operation or per-message on the receiver-side?
>> >
>> >Whereas an assertion of class #1 would only be settable for the entire
>> >endpoint (as this is the level of granularity of the transport
>> >listener). In WSDL (1.1) terms, such a policy expression could be
>> >attached to a portType, but not an operation or message.
>> >
>> >So for example, a security policy that would require a specific type of
>> >listener to be launched would be limited to endpoint-level granularity
>> >... e.g. a HTTPS listener with enabled cipher suites satisfying at 
>> least
>> >128 bit encryption could NOT be required by a server-side per-operation
>> >or per-message policy assertion.
>> >
>> >
>> Hi Eoghan,
>>
>> This is an interesting question. I believe class #1 assertions would not
>> be considered well designed assertions in the context of WS-Policy as
>> they'd exhibit no visible behaviour (behaviour that manifests on the
>> wire), see Understanding Web Services Policy -  4. Advanced Concepts II:
>> Policy Assertion Design
>> <
>> http://msdn2.microsoft.com/en-us/library/ms996497.aspx#understwspol_topic4 
>>
>> >
>> Another problem is that transports are not interceptors (nor interceptor
>> providers), so we'd have to find a mechanism that allows transports to
>> assert parts of the endpoint vocabulary in the same way as interceptors
>> would do. Rather than having each interceptor (and the transport too)
>> record the fact that they can assert part of the endpoint's vocabulary
>> (this would result in a lot of repetitive code), we could instead, at
>> the end of the chain on the server side iterate, back over all
>> interceptors *and* the transport, and for each candidate that implements
>> the AssertionBuilder API, check if it could satisfy the assertions of
>> what now is known to be the effective message/operation policy.
>> To avoid the instanceOf AssertionBuilder check, transports and
>> interceptors can instead do this if they want to participate in the
>> assertion process:
>> List<AssertionBuilder> assertionBuilders =
>> Message.get(List<AssertionBuilder>);
>> if (null == assertionBuilders ) {
>>     message.put(List<AssertionBuilder>.class, new
>> ArrayList<AssertionBuilder>());
>> }
>> assertionBuilders.add(this);
>> Then at the end of the chain (in the PolicyVerificationInterceptor) we
>> only check back with those AssertionBuilders that have registered
>> themselves.
>>
>> But back to the distinction of class #1/class #2 assertions: I am not
>> sure this can be formalised as an assertion can basically be anything.
>> We could assume though that assertions are of class #2 by default unless
>> registered otherwise with some sort of registry, e.g. the types used in
>> JMS configuration could be registered as class #1 assertions.
>> We should also switch from
>> <service name="JMSSOAPServiceAddressing">
>>         <port binding="tns:HWJMSAddressingBinding"
>> name="HWJMSAddressingPort">
>>             <jms:address ....>
>>            </jms:address>
>>         </port>
>>     </service>
>>
>> to
>>
>> <service name="JMSSOAPServiceAddressing">
>>         <port binding="tns:HWJMSAddressingBinding"
>> name="HWJMSAddressingPort">
>>             <wsp:policy>
>>                 <jms:address ....>
>>                </jms:address>
>>          </wsp:policy>
>>         </port>
>>     </service>
>>
>> >
>> >--
>> >
>> >On the client-side, for performance reasons I think it would be good to
>> >avoid traversing the AssertionBuilders for every invocation. 
>> Instead, we
>> >could optimize the process to re-use the policy reconciliation done for
>> >previous invocations.
>> >
>> >
>> Yes, we should definitely do that - these are good ideas.
>>
>> Andrea.
>>
>> >Off the top of my head, something like the following could work:
>> >
>> >1. Maintain flyweighted policy sets, so that these may be compared
>> >efficiently for equality using the == operator (as opposed to doing a
>> >deep compare).
>> >
>> >2. Cache the interceptor chain resulting from the traversal of the
>> >AssertBuilders for a particular merged policy set.
>> >
>> >
>> >3. Maintain a second-level cache (only checked if the cache-lookup from
>> >step #2 yields nothing) of interceptor chains, which is keyed on
>> >isCompatible()-style logic as opposed to equality. Dumb example, but
>> >suppose we consider the RM BaseRetransmissionInterval to be a upper
>> >bound on the wait for an ACK, i.e. an instruction to resend the message
>> >if an ACK isn't received at *or before* the interval expiry ... with
>> >that loose interpretation, an asserted RM BaseRetransmissionInterval of
>> >500ms could be considered compatible with a previously asserted 
>> value of
>> >250ms for an earlier invocation.
>> >
>> >The idea would be to always efficiently determine if there's a
>> >previously computed interceptor chain available for re-use, rather than
>> >setting one up from scratch for each invocation.
>> >
>> >To allow for the fact that the interceptor chains can be modified
>> >in-flight (e.g. by removing interceptor(s) from the tail of the chain
>> >during a message dispatch), I guess we'd need to clone the cached chain
>> >for each new invocation.
>> >
>> >Apologies if I'm showing my ignorance of WS-Policy with any of the 
>> above
>> >suggestions ;)
>> >
>> >Cheers,
>> >Eoghan
>> >
>> >
>> >
>>
>>
>
>


Mime
View raw message