Skip to main content

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Need clarification on Section 6.7

  • From: Marek Potociar <marek.potociar@...>
  • To: jsr339-experts@...
  • Subject: [jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Need clarification on Section 6.7
  • Date: Fri, 1 Feb 2013 14:06:21 +0100


On Feb 1, 2013, at 1:10 PM, Sergey Beryozkin <sberyozkin@...> wrote:

> On 01/02/13 12:02, Marek Potociar wrote:
>
>> On Feb 1, 2013, at 12:55 PM, Sergey Beryozkin<sberyozkin@...>  wrote:
>
>>> On 01/02/13 11:38, Marek Potociar wrote:
>>>> 
>>>> On Jan 31, 2013, at 6:29 PM, Sergey Beryozkin<sberyozkin@...>   wrote:
>>>> 
>>>>> On 31/01/13 16:57, Marek Potociar wrote:
>>>>>> Hi Bill,
>>>>>> I'm forwarding my recent reply to a similar question we received from
>>>>>> TCK team:
>>>>>> 
>>>>>> Global and globally name-bound filters and interceptors should be
>>>>>> invoked for all responses. Resource and method name-bound interceptors
>>>>>> should be invoked only for responses originated from the bound resource
>>>>>> or resource method.
>>>>>> 
>>>>>> I.e. if we define 2 groups of filters and interceptors based on their
>>>>>> binding:
>>>>>> 
>>>>>> G1: Global and globally name-bound (i.e. name-bound to the Application
>>>>>> sub-class) response filters and interceptors
>>>>>> - IMO the user intention with these is clearly to invoke them for ALL
>>>>>> responses
>>>>>> 
>>>>>> G2: Resource and method name-bound response filters and interceptors
>>>>>> - IMO the user intention with these is to invoke them only for 
>>>>>> responses
>>>>>> originated from a particular resource or method
>>>>>> 
>>>>> 
>>>>> What are resource-bound filters, is it:
>>>>> 
>>>>> @SomeName
>>>>> class MyFilter...
>>>>> 
>>>>> @SomeName
>>>>> @Path("/root")
>>>>> public class RootResource {
>>>>> }
>>>>> 
>>>>> Effectively MyFilter applies to all RootResource methods ?
>>>> 
>>>> Yes, exactly.
>>>> 
>>>>> 
>>>>>> With the groups defined above, here's what I think it should work
>>>>>> (Santiago, please correct me if you think otherwise):
>>>>>> 
>>>>>> UC1: Response returned from pre-matching filter:
>>>>>> - G1 gets invoked
>>>>>> 
>>>>>> UC2: Response produced by an ExceptionMapper from an exception that
>>>>>> originated in a pre-matching filter:
>>>>>> - G1 gets invoked
>>>>>> 
>>>>>> UC3: Response returned from post-matching filter:
>>>>>> - G2 + G1 gets invoked
>>>>>> 
>>>>>> UC4: Response returned from matched resource method:
>>>>>> - G2 + G1 gets invoked
>>>>>> 
>>>>>> UC5: Response produced by an ExceptionMapper from an exception that
>>>>>> originated in a matched resource method:
>>>>>> - G2 + G1 gets invoked
>>>>>> 
>>>>>> UC6: Response produced by an ExceptionMapper from an exception that
>>>>>> originated in a response filter or interceptor processing a response to
>>>>>> a matched request:
>>>>>> - G2 + G1 gets invoked
>>>>>> 
>>>>>> UC7: Response produced by an ExceptionMapper from an exception that
>>>>>> originated in a response filter or interceptor processing a response to
>>>>>> an unmatched request:
>>>>>> - G1 gets invoked
>>>>>> 
>>>>>> Additionally, there is a condition in the spec that prevents infinite
>>>>>> loops for UC6 and UC7 (see 2nd paragraph in section 6.7 of the spec).
>>>>>> So, to sum-up, here's the conceptual algorithm I have in mind:
>>>>>> 
>>>>>> start request processing
>>>>>> store G1 response filters and interceptors into the request context
>>>>>> try {
>>>>>> invoke pre-matching request filters
>>>>>> match request
>>>>>> if (request matched) {
>>>>>> store G2 response filters and interceptors into the request context
>>>>>> invoke global and bound post-matching request filters
>>>>>> invoke resource method
>>>>>> }
>>>>>> invoke all response filters stored to the request context
>>>>>> } catch (Exception ex) {
>>>>>> try {
>>>>>> map exception to response
>>>>>> invoke all response filters stored to the request context
>>>>>> } catch (Exception ex) {
>>>>>> propagate exception to the hosting container
>>>>>> }
>>>>>> }
>>>>>> exit request processing
>>>>>> 
>>>>> I think it basically says that in Bill's (2) case all response filters 
>>>>> are executed,
>>>>> What about his case 3 though, I think it is UC6, UC7 points, still not 
>>>>> clear what if the mapped response has to run through remaining filters 
>>>>> or not, for example,
>>>>> 
>>>>> A->B, A throws the exception, is B still given a chance to handle the 
>>>>> mapped response ?
>>>> 
>>>> I thought the algorithm above is also clear on that. For a mapped 
>>>> exception response, ALL applicable response filters are invoked (not 
>>>> only "remaining ones"). So, both, A and B are invoked.
>>>> 
>>>> FWIW, throwing an exception from a filter is IMO not the programming 
>>>> model we should optimize for. Such exceptions should mostly indicate 
>>>> that there is a problem with the filter implementation as such.
>>>> 
>>> 
>>> Hmm..., both A and B are response filters, they are processing some 
>>> Response, A is first to process it and decides to throw an exception 
>>> (intentionally) - what I don't quite get is whether it means we have an 
>>> immediate 500, or, we try to map this A-originated exception and if the 
>>> mapping was successful, then let B a chance to handle this mapped 
>>> response, even though A thought it was an exception case...
>>> 
>>> I'm sorry if I'm slow :-), but I'm still a bit unclear.
>
>> If A throws an exception that gets mapped, then both A and B will be 
>> invoked on the mapped response. If A throws an exception again, then the 
>> exception is going to be propagated to the hosting container.
>
>> Hope it's crystal clear now,
> 
> Definitely is, thanks Marek. The fact that A can be re-entered twice was 
> definitely something I was not getting.
> 
> Are we sure it is correct though to allow re-entrance into A and indeed all 
> the response filters before A if A throws the exception intentionally, 
> effectively saying 'I've had enough with processing this current response' 
> ? Not really sure whether it is right or not, I guess it is interesting to 
> imagine a bit the possible pros and cons

I'm not 100% sure, but as I wrote earlier, I believe that we should not 
promote programming models where a filter throws an exception in a "stateful" 
way, i.e. in a way that it would not expect to be applied to the mapped 
response. 

My main motivation factors for promoting this approach are:

1. it's based on simple rules and JAX-RS users will be able to grasp these 
rules without too much confusion
2. a response filters should be invoked for any response to which they are 
applicable. 
3. in general it's better to give all response filters involved in the given 
request processing a chance to react and process a mapped exception response 
that to ignore them for such responses.

In general, it means that global filters should be invoked for all responses 
and bound filters to responses originating from a component. Note here that a 
response to a mapped exception (thrown anyway in the req/resp processing) 
should not deviate from this rule IMO. While it may not be obvious with 2 
response filters, consider scenario with 3 filters:

A->B->C; B throws exception that gets mapped to a response R(ex).

IMO the A should be given a chance to process the new R(ex) response.

Cheers,
Marek

> 
> Cheers, Sergey
> 
> 
>> Marek
>
>>> 
>>> thanks, Sergey
>>> 
>>>> HTH,
>>>> Marek
>>>> 
>>>>> 
>>>>> Thanks, Sergey
>>>>> 
>>>>> 
>>>>> 
>>>>>> HTH,
>>>>>> Marek
>>>>>> 
>>>>>> 
>>>>>> On Jan 30, 2013, at 4:29 PM, Bill Burke<bburke@...
>>>>>> <mailto:bburke@...>>   wrote:
>>>>>> 
>>>>>>> The section on filters and exception handling is unclear.
>>>>>>> 
>>>>>>> if an exception is thrown from a resource method:
>>>>>>> 
>>>>>>> 1. An exception mapper is found
>>>>>>> 2. bound and global filters are executed on the response
>>>>>>> 
>>>>>>> If an exception is thrown from a request filter:
>>>>>>> 
>>>>>>> 1. An exception mapper is found and executed
>>>>>>> 2. response filters are executed. BOund response filters only executed
>>>>>>> if this is not prematch
>>>>>>> 
>>>>>>> If an exception is thrown from a response filter:
>>>>>>> 
>>>>>>> 1. An exception maper is found and executed
>>>>>>> 2. ??? I assume no response filters are then executed?
>>>>>>> --
>>>>>>> Bill Burke
>>>>>>> JBoss, a division of Red Hat
>>>>>>> http://bill.burkecentral.com
>>>>>> 
>>>>> 
>>>>> 
>>>> 
>>> 
>>> 
>
> 



[jsr339-experts] Re: [jax-rs-spec users] Re: Need clarification on Section 6.7

Marek Potociar 02/01/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Need clarification on Section 6.7

Sergey Beryozkin 02/01/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Need clarification on Section 6.7

Marek Potociar 02/01/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Need clarification on Section 6.7

Sergey Beryozkin 02/01/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Need clarification on Section 6.7

Marek Potociar 02/01/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Need clarification on Section 6.7

Sergey Beryozkin 02/01/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Re: Need clarification on Section 6.7

Marek Potociar 02/01/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Re: Need clarification on Section 6.7

Sergey Beryozkin 02/04/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Re: Re: Need clarification on Section 6.7

Marek Potociar 02/04/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Re: Re: Need clarification on Section 6.7

Sergey Beryozkin 02/04/2013

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Need clarification on Section 6.7

Santiago Pericas-Geertsen 02/01/2013
 
 
Close
loading
Please Confirm
Close