Gang Yang wrote:
----- Original Message ----- From: "Simon Nash" <[email protected]>
To: <[email protected]>
Sent: Sunday, February 20, 2011 4:06 PM
Subject: Re: PolicyHandler exception handling issue -
PolicyHandler.afterInvoke() is not called when SOAPFault is generated
(UNCLASSIFIED)
Simon Nash wrote:
Gang Yang wrote:
--- Cut ---
4. PolicyHandler.afterInvoke is not called when Fault is generated.
So far, I have no workaround on this and would like a fix. If I
remember the code correctly, a quick fix is possible if
Axis2ServiceInOutSyncMessageReceiver.invokeBusinessLogic() can catch
the exception, create the Fault body and call
PolicyHandler.afterInvoke() on the service side. I'm not sure how
the client (requester) side works, but the
PolicyHandler.afterInvoke() is also skipped on the return with the
Fault.
I'll take a look at this code and post some comments on how I think the
problem could be addressed.
Hi Gang,
I've looked at this code and it doesn't seem like a simple fix.
1. On the service side, any business exceptions from the implementation
cause afterInvoke() to be skipped. Tuscany creates an AxisFault
wrapping the business exception, and throws this back to Axis2
for it to generate the on-the-wire fault.
2. On the service side, any system exceptions from the implementation
(e.g., ServiceRuntimeException) or from beforeInvoke() cause
afterInvoke() to be skipped. Tuscany creates an AxisFault by calling
AxisFault.makeFault() and throws this back to Axis2 for it to
generate the on-the-wire fault.
3. On the reference side, any AxisFault (either created by Axis2 or
created by Tuscany on the service side because of cases 1 or 2)
causes afterInvoke() to be skipped.
I'm assuming that both cases 1 and 2 are a problem for what you need
to do. Your suggestion of moving responsibility for creating the
fault body from Axis2 to Tuscany seems like a big change with plenty
of opportunity for things to go wrong because Axis2 would then take
different code paths when Tuscany returns back to it. I don't know
Axis2 well enough to know whether it is considered correct for the
business method to create a fault body as the operation response and
return normally instead of throwing an AxisFault. This change could
affect other scenarios such as handling business exceptions, so
it would need very careful thought and thorough testing.
Is there agreement that all the situations described by cases 1 and 2 need
the same handling? The original comment about this only mentioned case 2
in the specific situation where the exception is thrown by beforeInvoke().
Returning a SOAPFault as normal response if fine. However, I can't
effective do so because of code structure. The PolicyHandler API
provides two separate methods, beforeInvoke and afterInvoke, for inbound
and outbound. When we detect the security problem and want to stop the
request from reaching the endpoint in beforeInvoke, we throw
runtimeException. But it's this very RuntimeException that prevents
afterInvoke on the outbound to be called. So I don't have a chance to
create a SOAPFault as a normal response.
Thanks for the clarification. I had thought that Tuscany would need to
create the SOAPFault in all cases. If Tuscany doesn't need to create
the SOAPFault, but just needs to call afterInvoke() so that afterInvoke()
can create the SOAPFault, then I'm less concerned about making this change.
I think there's still one issue, which is how Tuscany would know whether
afterInvoke() has created a SOAPFault as a normal response. If
afterInvoke() hasn't done this, then Tuscany needs to throw AxisFault
when afterInvoke() returns. If afterInvoke() has done this, then
Tuscany needs to return normally to Axis2. Would it be correct for
Tuscany to look in outMC to see whether afterInvoke() has put a SOAPFault
in there as a normal response?
Simon
For case 3, Tuscany could catch the AxisFault, call afterInvoke()
and then rethrow the AxisFault. I wouldn't be concerned about making
this change because it only affects a small amount of Tuscany code
and doesn't have any side effects on Axis2.
I think this would help for auditing system and for the case where the
remote service side is a non-Tuscany framework. If the remote service
side is also a Tuscany framework, then security processing will fail
because the service side could not invoke afterInvoke() and therefore
did not process security headers.
Simon