Skip to main content

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

  • From: Sergey Beryozkin <sberyozkin@...>
  • 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 16:24:31 +0000

Hi Marek, and Santiago
On 01/02/13 13:06, Marek Potociar wrote:

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.

Yes, I agree it makes sense in most cases to support it.
I think there could be some issues though like double logging or similar, etc, when the response filter which throws the exception has been prioritized to be after such filters like logging one, etc.
The user might see for example from the in & out loggers:

Request: a
Response: aResponse
Response: aResponse2 or even aResponse

May be it is negligible this issue. Perhaps it can make sense to consider adding an annotation like @NonReentrant or similar either for 2.0 or 2.1 if the group agrees it can be warranted. I'm easy either way

Cheers. Sergey


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