users@jax-rs-spec.java.net

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

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Fri, 1 Feb 2013 12:10:04 +0000

On 01/02/13 12:02, Marek Potociar wrote:
>
> On Feb 1, 2013, at 12:55 PM, Sergey Beryozkin<sberyozkin_at_talend.com> wrote:
>
>> On 01/02/13 11:38, Marek Potociar wrote:
>>>
>>> On Jan 31, 2013, at 6:29 PM, Sergey Beryozkin<sberyozkin_at_talend.com> 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

Cheers, Sergey


> Marek
>
>>
>> thanks, Sergey
>>
>>> HTH,
>>> Marek
>>>
>>>>
>>>> Thanks, Sergey
>>>>
>>>>
>>>>
>>>>> HTH,
>>>>> Marek
>>>>>
>>>>>
>>>>> On Jan 30, 2013, at 4:29 PM, Bill Burke<bburke_at_redhat.com
>>>>> <mailto:bburke_at_redhat.com>> 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
>>>>>
>>>>
>>>>
>>>
>>
>>
>