> -----Original Message-----
> From: Gary Gregory
> Sent: Sunday, December 27, 2009 16:16
> To: 'Daniel Kulp'; [email protected]
> Subject: RE: Inflexible fault interceptor chain?
>
> > -----Original Message-----
> > From: Daniel Kulp [mailto:[email protected]]
> > Sent: Tuesday, December 22, 2009 10:06
> > To: [email protected]
> > Cc: Gary Gregory
> > Subject: Re: Inflexible fault interceptor chain?
> >
> >
> > Can you create a small test case and attach to a jira?
>
> Here is the unit test:
>
> https://issues.apache.org/jira/browse/CXF-2594
> No SOAP fault XML elements when a Fault is thrown in the output chain
> after SAAJOutInterceptor.
Hi Dan and all,
Any news on looking at this unit tests? Can you see the failure and situation I
am talking about?
Thank you,
Gary
>
> Thank you,
> Gary
>
> >
> > This definitely sounds like bug of some sort. When I redid the
> > Provider
> > based services, I noticed that strange code in the StaxOutInterceptor
> > as well
> > and tried to remove it. However, that broke some of the JAX-WS tck
> > tests.
> > I don't remember the exact reason. I think it has something to do
> > with
> > faults thrown from the logical or soap handlers on the outgoing chain
> > needed
> > some strange and wacky processing. Don't really remember.
> >
> > If we can get your test case, we may be able to get it to work
> better.
> >
> > That said, you could probably write your own interceptor (you seem to
> > be good
> > at that :-) that would run on the fault chain prior to the SAAJOut
> and
> > have
> > it remove the SAAJ model from the message. You may need to trace
> > through a
> > couple other interceptors (like SoapOutInterceptor) to see if other
> > properties
> > need to be removed/reset.
> >
> > Dan
> >
> >
> > On Mon December 21 2009 8:12:50 pm Gary Gregory wrote:
> > > Hello Dan and all,
> > >
> > > Ok, the SAAJOutInterceptor solution almost worked. The behavior I
> > describe
> > > below is the same in CXF 2.2.4 and 2.2.6-SNAPSHOT (as of
> Saturday's
> > > build). I am not on 2.2.5 due to some bugs that are fixed in
> 2.2.6.
> > The
> > > debugging information I gathered for this message is with 2.2.4.
> > >
> > > I have two scenarios, one works and one does not with the
> > > SAAJOutInterceptor solution.
> > >
> > > If a Fault is thrown by a custom interceptor at a certain point in
> > the
> > > output chain, the wrong SOAP XML is generated, specifically no
> SOAP
> > fault
> > > XML elements are generated. Let me start by showing what works and
> > why
> > > before showing what does not and why.
> > >
> > > In the first scenario, which works, a SoapFault is thrown by our
> > provider's
> > > invoke(SOAPMessage) method under certain conditions, basically if
> > our
> > > server detects certain errors. Our provider looks like this:
> > >
> > > @WebServiceProvider
> > > @ServiceMode(value = Service.Mode.MESSAGE)
> > > public static class LdeWebServiceProvider implements
> > Provider<SOAPMessage>
> > > { @Override
> > > public SOAPMessage invoke(SOAPMessage soapRequest) {
> > > ...
> > > throw new SoapFault("Our message",
> > > Soap11.getInstance().getReceiver()); }
> > > }
> > >
> > > In SAAJOutInterceptor.handleMessage, the local variable saaj is
> null,
> > so
> > > the code path taken builds a SOAP message from scratch and plugs
> in
> > a
> > > W3CDOMStreamWriter. All of the interceptors then write to
> > > W3CDOMStreamWriter instead of the default XMLStreamWriter which
> > normally
> > > caches and writes to the HTTP wire. The W3CDOMStreamWriter allows
> me
> > to
> > > transform the DOM before it gets on the wire. Great stuff, it
> works.
> > >
> > > In the second scenario, I test our output feature where in addition
> > to an
> > > optional transformation, we have custom interceptors to do
> optional
> > XML
> > > validation before and after the XML transformation. After our
> > provider
> > > successfully processed a message, the output chain processing
> kicks
> > in and
> > > looks like this:
> > >
> > > Chain org.apache.cxf.phase.phaseinterceptorch...@c375934. Current
> > flow:
> > > setup [PolicyOutInterceptor]
> > > pre-logical [SwAOutInterceptor, SoapHeaderOutFilterInterceptor]
> > > post-logical [SoapPreProtocolOutInterceptor]
> > > prepare-send [MessageSenderInterceptor,
> MessageModeOutInterceptor]
> > > pre-stream [LoggingOutInterceptor, XmlDeclOutInterceptor*,
> > > AttachmentOutInterceptor, StaxOutInterceptor] pre-protocol
> > > [MessageModeOutInterceptorInternal, SAAJOutInterceptor,
> > > SOAPHandlerInterceptor, OurWSS4JOutInterceptor] write
> > [SoapOutInterceptor]
> > > pre-marshal [LogicalHandlerOutInterceptor,
> > ValidatingOutInterceptor*,
> > > TransformOutInterceptor*, ValidatingOutInterceptor*] marshal
> > > [BareOutInterceptor]
> > > write-ending [SoapOutEndingInterceptor]
> > > pre-protocol-ending [SAAJOutEndingInterceptor]
> > > pre-stream-ending [StaxOutEndingInterceptor]
> > > prepare-send-ending [MessageSenderEndingInterceptor]
> > >
> > > The interceptors marked with * are mine:
> > > - XmlDeclOutInterceptor forces the XML declaration to be written.
> > > - ValidatingOutInterceptor validates XML
> > > - TransformOutInterceptor transforms XML
> > > - ValidatingOutInterceptor validates XML
> > >
> > > The problem occurs if XML validation fails (the first validation in
> > this
> > > test).
> > >
> > > When the XML validation fails, an exception thrown, caught, and re-
> > thrown
> > > as a fault.
> > >
> > > At the start of fault processing, the chain when SAAJOutInterceptor
> > is
> > > called looks like this:
> > >
> > > Chain org.apache.cxf.phase.phaseinterceptorch...@77c16c5f.
> Current
> > flow:
> > > setup [ServerPolicyOutFaultInterceptor]
> > > prepare-send [MessageSenderInterceptor,
> Soap11FaultOutInterceptor]
> > > pre-stream [LoggingOutInterceptor, XmlDeclOutInterceptor*,
> > > StaxOutInterceptor] pre-protocol [WebFaultOutInterceptor,
> > > SAAJOutInterceptor, SOAPHandlerFaultOutInterceptor] write
> > > [SoapOutInterceptor]
> > > pre-marshal [LogicalHandlerFaultOutInterceptor]
> > > marshal [Soap11FaultOutInterceptorInternal]
> > > pre-protocol-ending [TransformOutFaultInterceptor*]
> > > prepare-send-ending [MessageSenderEndingInterceptor]
> > >
> > > The interceptors marked with * are mine:
> > > - XmlDeclOutInterceptor forces the XML declaration to be written.
> > > - TransformOutFaultInterceptor validates XML
> > >
> > > When I step through this SAAJOutInterceptor invocation, the saaj
> > variable
> > > is NOT null, so the code path taken is different from what I
> > described
> > > above. Instead of a W3CDOMStreamWriter, a dummy XMLStreamWriter is
> > created
> > > that throws away whatever is written to it:
> > >
> > > //as the SOAPMessage already has everything in place,
> we
> > do not
> > > need XMLStreamWriter to write //anything for us, so we just set
> > > XMLStreamWriter's output to a dummy output stream. XMLStreamWriter
> > > origWriter = message.getContent(XMLStreamWriter.class);
> > > message.put(ORIGINAL_XML_WRITER, origWriter);
> > >
> > > XMLStreamWriter dummyWriter =
> > > StaxUtils.createXMLStreamWriter(new OutputStream() { public void
> > write(int
> > > b) throws IOException {
> > > }
> > > public void write(byte b[], int off, int len)
> > throws
> > > IOException { }
> > > });
> > > message.setContent(XMLStreamWriter.class, dummyWriter);
> > >
> > > No wonder I get no SOAP fault information back, I get:
> > >
> > > <?xml version='1.0' encoding='ISO-8859-1'?>
> > > <SOAP-ENV:Envelope
> > > xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
> > > xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-
> > ENV:Header
> > > xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
> > <ais:requestID
> > >
> >
> xmlns:ais="http://com.seagullsw.appinterface/AppInterfaceServer">{c0a80
> > 102
> > > -00ce16ad0000010e75da25398002}</ais:requestID> </SOAP-ENV:Header>
> > > <SOAP-ENV:Body xmlns:SOAP-
> > ENV="http://schemas.xmlsoap.org/soap/envelope/"
> > > /> </SOAP-ENV:Envelope>
> > >
> > > Is this a bug? Why would there be a dummy writer put in place? Is
> > there
> > > another CXF way to do this?
> > >
> > > Thank you,
> > > Gary
> > >
> > > > -----Original Message-----
> > > > From: Gary Gregory
> > > > Sent: Friday, December 18, 2009 18:11
> > > > To: 'Daniel Kulp'; [email protected]
> > > > Subject: RE: Inflexible fault interceptor chain?
> > > >
> > > > Ok, that worked!
> > > >
> > > > Thank you Dan,
> > > > Gary
> > > >
> > > > > -----Original Message-----
> > > > > From: Daniel Kulp [mailto:[email protected]]
> > > > > Sent: Friday, December 18, 2009 07:33
> > > > > To: [email protected]
> > > > > Cc: Gary Gregory; Lee Breisacher; Nikolay Glazyrin
> > > > > Subject: Re: Inflexible fault interceptor chain?
> > > > >
> > > > >
> > > > > Honestly, the EASIEST way to accomplish this, since you are
> using
> > > >
> > > > soap,
> > > >
> > > > > is to
> > > > > add the SAAJOutInterceptor to the fault chain. Then, your
> > > >
> > > > interceptor
> > > >
> > > > > would
> > > > > live right before it's "ending" interceptor and do:
> > > > >
> > > > > message.getContext(SOAPMessage.class)
> > > > >
> > > > > to get the SAAJ model out. Since the SAAJ model implements
> the
> > DOM
> > > > > interfaces, you can then feed that into an XSLT processor or
> > similar
> > > >
> > > > to
> > > >
> > > > > transform it and then set a new version back with the
> setContent
> > > >
> > > > call.
> > > >
> > > > > Dan
> > > > >
> > > > > On Fri December 18 2009 4:13:29 am Gary Gregory wrote:
> > > > > > Hi All:
> > > > > >
> > > > > > I need to apply an XSL transformation to messages coming out
> of
> > CXF
> > > > >
> > > > > (our
> > > > >
> > > > > > users configure what the XSL looks like.) For a normal
> > > >
> > > > (successful)
> > > >
> > > > > > message, I have an interceptor (during Phase.PRE_MARSHAL)
> that
> > > >
> > > > uses
> > > >
> > > > > the
> > > > >
> > > > > > DOM aspect of a message. That works great. BTW, I get to the
> > DOM
> > > > >
> > > > > like
> > > > >
> > > > > > this:
> > > > > >
> > > > > > Node node = (Node) message.getContent(List.class).get(0);
> > > > > >
> > > > > > That seems brittle, is there a safer way to get to an aspect
> of
> > the
> > > > >
> > > > > message
> > > > >
> > > > > > I can feed to javax.xml.transform?
> > > > > >
> > > > > > The real issue comes with fault messages because the fault
> > chain
> > > >
> > > > uses
> > > >
> > > > > an
> > > >
> > > >
> >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > > >
> > > > > XML
> > > > >
> > > > > > StreamWriter.html>. The fault chain looks like this:
> > > > > >
> > > > > > Chain org.apache.cxf.phase.phaseinterceptorch...@3015b303.
> > Current
> > > > >
> > > > > flow:
> > > > > > setup [ServerPolicyOutFaultInterceptor]
> > > > > > prepare-send [MessageSenderInterceptor,
> > > >
> > > > Soap11FaultOutInterceptor]
> > > >
> > > > > > pre-stream [LoggingOutInterceptor, XmlDeclOutInterceptor*,
> > > > > > StaxOutInterceptor] pre-protocol [WebFaultOutInterceptor,
> > > > > > SOAPHandlerFaultOutInterceptor] write [SoapOutInterceptor]
> > > > > > pre-marshal [LogicalHandlerFaultOutInterceptor]
> > > > > > marshal [Soap11FaultOutInterceptorInternal]
> > > > > > pre-stream-ending [StaxOutEndingInterceptor,
> > > > > > TransformOutFaultInterceptor*] prepare-send-ending
> > > > > > [MessageSenderEndingInterceptor]
> > > > > >
> > > > > > FYI, the interceptors marked with * are our own:
> > > > > >
> > > > > > * XmlDeclOutInterceptor forces an XML declaration to
> be
> > > > >
> > > > > written.
> > > > >
> > > > > > * TransformOutFaultInterceptor is where I thought I
> > could
> > > > >
> > > > > transform
> > > > >
> > > > > > the fault XML message.
> > > > > >
> > > > > > The
> > > >
> > > >
> >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > > >
> > > > > XML
> > > > >
> > > > > > StreamWriter.html> looks like this:
> > > > > >
> > > > > > [StreamWriter: class com.ctc.wstx.sw.SimpleNsStreamWriter,
> > > >
> > > > underlying
> > > >
> > > > > > outputter:
> > > >
> > > >
> >
> com.ctc.wstx.sw.isolatin1xmlwri...@1125cf44<mailto:com.ctc.wstx.sw.ISOL
> > > >
> > > > > ati
> > > > >
> > > > > > n1xmlwri...@1125cf44>
> > > > > >
> > > > > > The com.ctc.wstx.sw.ISOLatin1XmlWriter wraps a
> > > > > > org.apache.cxf.io.CachedOutputStream, which in turns wraps:
> > > > > >
> > > > > > * currentStream - LoadingByteArrayOutputStream
> > > > > >
> > > > > > * flowThroughStream -
> > > > >
> > > > > AbstractHTTPDestination$WrappedOutputStream
> > > > >
> > > > > > All of this to say that when the chain's interceptors are
> > working
> > > > >
> > > > > with the
> > > > >
> > > > > > message's
> > > >
> > > >
> >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > > >
> > > > > XML
> > > > >
> > > > > > StreamWriter.html>, the bytes are cached and written to the
> > wire.
> > > >
> > > > It
> > > >
> > > > > is not
> > > > >
> > > > > > possible to catch the fault XML message and change it.
> > > > > >
> > > > > > The only thing I've come up with but not implemented yet
> would
> > be
> > > >
> > > > to
> > > >
> > > > > insert
> > > > >
> > > > > > an interceptor before the XML declaration is written and put
> > the
> > > >
> > > >
> >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > > >
> > > > > XML
> > > > >
> > > > > > StreamWriter.html> into a temp spot in the message content
> map,
> > > >
> > > > then
> > > >
> > > > > put a
> > > > >
> > > > > > new
> > > >
> > > >
> >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > > >
> > > > > XML
> > > > >
> > > > > > StreamWriter.html> on a byte array in its place. A pre-
> stream-
> > > >
> > > > ending
> > > >
> > > > > > interceptor can take those bytes, apply XSL to them and then
> > write
> > > > >
> > > > > them to
> > > > >
> > > > > > the original
> > > >
> > > >
> >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > > >
> > > > > XML
> > > > >
> > > > > > StreamWriter.html>, before putting the original
> > > >
> > > >
> >
> XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/
> > > >
> > > > > XML
> > > > >
> > > > > > StreamWriter.html> back in it original slot in the message
> > content
> > > > >
> > > > > map.
> > > > >
> > > > > > That seems like big old hack.
> > > > > >
> > > > > > Any ideas on a cleaner solution?
> > > > > >
> > > > > > Thank you,
> > > > > > Gary Gregory
> > > > > > Seagull Software
> > > > > > [email protected]
> > > > > > www.seagullsoftware.com
> > > > >
> > > > > --
> > > > > Daniel Kulp
> > > > > [email protected]
> > > > > http://www.dankulp.com/blog
> > >
> >
> > --
> > Daniel Kulp
> > [email protected]
> > http://www.dankulp.com/blog