Glynn, Eoghan wrote:
-----Original Message-----
From: Andrea Smyth [mailto:[EMAIL PROTECTED]
Sent: 15 January 2007 09:21
To: [email protected]
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