cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Interceptor chains, one way requests, WSA FaultTo
Date Fri, 08 Oct 2010 11:41:59 GMT
Just FYI, here is a commit to do with the optional support for decoupled
faults in case of oneway requests :

http://svn.apache.org/viewvc?rev=1005784&view=rev
See also CXF-3052.

If users find that they need to bypass the restrictions around dealing with
oneway requests and decoupled faults then they can simply set a contextual
boolean property
"org.apache.cxf.ws.addressing.oneway.decoupled_fault_support" to true or
explicitly register a OneWayDecoupledFaultHandler via annotations,
programmatically, etc.

Hope this is a reasonable compromise

cheers, Sergey

On Tue, Oct 5, 2010 at 6:16 PM, Sergey Beryozkin <sberyozkin@gmail.com>wrote:

> Hi
>
> I decided to go ahead and experiment with implementing a support for
> decoupled faults for oneway requests so that we at least could tell users
> how that can be done using custom interceptors if that is what is needed in
> a particular case.
> Originally I was planning just to have a MAPCodec interceptor dealing with
> posting a fault in its handleFault callback due to PhaseInterceptorChain not
> delegating to the faultObserver in case of oneways. That is not the most
> elegant solution though given that handleFault is meant to notify that a
> given in/out interceptor should do some cleanup. Additionally, it is not
> quite clear how to dynamically setup a fault interceptor chain so that the
> fault can be properly serialized and sent.
>
> So Dan suggested that PhaseInterceptorChain gets updated so that a oneway
> check is done after the unwind() is called on the current chain. Next, the
> custom in or out interceptor would trick PhaseInterceptorChain by chnaging
> the oneway status on the exchange to a two way one and also set up a Conduit
> with the destination address pointing to a faultTo EPR address.
>
> Here is a sample code :
>
> public void handleFault(SoapMessage message) {
>         if (!message.getExchange().isOneWay()) {
>             // do some two way specific cleanup
>         } else if (!ContextUtils.isRequestor(message)) {
>             Exchange exchange = message.getExchange();
>             Message inMessage = exchange.getInMessage();
>             final AddressingPropertiesImpl maps =
> ContextUtils.retrieveMAPs(inMessage, false, false, true);
>             final EndpointReferenceType reference = maps.getFaultTo();
>
>             if (maps != null &&
> !ContextUtils.isGenericAddress(exReference)) {
>                 exchange.setOneWay(false);
>
>
>                 // set the new Conduit
>                 final EndpointInfo ei =
> exchange.get(Endpoint.class).getEndpointInfo();
>                 exchange.setDestination(new Destination() {
>                     public EndpointReferenceType getAddress() {
>                         return reference;
>                     }
>                     public Conduit getBackChannel(Message inMessage,
> Message partialResponse,
>                                                   EndpointReferenceType
> address) throws IOException {
>
>                         Bus bus = inMessage.getExchange().get(Bus.class);
>                         ConduitInitiator conduitInitiator
>                             =
> bus.getExtension(ConduitInitiatorManager.class)
>
> .getConduitInitiatorForUri(reference.getAddress().getValue());
>                         if (conduitInitiator != null) {
>                             Conduit c =
> conduitInitiator.getConduit(ei,reference);
>                             // ensure decoupled back channel input stream
> is closed
>                             c.setMessageObserver(new MessageObserver() {
>                                 public void onMessage(Message m) {
>                                     InputStream is =
> m.getContent(InputStream.class);
>                                     if (is != null) {
>                                         try {
>                                             is.close();
>                                         } catch (Exception e) {
>                                             // ignore
>                                         }
>                                     }
>                                 }
>                             });
>                             return c;
>                         }
>                         return null;
>                     }
>                     public MessageObserver getMessageObserver() {
>                         return null;
>                     }
>                     public void shutdown() {
>                     }
>                     public void setMessageObserver(MessageObserver
> observer) {
>                     }
>                 });
>
>             }
>
>         }
>     }
>
> This code to do with setting up a destination is complicated but is
> boilerplate....
>
>
> The end result is that a fault is processed properly by a fault observer
> even for oneways and is forwarded to the faultTo decoupled address. And an
> empty SOAP response is sent to ReplyTo as well.
>
> So - I'm assuming it is safe enough to update PhaseInterceptorChain so that
> fault interceptors are involved even for oneway requests failing for
> whatever reasons - a fault can be sent to a decoupled destination even as
> part of some custom protocol.
>
> I'm presuming that updating a MapCodec with the above code is not something
> which we can do right now, right, due to the compliance concerns  ? In this
> case a custom interceptor can be added if needed
>
> cheers, Sergey
>
>
>
> On Fri, Oct 1, 2010 at 2:31 PM, Oliver Wulff <oliver.wulff@sopera.com>wrote:
>
>> Hi Sergey
>>
>> IMHO, if you use WSDL 1.1 and want to return a fault you must define an
>> empty outpt message - even it's just a kind of place holder.
>>
>>
>> If you use FaultTo and ReplyTo the anonymous EPR, the service send the
>> response on the back channel.
>>
>> Oli
>>
>> ________________________________________
>> Von: Sergey Beryozkin [sberyozkin@gmail.com]
>> Gesendet: Freitag, 1. Oktober 2010 13:42
>> An: dev@cxf.apache.org
>> Cc: Daniel Kulp
>> Betreff: Re: Interceptor chains, one way requests, WSA FaultTo
>>
>> Hi Oli,
>>
>> thanks for the clarifications,
>>
>> I'm wondering, is it indeed "Robust In-Only" case that we are talking
>> about
>> here :
>>
>>
>> http://www.pacificspirit.com/Authoring/async/async-scenarios.html#twoway-robust-inonly-b
>>
>> so we have a client sending a oneway request, getting a 202 ACK, and then
>> possibly getting a fault back at some local endpoint. But CXF does not
>> support WSDL 2.0...
>>
>> cheers, Sergey
>>
>> On Fri, Oct 1, 2010 at 8:03 AM, Oliver Wulff <oliver.wulff@sopera.com
>> >wrote:
>>
>> > Hi Sergey
>> >
>> > I thought that wsdl 1.1 specification requires that a fault message is
>> used
>> > only in combination with an output message.
>> > WSDL 2.0 defines the MEP called "Robust In-Only" where you could define
>> an
>> > input and a fault message.
>> >
>> > I'm only aware of WS-ReliableMessaging where a soap envelope can be
>> > returned for a one-way message to send the acknowledges back where soap
>> body
>> > itself is empty. This is only valid if the Anonymous epr is used for
>> AcksTo
>> > element.
>> >
>> > Oli
>> >
>> > ________________________________________
>> > Von: Sergey Beryozkin [sberyozkin@gmail.com]
>> > Gesendet: Freitag, 1. Oktober 2010 00:19
>> > An: Daniel Kulp
>> > Cc: dev@cxf.apache.org
>> > Betreff: Re: Interceptor chains, one way requests, WSA FaultTo
>> >
>> > Hi
>> >
>> > I'm wondering, does Fault qualify as a response in case of one way
>> > requests.
>> >
>> > I'm thinking that may be specifying a decoupled FaultTo as part of
>> oneways
>> > is an attempt to find out if a given oneway request ultimately succeeded
>> or
>> > not.
>> >
>> > Thus I'm not sure what the right answer is here. It's part of the
>> advanced
>> > WSA-related transactions framework test suite but if it is a valid test
>> - I
>> > do not know...
>> >
>> > But I guess that code I'm prototyping may also help in cases where we
>> have
>> > a
>> > 2 way request and decoupled ReplyTo and FaultTo values. At the moment,
>> the
>> > fault will be sent to the decoupled ReplyTo (because
>> > ContextUtils.rebaseUtils uses replyTo to rebase)...
>> >
>> > We then can decide if we want that code to execute in case of oneways or
>> > not.
>> >
>> > cheers, Sergey
>> >
>> >
>> > On Thu, Sep 30, 2010 at 7:45 PM, Daniel Kulp <dkulp@apache.org> wrote:
>> >
>> > >
>> > > My question is:  is this even a valid use case?
>> > >
>> > > According to the WS-I Basic Profile:
>> > >
>> > >
>> > > R2714 For one-way operations, an INSTANCE MUST NOT return a HTTP
>> response
>> > > that
>> > > contains an envelope. Specifically, the HTTP response entity-body must
>> be
>> > > empty.
>> > >
>> > > R2750 A CONSUMER MUST ignore an envelope carried in a HTTP response
>> > message
>> > > in
>> > > a one-way operation.
>> > >
>> > > R2727 For one-way operations, a CONSUMER MUST NOT interpret a
>> successful
>> > > HTTP
>> > > response status code (i.e., 2xx) to mean the message is valid or that
>> the
>> > > receiver would process it.
>> > >
>> > > One-way operations do not produce SOAP responses. Therefore, the
>> Profile
>> > > prohibits sending a SOAP envelope in response to a one-way operation.
>> > >
>> > >
>> > > Thus, producing a Fault as part of processing a One-Way operation
>> would
>> > be
>> > > against the spec.
>> > >
>> > >
>> > > Dan
>> > >
>> > >
>> > >
>> > >
>> > > On Thursday 30 September 2010 1:32:11 pm Sergey Beryozkin wrote:
>> > > > Hi
>> > > >
>> > > > I'm looking at the following issue.
>> > > > A oneway request with a decoupled WSA FaultTo address is processed
>> on
>> > the
>> > > > server side and then a fault is thrown.
>> > > > MapCodec and MapAggregator interceptors are not handling this case
>> at
>> > the
>> > > > moment.
>> > > >
>> > > > Eoghan clarified how ContextUtils.rebaseAddress used by
>> MapAggregator
>> > > > works. Particularly, a partial response is sent back asap, and then
>> > > > an out message is prepared such that a normal response is sent to
>> the
>> > > > decoupled ReplyTo (during this process an out interceptor chain is
>> > > > created).
>> > > >
>> > > > The question is how to forward a fault to the decoupled address in
>> case
>> > > of
>> > > > oneway requests and particularly, how to build a proper chain.
>> > > > I'm prototyping the following code in MapCodec.handleFault() :
>> > > >
>> > > > // MapCodec::handleFault(Message message)
>> > > >             if (oneWay and !isRequestor())
>> > > >             {
>> > > >                Exchange exchange = message.getExchange();
>> > > >
>> > > >                // we need the input message so that we can get the
>> WSA
>> > > > properties from it
>> > > >
>> > > >                Message inMessage = exchange.getInMessage();
>> > > >                AddressingPropertiesImpl maps =
>> > > >                    ContextUtils.retrieveMAPs(inMessage, false,
>> false,
>> > > > true); if (maps != null &&
>> > > > !ContextUtils.isGenericAddress(maps.getFaultTo())) {
>> > > >
>> > > >                 // boilerplate code for getting a backChannel, using
>> > > > inMessage
>> > > >                 Destination target = inMessage.getDestination();
>> > > >                 exchange.setOutMessage(message);
>> > > >
>> > > >                 Conduit backChannel =
>> target.getBackChannel(inMessage,
>> > > >
>> > message,
>> > > >
>> > > > maps.getFaultTo());
>> > > >
>> > > >                 // Set up the chain
>> > > >                 InterceptorChain chain =
>> > > > OutgoingChainInterceptor.getOutInterceptorChain(exchange);
>> > > >                 message.setInterceptorChain(chain);
>> > > >
>> > > >                 exchange.put(ConduitSelector.class,
>> > > >                                      new
>> > > > PreexistingConduitSelector(backChannel,
>> > > >
>> > > > exchange.get(Endpoint.class)));
>> > > >
>> > > >                 chain.doIntercept(message)
>> > > >            }
>> > > >
>> > > >
>> > > > The question is basically how to set up an out chain properly to
>> deal
>> > > with
>> > > > delivering a fault message in case of oneway requests.
>> > > >
>> > > > Some clarifications would help
>> > > > thanks, Sergey
>> > >
>> > > --
>> > > Daniel Kulp
>> > > dkulp@apache.org
>> > > http://dankulp.com/blog
>> > >
>> >
>>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message