Classification: UNCLASSIFIED Caveats: NONE
--- Cut --- > >> 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(). Yes, both case 1 and 2 needs to pass through afterInvoke() for security processing. > > > 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? You just brought up a good question that makes me think twice before taking the Fault creation business into my only hands. The right thing to do as a handler is to plug into the framework and use the underlying framework's fault handling mechanism instead of managing the fault myself incurring unnecessary and duplicated work and creating risk of not conforming to either standards or underlying framework. The issues here are several. First, if I'm to create the Fault body myself, I would have to determine what SOAP version to use, SOAP 1.1 or 1.2. Then, Tuscany runtime needs a way to know if the handler actually created a Fault. Peek into the outMC is possible, but not a desired way in my opinion. Also as you mentioned that this will make the execution to take a different path, so I may have to understand more about Axis2 internals to make sure the context/content is set correctly for downstream processing, such as on the client side, etc. Architecturally, this is not a good solution. I'll keep thinking and playing with it to see if anything else is possible. > > 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 > >> > > > > > > Classification: UNCLASSIFIED Caveats: NONE