You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "Muller, Anthony" <an...@sap.com> on 2012/07/05 12:17:11 UTC
JAX-RS services - Interceptor
Hello,
I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
Example of concurrent calls:
Client 1 : [POST] <baseurl>/books/1234/chapters/ --> Book « 1234 » must be locked to avoid concurrent modifications
Client 2 : [POST] <baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book « 1234 » is currently locked
So, I wish to add a CXF interceptor on URL starting by « /books/{bookId}/... », but I don't see how can I do...
(In my case, I can not use Servlet API...)
Can you help ?
Thanks and regards,
Anthony
RE: JAX-RS services - Interceptor
Posted by "Muller, Anthony" <an...@sap.com>.
Hi Sergey,
We are using CXF 2.3.8 and I can confirm that uriInfo.getPathParameters() return an empty map.
Effectivelly, we are using CXFNonSpringJaxrsServlet. Great you will add "jaxrs:invoker" extension asap :)
Thanks and regards,
Anthony
-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
Sent: jeudi 5 juillet 2012 14:17
To: Muller, Anthony
Cc: users@cxf.apache.org
Subject: Re: JAX-RS services - Interceptor
Hi Anthony
On 05/07/12 12:50, Muller, Anthony wrote:
> Thx Sergey, that seems fine!
>
> I'm trying using UriInfo injection and I'm trying to detect the case where I must lock my resource.
>
> I hope to get the {bookId} easily, but there is nothing into path parameters... Normal?
>
> I wrote something like:
>
> @Override
> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass) {
> System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
>
> if(uriInfo.getPath().contains("/books/")) {
> final MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
> final Set<String> pathParameterNames = pathParameters.keySet();
> for (final String pathParameterName : pathParameterNames) {
> System.out.println(pathParameterName + " : " + pathParameters.getFirst(pathParameterName));
> }
> }
>
> return null;
> }
>
I'm looking at the CXF code and I can confirm that the operation
matching is attempted before the filters are run. So if you have a
method such as
@POST
@Path("{index}")
public void addBook(@PathParam("index") int index, Book book) {}
and a request URI ending with something like /books/123
then UriInfo should return an "index":123 pair
Can you confirm please that in your above case the request URI is
expected to match a method with @PathParam annotations ?
By the way, perhaps there's one option for this case.
Instead of doing the filters, consider creating a custom invoker which
gets the control immediately before and after the matched method is
invoked. For example:
http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java
Custom invokers are registered using a jaxrs:invoker extension. However,
I recall you might be using CXFNonSpringJaxrsServlet - so is not
possible to register invokers from this servlet yet unless you extend
the servlet class and set the invoker on JAXRSServerFactoryBean. I'll
get this specific issue fixed,
But using the filters should also do OK
Sergey
>
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: jeudi 5 juillet 2012 12:49
> To: users@cxf.apache.org
> Cc: Muller, Anthony
> Subject: Re: JAX-RS services - Interceptor
>
> Hi Anthony
> On 05/07/12 11:17, Muller, Anthony wrote:
>> Hello,
>>
>> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>>
>> Example of concurrent calls:
>> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book< 1234> must be locked to avoid concurrent modifications
>> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book< 1234> is currently locked
>>
>> So, I wish to add a CXF interceptor on URL starting by< /books/{bookId}/...>, but I don't see how can I do...
>>
>> (In my case, I can not use Servlet API...)
>>
>
> I think the simplest way is to create a class implementing both
> RequestHandler and ResponseHandler interfaces and have a '@Context
> UriInfo' injected (which is thread safe).
>
> You can use UriInfo.getPath() method to get values like
> 'books/1234/chapters', etc. Perhaps, even simpler, is to do
> RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
> type Message and is available as a method parameter.
>
> This implementation will 'lock' by updating the concurrent cache of some
> sort (Colm done few Ehcache based implementations in CXF for example) in
> its handleRequest method and 'unlock' in its handleResponse if it is
> 'books/1234/chapters'. It can be registered as a jaxrs:provider
>
>
>
> Hope that helps :-)
>
> Sergey
>
>> Can you help ?
>>
>> Thanks and regards,
>> Anthony
>>
>
Re: JAX-RS services - Interceptor
Posted by Sergey Beryozkin <sb...@gmail.com>.
FYI:
http://svn.apache.org/viewvc?rev=1359298&view=rev
Sergey
On 09/07/12 18:27, Sergey Beryozkin wrote:
> Actually, I forgot to commit the actual changes to the test filter,
> sorry about it, will be merging now :-)
>
> Sergey
> On 09/07/12 13:20, Sergey Beryozkin wrote:
>> Hi Anthony
>> On 05/07/12 21:53, Muller, Anthony wrote:
>>> Thanks for all these informations Sergey, your help is very appreciated!
>>>
>>
>> No problems :-), please see some comments below
>>
>>> Anthony
>>>
>>> Envoyé de mon iPad
>>>
>>> Le 5 juil. 2012 à 17:37, "Sergey Beryozkin"<sb...@gmail.com> a
>>> écrit :
>>>
>>>> Hi Anthony
>>>>
>>>> Sorry for a delay
>>>> On 05/07/12 15:50, Muller, Anthony wrote:
>>>>> Sergey,
>>>>>
>>>>> More particularly, could you confirm handleRequest ans
>>>>> handleResponse will still be called before and after any REST calls?
>>>>>
>>>>> I don't like to have a lock never removed! :)
>>>>>
>>>> As it happens at the moment, if the exception is thrown during a
>>>> call to
>>>> the resource method, then the out filters (ResponseHandler) are not
>>>> called so effectively a lock will stay where it is at the moment.
>>>>
>>>> It appears things are not going to easy for you :-).
>>>> Few options are still available but given the fact you can not use
>>>> Spring and that CXF 2.3.x has been made obsolete makes it a bit tricky
>>>> to plan for a best approach.
>>>>
>>>> First of all, regarding that missing path parameter. I'll write a test
>>>> later on and fix if needed, but your custom approach to do with parsing
>>>> the URI looks OK.
>>>>
>>>> Now, using the custom invoker would be perfect in this case because the
>>>> exceptions will be caught early. But the fix I will apply to get
>>>> CXFNonSpringJAXRSServlet accept custom invokers won't make it to 2.3.8.
>>>>
>>>> Next is the possible workaround where your resource method makes sure
>>>> that no exception ever escapes it: returning Response which will have a
>>>> proper status code set will be the easiest way to achieve it
>>>>
>>>> Next option is to have your composite filter also implement CXF
>>>> OutFaultInterceptor, example:
>>>> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java
>>>>
>>>>
>>>>
>>>> and register it as jaxrs:outFaultInterceptors, however I can see
>>>> CXFNonSpringJAXRSServlet does only recognizes in/out interceptors but
>>>> not fault ones.
>>>>
>>>> So I think right now the best approach, given that you can not use
>>>> Spring/Blueprint, is to have the resource method which is being locked
>>>> ensure that no exception escapes and use the current filter
>>>> implementation.
>>>>
>>>> I'll take care of fixing CXFNonSpringJaxrsServlet to recognize custom
>>>> invokers and fault interceptors,
>> that is supported with "jaxrs.invoker" and "jaxrs.outFaultInterceptors",
>> starting from CXF 2.4.9-SNAPSHOT
>>
>>> and check why UriInfo.getPathParameters
>>>> does not return the parameters as expected
>>
>> That actually works for me, please see the update to the test filter
>> from the revision history at
>> https://issues.apache.org/jira/browse/CXF-4413
>>
>> For UriInfo.getPathParameters to return a non-empty map (either from
>> within the filter code or the actual resource method code), there has to
>> be a *matching* resource method available, with its @Path having at
>> least one template variable. May be there are some issues to do with
>> getting the path parameters from UriInfo in CXF 2.3.8, but things work
>> as expected in later versions
>>
>> Cheers, Sergey
>>
>>
>>>>
>>>>> Anthony
>>>>>
>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: JAX-RS services - Interceptor
Posted by "Muller, Anthony" <an...@sap.com>.
Great, thanks again Sergey!
Envoyé de mon iPad
Le 9 juil. 2012 à 19:27, "Sergey Beryozkin" <sb...@gmail.com> a écrit :
> Actually, I forgot to commit the actual changes to the test filter,
> sorry about it, will be merging now :-)
>
> Sergey
> On 09/07/12 13:20, Sergey Beryozkin wrote:
>> Hi Anthony
>> On 05/07/12 21:53, Muller, Anthony wrote:
>>> Thanks for all these informations Sergey, your help is very appreciated!
>>>
>>
>> No problems :-), please see some comments below
>>
>>> Anthony
>>>
>>> Envoyé de mon iPad
>>>
>>> Le 5 juil. 2012 à 17:37, "Sergey Beryozkin"<sb...@gmail.com> a
>>> écrit :
>>>
>>>> Hi Anthony
>>>>
>>>> Sorry for a delay
>>>> On 05/07/12 15:50, Muller, Anthony wrote:
>>>>> Sergey,
>>>>>
>>>>> More particularly, could you confirm handleRequest ans
>>>>> handleResponse will still be called before and after any REST calls?
>>>>>
>>>>> I don't like to have a lock never removed! :)
>>>>>
>>>> As it happens at the moment, if the exception is thrown during a call to
>>>> the resource method, then the out filters (ResponseHandler) are not
>>>> called so effectively a lock will stay where it is at the moment.
>>>>
>>>> It appears things are not going to easy for you :-).
>>>> Few options are still available but given the fact you can not use
>>>> Spring and that CXF 2.3.x has been made obsolete makes it a bit tricky
>>>> to plan for a best approach.
>>>>
>>>> First of all, regarding that missing path parameter. I'll write a test
>>>> later on and fix if needed, but your custom approach to do with parsing
>>>> the URI looks OK.
>>>>
>>>> Now, using the custom invoker would be perfect in this case because the
>>>> exceptions will be caught early. But the fix I will apply to get
>>>> CXFNonSpringJAXRSServlet accept custom invokers won't make it to 2.3.8.
>>>>
>>>> Next is the possible workaround where your resource method makes sure
>>>> that no exception ever escapes it: returning Response which will have a
>>>> proper status code set will be the easiest way to achieve it
>>>>
>>>> Next option is to have your composite filter also implement CXF
>>>> OutFaultInterceptor, example:
>>>> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java
>>>>
>>>>
>>>> and register it as jaxrs:outFaultInterceptors, however I can see
>>>> CXFNonSpringJAXRSServlet does only recognizes in/out interceptors but
>>>> not fault ones.
>>>>
>>>> So I think right now the best approach, given that you can not use
>>>> Spring/Blueprint, is to have the resource method which is being locked
>>>> ensure that no exception escapes and use the current filter
>>>> implementation.
>>>>
>>>> I'll take care of fixing CXFNonSpringJaxrsServlet to recognize custom
>>>> invokers and fault interceptors,
>> that is supported with "jaxrs.invoker" and "jaxrs.outFaultInterceptors",
>> starting from CXF 2.4.9-SNAPSHOT
>>
>>> and check why UriInfo.getPathParameters
>>>> does not return the parameters as expected
>>
>> That actually works for me, please see the update to the test filter
>> from the revision history at
>> https://issues.apache.org/jira/browse/CXF-4413
>>
>> For UriInfo.getPathParameters to return a non-empty map (either from
>> within the filter code or the actual resource method code), there has to
>> be a *matching* resource method available, with its @Path having at
>> least one template variable. May be there are some issues to do with
>> getting the path parameters from UriInfo in CXF 2.3.8, but things work
>> as expected in later versions
>>
>> Cheers, Sergey
>>
>>
>>>>
>>>>> Anthony
>>>>>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com
Re: JAX-RS services - Interceptor
Posted by Sergey Beryozkin <sb...@gmail.com>.
Actually, I forgot to commit the actual changes to the test filter,
sorry about it, will be merging now :-)
Sergey
On 09/07/12 13:20, Sergey Beryozkin wrote:
> Hi Anthony
> On 05/07/12 21:53, Muller, Anthony wrote:
>> Thanks for all these informations Sergey, your help is very appreciated!
>>
>
> No problems :-), please see some comments below
>
>> Anthony
>>
>> Envoyé de mon iPad
>>
>> Le 5 juil. 2012 à 17:37, "Sergey Beryozkin"<sb...@gmail.com> a
>> écrit :
>>
>>> Hi Anthony
>>>
>>> Sorry for a delay
>>> On 05/07/12 15:50, Muller, Anthony wrote:
>>>> Sergey,
>>>>
>>>> More particularly, could you confirm handleRequest ans
>>>> handleResponse will still be called before and after any REST calls?
>>>>
>>>> I don't like to have a lock never removed! :)
>>>>
>>> As it happens at the moment, if the exception is thrown during a call to
>>> the resource method, then the out filters (ResponseHandler) are not
>>> called so effectively a lock will stay where it is at the moment.
>>>
>>> It appears things are not going to easy for you :-).
>>> Few options are still available but given the fact you can not use
>>> Spring and that CXF 2.3.x has been made obsolete makes it a bit tricky
>>> to plan for a best approach.
>>>
>>> First of all, regarding that missing path parameter. I'll write a test
>>> later on and fix if needed, but your custom approach to do with parsing
>>> the URI looks OK.
>>>
>>> Now, using the custom invoker would be perfect in this case because the
>>> exceptions will be caught early. But the fix I will apply to get
>>> CXFNonSpringJAXRSServlet accept custom invokers won't make it to 2.3.8.
>>>
>>> Next is the possible workaround where your resource method makes sure
>>> that no exception ever escapes it: returning Response which will have a
>>> proper status code set will be the easiest way to achieve it
>>>
>>> Next option is to have your composite filter also implement CXF
>>> OutFaultInterceptor, example:
>>> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java
>>>
>>>
>>> and register it as jaxrs:outFaultInterceptors, however I can see
>>> CXFNonSpringJAXRSServlet does only recognizes in/out interceptors but
>>> not fault ones.
>>>
>>> So I think right now the best approach, given that you can not use
>>> Spring/Blueprint, is to have the resource method which is being locked
>>> ensure that no exception escapes and use the current filter
>>> implementation.
>>>
>>> I'll take care of fixing CXFNonSpringJaxrsServlet to recognize custom
>>> invokers and fault interceptors,
> that is supported with "jaxrs.invoker" and "jaxrs.outFaultInterceptors",
> starting from CXF 2.4.9-SNAPSHOT
>
>> and check why UriInfo.getPathParameters
>>> does not return the parameters as expected
>
> That actually works for me, please see the update to the test filter
> from the revision history at
> https://issues.apache.org/jira/browse/CXF-4413
>
> For UriInfo.getPathParameters to return a non-empty map (either from
> within the filter code or the actual resource method code), there has to
> be a *matching* resource method available, with its @Path having at
> least one template variable. May be there are some issues to do with
> getting the path parameters from UriInfo in CXF 2.3.8, but things work
> as expected in later versions
>
> Cheers, Sergey
>
>
>>>
>>>> Anthony
>>>>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: JAX-RS services - Interceptor
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Anthony
On 05/07/12 21:53, Muller, Anthony wrote:
> Thanks for all these informations Sergey, your help is very appreciated!
>
No problems :-), please see some comments below
> Anthony
>
> Envoyé de mon iPad
>
> Le 5 juil. 2012 à 17:37, "Sergey Beryozkin"<sb...@gmail.com> a écrit :
>
>> Hi Anthony
>>
>> Sorry for a delay
>> On 05/07/12 15:50, Muller, Anthony wrote:
>>> Sergey,
>>>
>>> More particularly, could you confirm handleRequest ans handleResponse will still be called before and after any REST calls?
>>>
>>> I don't like to have a lock never removed! :)
>>>
>> As it happens at the moment, if the exception is thrown during a call to
>> the resource method, then the out filters (ResponseHandler) are not
>> called so effectively a lock will stay where it is at the moment.
>>
>> It appears things are not going to easy for you :-).
>> Few options are still available but given the fact you can not use
>> Spring and that CXF 2.3.x has been made obsolete makes it a bit tricky
>> to plan for a best approach.
>>
>> First of all, regarding that missing path parameter. I'll write a test
>> later on and fix if needed, but your custom approach to do with parsing
>> the URI looks OK.
>>
>> Now, using the custom invoker would be perfect in this case because the
>> exceptions will be caught early. But the fix I will apply to get
>> CXFNonSpringJAXRSServlet accept custom invokers won't make it to 2.3.8.
>>
>> Next is the possible workaround where your resource method makes sure
>> that no exception ever escapes it: returning Response which will have a
>> proper status code set will be the easiest way to achieve it
>>
>> Next option is to have your composite filter also implement CXF
>> OutFaultInterceptor, example:
>> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java
>>
>> and register it as jaxrs:outFaultInterceptors, however I can see
>> CXFNonSpringJAXRSServlet does only recognizes in/out interceptors but
>> not fault ones.
>>
>> So I think right now the best approach, given that you can not use
>> Spring/Blueprint, is to have the resource method which is being locked
>> ensure that no exception escapes and use the current filter implementation.
>>
>> I'll take care of fixing CXFNonSpringJaxrsServlet to recognize custom
>> invokers and fault interceptors,
that is supported with "jaxrs.invoker" and "jaxrs.outFaultInterceptors",
starting from CXF 2.4.9-SNAPSHOT
> and check why UriInfo.getPathParameters
>> does not return the parameters as expected
That actually works for me, please see the update to the test filter
from the revision history at
https://issues.apache.org/jira/browse/CXF-4413
For UriInfo.getPathParameters to return a non-empty map (either from
within the filter code or the actual resource method code), there has to
be a *matching* resource method available, with its @Path having at
least one template variable. May be there are some issues to do with
getting the path parameters from UriInfo in CXF 2.3.8, but things work
as expected in later versions
Cheers, Sergey
>>
>>> Anthony
>>>
Re: JAX-RS services - Interceptor
Posted by "Muller, Anthony" <an...@sap.com>.
Thanks for all these informations Sergey, your help is very appreciated!
Anthony
Envoyé de mon iPad
Le 5 juil. 2012 à 17:37, "Sergey Beryozkin" <sb...@gmail.com> a écrit :
> Hi Anthony
>
> Sorry for a delay
> On 05/07/12 15:50, Muller, Anthony wrote:
>> Sergey,
>>
>> More particularly, could you confirm handleRequest ans handleResponse will still be called before and after any REST calls?
>>
>> I don't like to have a lock never removed! :)
>>
> As it happens at the moment, if the exception is thrown during a call to
> the resource method, then the out filters (ResponseHandler) are not
> called so effectively a lock will stay where it is at the moment.
>
> It appears things are not going to easy for you :-).
> Few options are still available but given the fact you can not use
> Spring and that CXF 2.3.x has been made obsolete makes it a bit tricky
> to plan for a best approach.
>
> First of all, regarding that missing path parameter. I'll write a test
> later on and fix if needed, but your custom approach to do with parsing
> the URI looks OK.
>
> Now, using the custom invoker would be perfect in this case because the
> exceptions will be caught early. But the fix I will apply to get
> CXFNonSpringJAXRSServlet accept custom invokers won't make it to 2.3.8.
>
> Next is the possible workaround where your resource method makes sure
> that no exception ever escapes it: returning Response which will have a
> proper status code set will be the easiest way to achieve it
>
> Next option is to have your composite filter also implement CXF
> OutFaultInterceptor, example:
> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java
>
> and register it as jaxrs:outFaultInterceptors, however I can see
> CXFNonSpringJAXRSServlet does only recognizes in/out interceptors but
> not fault ones.
>
> So I think right now the best approach, given that you can not use
> Spring/Blueprint, is to have the resource method which is being locked
> ensure that no exception escapes and use the current filter implementation.
>
> I'll take care of fixing CXFNonSpringJaxrsServlet to recognize custom
> invokers and fault interceptors, and check why UriInfo.getPathParameters
> does not return the parameters as expected
>
> Thanks, Sergey
>
>> Anthony
>>
>>
>> -----Original Message-----
>> From: Muller, Anthony
>> Sent: jeudi 5 juillet 2012 16:23
>> To: 'Sergey Beryozkin'
>> Cc: users@cxf.apache.org
>> Subject: RE: JAX-RS services - Interceptor
>>
>> Sergey,
>>
>> What do you think about this implementation?
>>
>> Anthony
>>
>>
>> public final class BookHandler implements RequestHandler, ResponseHandler {
>>
>> private static final String KEY = "/books/";
>>
>> private static final ConcurrentMap<String, Lock> BOOK_LOCKS = new ConcurrentHashMap<String, Lock>();
>>
>> public BookHandler() {}
>>
>> @Context
>> private UriInfo uriInfo;
>>
>> @Override
>> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass)
>> {
>> final String bookId = getBookId();
>>
>> if (bookId != null) {
>> BOOK_LOCKS.putIfAbsent(bookId, new ReentrantLock());
>> BOOK_LOCKS.get(bookId).lock();
>> System.out.println("lock: " + bookId);
>> }
>>
>> return null;
>> }
>>
>> @Override
>> public Response handleResponse(final Message m, final OperationResourceInfo ori, final Response response)
>> {
>> final String bookId = getBookId();
>>
>> if(bookId != null) {
>> BOOK_LOCKS.get(bookId).unlock();
>> System.out.println("unlock: " + bookId);
>> }
>>
>> return null;
>> }
>>
>> private String getBookId() {
>> String bookId = null;
>> int startIndex = uriInfo.getPath().indexOf(KEY);
>> startIndex += KEY.length();
>> if (startIndex>= 0) {
>> final int lastIndex = uriInfo.getPath().indexOf("/", startIndex);
>> bookId = uriInfo.getPath().substring(startIndex, lastIndex);
>> }
>> return bookId;
>> }
>> }
>>
>>
>>
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>> Sent: jeudi 5 juillet 2012 14:17
>> To: Muller, Anthony
>> Cc: users@cxf.apache.org
>> Subject: Re: JAX-RS services - Interceptor
>>
>> Hi Anthony
>> On 05/07/12 12:50, Muller, Anthony wrote:
>>> Thx Sergey, that seems fine!
>>>
>>> I'm trying using UriInfo injection and I'm trying to detect the case where I must lock my resource.
>>>
>>> I hope to get the {bookId} easily, but there is nothing into path parameters... Normal?
>>>
>>> I wrote something like:
>>>
>>> @Override
>>> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass) {
>>> System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
>>>
>>> if(uriInfo.getPath().contains("/books/")) {
>>> final MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
>>> final Set<String> pathParameterNames = pathParameters.keySet();
>>> for (final String pathParameterName : pathParameterNames) {
>>> System.out.println(pathParameterName + " : " + pathParameters.getFirst(pathParameterName));
>>> }
>>> }
>>>
>>> return null;
>>> }
>>>
>>
>> I'm looking at the CXF code and I can confirm that the operation
>> matching is attempted before the filters are run. So if you have a
>> method such as
>>
>> @POST
>> @Path("{index}")
>> public void addBook(@PathParam("index") int index, Book book) {}
>>
>> and a request URI ending with something like /books/123
>>
>> then UriInfo should return an "index":123 pair
>>
>> Can you confirm please that in your above case the request URI is
>> expected to match a method with @PathParam annotations ?
>>
>> By the way, perhaps there's one option for this case.
>> Instead of doing the filters, consider creating a custom invoker which
>> gets the control immediately before and after the matched method is
>> invoked. For example:
>>
>> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java
>>
>> Custom invokers are registered using a jaxrs:invoker extension. However,
>> I recall you might be using CXFNonSpringJaxrsServlet - so is not
>> possible to register invokers from this servlet yet unless you extend
>> the servlet class and set the invoker on JAXRSServerFactoryBean. I'll
>> get this specific issue fixed,
>>
>> But using the filters should also do OK
>>
>> Sergey
>>
>>
>>>
>>>
>>> -----Original Message-----
>>> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>>> Sent: jeudi 5 juillet 2012 12:49
>>> To: users@cxf.apache.org
>>> Cc: Muller, Anthony
>>> Subject: Re: JAX-RS services - Interceptor
>>>
>>> Hi Anthony
>>> On 05/07/12 11:17, Muller, Anthony wrote:
>>>> Hello,
>>>>
>>>> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>>>>
>>>> Example of concurrent calls:
>>>> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book< 1234> must be locked to avoid concurrent modifications
>>>> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book< 1234> is currently locked
>>>>
>>>> So, I wish to add a CXF interceptor on URL starting by< /books/{bookId}/...>, but I don't see how can I do...
>>>>
>>>> (In my case, I can not use Servlet API...)
>>>>
>>>
>>> I think the simplest way is to create a class implementing both
>>> RequestHandler and ResponseHandler interfaces and have a '@Context
>>> UriInfo' injected (which is thread safe).
>>>
>>> You can use UriInfo.getPath() method to get values like
>>> 'books/1234/chapters', etc. Perhaps, even simpler, is to do
>>> RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
>>> type Message and is available as a method parameter.
>>>
>>> This implementation will 'lock' by updating the concurrent cache of some
>>> sort (Colm done few Ehcache based implementations in CXF for example) in
>>> its handleRequest method and 'unlock' in its handleResponse if it is
>>> 'books/1234/chapters'. It can be registered as a jaxrs:provider
>>>
>>>
>>>
>>> Hope that helps :-)
>>>
>>> Sergey
>>>
>>>> Can you help ?
>>>>
>>>> Thanks and regards,
>>>> Anthony
>>>>
>>>
>>
>>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com
Re: JAX-RS services - Interceptor
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Anthony
Sorry for a delay
On 05/07/12 15:50, Muller, Anthony wrote:
> Sergey,
>
> More particularly, could you confirm handleRequest ans handleResponse will still be called before and after any REST calls?
>
> I don't like to have a lock never removed! :)
>
As it happens at the moment, if the exception is thrown during a call to
the resource method, then the out filters (ResponseHandler) are not
called so effectively a lock will stay where it is at the moment.
It appears things are not going to easy for you :-).
Few options are still available but given the fact you can not use
Spring and that CXF 2.3.x has been made obsolete makes it a bit tricky
to plan for a best approach.
First of all, regarding that missing path parameter. I'll write a test
later on and fix if needed, but your custom approach to do with parsing
the URI looks OK.
Now, using the custom invoker would be perfect in this case because the
exceptions will be caught early. But the fix I will apply to get
CXFNonSpringJAXRSServlet accept custom invokers won't make it to 2.3.8.
Next is the possible workaround where your resource method makes sure
that no exception ever escapes it: returning Response which will have a
proper status code set will be the easiest way to achieve it
Next option is to have your composite filter also implement CXF
OutFaultInterceptor, example:
http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java
and register it as jaxrs:outFaultInterceptors, however I can see
CXFNonSpringJAXRSServlet does only recognizes in/out interceptors but
not fault ones.
So I think right now the best approach, given that you can not use
Spring/Blueprint, is to have the resource method which is being locked
ensure that no exception escapes and use the current filter implementation.
I'll take care of fixing CXFNonSpringJaxrsServlet to recognize custom
invokers and fault interceptors, and check why UriInfo.getPathParameters
does not return the parameters as expected
Thanks, Sergey
> Anthony
>
>
> -----Original Message-----
> From: Muller, Anthony
> Sent: jeudi 5 juillet 2012 16:23
> To: 'Sergey Beryozkin'
> Cc: users@cxf.apache.org
> Subject: RE: JAX-RS services - Interceptor
>
> Sergey,
>
> What do you think about this implementation?
>
> Anthony
>
>
> public final class BookHandler implements RequestHandler, ResponseHandler {
>
> private static final String KEY = "/books/";
>
> private static final ConcurrentMap<String, Lock> BOOK_LOCKS = new ConcurrentHashMap<String, Lock>();
>
> public BookHandler() {}
>
> @Context
> private UriInfo uriInfo;
>
> @Override
> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass)
> {
> final String bookId = getBookId();
>
> if (bookId != null) {
> BOOK_LOCKS.putIfAbsent(bookId, new ReentrantLock());
> BOOK_LOCKS.get(bookId).lock();
> System.out.println("lock: " + bookId);
> }
>
> return null;
> }
>
> @Override
> public Response handleResponse(final Message m, final OperationResourceInfo ori, final Response response)
> {
> final String bookId = getBookId();
>
> if(bookId != null) {
> BOOK_LOCKS.get(bookId).unlock();
> System.out.println("unlock: " + bookId);
> }
>
> return null;
> }
>
> private String getBookId() {
> String bookId = null;
> int startIndex = uriInfo.getPath().indexOf(KEY);
> startIndex += KEY.length();
> if (startIndex>= 0) {
> final int lastIndex = uriInfo.getPath().indexOf("/", startIndex);
> bookId = uriInfo.getPath().substring(startIndex, lastIndex);
> }
> return bookId;
> }
> }
>
>
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: jeudi 5 juillet 2012 14:17
> To: Muller, Anthony
> Cc: users@cxf.apache.org
> Subject: Re: JAX-RS services - Interceptor
>
> Hi Anthony
> On 05/07/12 12:50, Muller, Anthony wrote:
>> Thx Sergey, that seems fine!
>>
>> I'm trying using UriInfo injection and I'm trying to detect the case where I must lock my resource.
>>
>> I hope to get the {bookId} easily, but there is nothing into path parameters... Normal?
>>
>> I wrote something like:
>>
>> @Override
>> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass) {
>> System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
>>
>> if(uriInfo.getPath().contains("/books/")) {
>> final MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
>> final Set<String> pathParameterNames = pathParameters.keySet();
>> for (final String pathParameterName : pathParameterNames) {
>> System.out.println(pathParameterName + " : " + pathParameters.getFirst(pathParameterName));
>> }
>> }
>>
>> return null;
>> }
>>
>
> I'm looking at the CXF code and I can confirm that the operation
> matching is attempted before the filters are run. So if you have a
> method such as
>
> @POST
> @Path("{index}")
> public void addBook(@PathParam("index") int index, Book book) {}
>
> and a request URI ending with something like /books/123
>
> then UriInfo should return an "index":123 pair
>
> Can you confirm please that in your above case the request URI is
> expected to match a method with @PathParam annotations ?
>
> By the way, perhaps there's one option for this case.
> Instead of doing the filters, consider creating a custom invoker which
> gets the control immediately before and after the matched method is
> invoked. For example:
>
> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java
>
> Custom invokers are registered using a jaxrs:invoker extension. However,
> I recall you might be using CXFNonSpringJaxrsServlet - so is not
> possible to register invokers from this servlet yet unless you extend
> the servlet class and set the invoker on JAXRSServerFactoryBean. I'll
> get this specific issue fixed,
>
> But using the filters should also do OK
>
> Sergey
>
>
>>
>>
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>> Sent: jeudi 5 juillet 2012 12:49
>> To: users@cxf.apache.org
>> Cc: Muller, Anthony
>> Subject: Re: JAX-RS services - Interceptor
>>
>> Hi Anthony
>> On 05/07/12 11:17, Muller, Anthony wrote:
>>> Hello,
>>>
>>> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>>>
>>> Example of concurrent calls:
>>> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book< 1234> must be locked to avoid concurrent modifications
>>> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book< 1234> is currently locked
>>>
>>> So, I wish to add a CXF interceptor on URL starting by< /books/{bookId}/...>, but I don't see how can I do...
>>>
>>> (In my case, I can not use Servlet API...)
>>>
>>
>> I think the simplest way is to create a class implementing both
>> RequestHandler and ResponseHandler interfaces and have a '@Context
>> UriInfo' injected (which is thread safe).
>>
>> You can use UriInfo.getPath() method to get values like
>> 'books/1234/chapters', etc. Perhaps, even simpler, is to do
>> RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
>> type Message and is available as a method parameter.
>>
>> This implementation will 'lock' by updating the concurrent cache of some
>> sort (Colm done few Ehcache based implementations in CXF for example) in
>> its handleRequest method and 'unlock' in its handleResponse if it is
>> 'books/1234/chapters'. It can be registered as a jaxrs:provider
>>
>>
>>
>> Hope that helps :-)
>>
>> Sergey
>>
>>> Can you help ?
>>>
>>> Thanks and regards,
>>> Anthony
>>>
>>
>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
RE: JAX-RS services - Interceptor
Posted by "Muller, Anthony" <an...@sap.com>.
Sergey,
More particularly, could you confirm handleRequest ans handleResponse will still be called before and after any REST calls?
I don't like to have a lock never removed! :)
Anthony
-----Original Message-----
From: Muller, Anthony
Sent: jeudi 5 juillet 2012 16:23
To: 'Sergey Beryozkin'
Cc: users@cxf.apache.org
Subject: RE: JAX-RS services - Interceptor
Sergey,
What do you think about this implementation?
Anthony
public final class BookHandler implements RequestHandler, ResponseHandler {
private static final String KEY = "/books/";
private static final ConcurrentMap<String, Lock> BOOK_LOCKS = new ConcurrentHashMap<String, Lock>();
public BookHandler() {}
@Context
private UriInfo uriInfo;
@Override
public Response handleRequest(final Message m, final ClassResourceInfo resourceClass)
{
final String bookId = getBookId();
if (bookId != null) {
BOOK_LOCKS.putIfAbsent(bookId, new ReentrantLock());
BOOK_LOCKS.get(bookId).lock();
System.out.println("lock: " + bookId);
}
return null;
}
@Override
public Response handleResponse(final Message m, final OperationResourceInfo ori, final Response response)
{
final String bookId = getBookId();
if(bookId != null) {
BOOK_LOCKS.get(bookId).unlock();
System.out.println("unlock: " + bookId);
}
return null;
}
private String getBookId() {
String bookId = null;
int startIndex = uriInfo.getPath().indexOf(KEY);
startIndex += KEY.length();
if (startIndex >= 0) {
final int lastIndex = uriInfo.getPath().indexOf("/", startIndex);
bookId = uriInfo.getPath().substring(startIndex, lastIndex);
}
return bookId;
}
}
-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
Sent: jeudi 5 juillet 2012 14:17
To: Muller, Anthony
Cc: users@cxf.apache.org
Subject: Re: JAX-RS services - Interceptor
Hi Anthony
On 05/07/12 12:50, Muller, Anthony wrote:
> Thx Sergey, that seems fine!
>
> I'm trying using UriInfo injection and I'm trying to detect the case where I must lock my resource.
>
> I hope to get the {bookId} easily, but there is nothing into path parameters... Normal?
>
> I wrote something like:
>
> @Override
> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass) {
> System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
>
> if(uriInfo.getPath().contains("/books/")) {
> final MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
> final Set<String> pathParameterNames = pathParameters.keySet();
> for (final String pathParameterName : pathParameterNames) {
> System.out.println(pathParameterName + " : " + pathParameters.getFirst(pathParameterName));
> }
> }
>
> return null;
> }
>
I'm looking at the CXF code and I can confirm that the operation
matching is attempted before the filters are run. So if you have a
method such as
@POST
@Path("{index}")
public void addBook(@PathParam("index") int index, Book book) {}
and a request URI ending with something like /books/123
then UriInfo should return an "index":123 pair
Can you confirm please that in your above case the request URI is
expected to match a method with @PathParam annotations ?
By the way, perhaps there's one option for this case.
Instead of doing the filters, consider creating a custom invoker which
gets the control immediately before and after the matched method is
invoked. For example:
http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java
Custom invokers are registered using a jaxrs:invoker extension. However,
I recall you might be using CXFNonSpringJaxrsServlet - so is not
possible to register invokers from this servlet yet unless you extend
the servlet class and set the invoker on JAXRSServerFactoryBean. I'll
get this specific issue fixed,
But using the filters should also do OK
Sergey
>
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: jeudi 5 juillet 2012 12:49
> To: users@cxf.apache.org
> Cc: Muller, Anthony
> Subject: Re: JAX-RS services - Interceptor
>
> Hi Anthony
> On 05/07/12 11:17, Muller, Anthony wrote:
>> Hello,
>>
>> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>>
>> Example of concurrent calls:
>> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book< 1234> must be locked to avoid concurrent modifications
>> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book< 1234> is currently locked
>>
>> So, I wish to add a CXF interceptor on URL starting by< /books/{bookId}/...>, but I don't see how can I do...
>>
>> (In my case, I can not use Servlet API...)
>>
>
> I think the simplest way is to create a class implementing both
> RequestHandler and ResponseHandler interfaces and have a '@Context
> UriInfo' injected (which is thread safe).
>
> You can use UriInfo.getPath() method to get values like
> 'books/1234/chapters', etc. Perhaps, even simpler, is to do
> RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
> type Message and is available as a method parameter.
>
> This implementation will 'lock' by updating the concurrent cache of some
> sort (Colm done few Ehcache based implementations in CXF for example) in
> its handleRequest method and 'unlock' in its handleResponse if it is
> 'books/1234/chapters'. It can be registered as a jaxrs:provider
>
>
>
> Hope that helps :-)
>
> Sergey
>
>> Can you help ?
>>
>> Thanks and regards,
>> Anthony
>>
>
RE: JAX-RS services - Interceptor
Posted by "Muller, Anthony" <an...@sap.com>.
Sergey,
What do you think about this implementation?
Anthony
public final class BookHandler implements RequestHandler, ResponseHandler {
private static final String KEY = "/books/";
private static final ConcurrentMap<String, Lock> BOOK_LOCKS = new ConcurrentHashMap<String, Lock>();
public BookHandler() {}
@Context
private UriInfo uriInfo;
@Override
public Response handleRequest(final Message m, final ClassResourceInfo resourceClass)
{
final String bookId = getBookId();
if (bookId != null) {
BOOK_LOCKS.putIfAbsent(bookId, new ReentrantLock());
BOOK_LOCKS.get(bookId).lock();
System.out.println("lock: " + bookId);
}
return null;
}
@Override
public Response handleResponse(final Message m, final OperationResourceInfo ori, final Response response)
{
final String bookId = getBookId();
if(bookId != null) {
BOOK_LOCKS.get(bookId).unlock();
System.out.println("unlock: " + bookId);
}
return null;
}
private String getBookId() {
String bookId = null;
int startIndex = uriInfo.getPath().indexOf(KEY);
startIndex += KEY.length();
if (startIndex >= 0) {
final int lastIndex = uriInfo.getPath().indexOf("/", startIndex);
bookId = uriInfo.getPath().substring(startIndex, lastIndex);
}
return bookId;
}
}
-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
Sent: jeudi 5 juillet 2012 14:17
To: Muller, Anthony
Cc: users@cxf.apache.org
Subject: Re: JAX-RS services - Interceptor
Hi Anthony
On 05/07/12 12:50, Muller, Anthony wrote:
> Thx Sergey, that seems fine!
>
> I'm trying using UriInfo injection and I'm trying to detect the case where I must lock my resource.
>
> I hope to get the {bookId} easily, but there is nothing into path parameters... Normal?
>
> I wrote something like:
>
> @Override
> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass) {
> System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
>
> if(uriInfo.getPath().contains("/books/")) {
> final MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
> final Set<String> pathParameterNames = pathParameters.keySet();
> for (final String pathParameterName : pathParameterNames) {
> System.out.println(pathParameterName + " : " + pathParameters.getFirst(pathParameterName));
> }
> }
>
> return null;
> }
>
I'm looking at the CXF code and I can confirm that the operation
matching is attempted before the filters are run. So if you have a
method such as
@POST
@Path("{index}")
public void addBook(@PathParam("index") int index, Book book) {}
and a request URI ending with something like /books/123
then UriInfo should return an "index":123 pair
Can you confirm please that in your above case the request URI is
expected to match a method with @PathParam annotations ?
By the way, perhaps there's one option for this case.
Instead of doing the filters, consider creating a custom invoker which
gets the control immediately before and after the matched method is
invoked. For example:
http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java
Custom invokers are registered using a jaxrs:invoker extension. However,
I recall you might be using CXFNonSpringJaxrsServlet - so is not
possible to register invokers from this servlet yet unless you extend
the servlet class and set the invoker on JAXRSServerFactoryBean. I'll
get this specific issue fixed,
But using the filters should also do OK
Sergey
>
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: jeudi 5 juillet 2012 12:49
> To: users@cxf.apache.org
> Cc: Muller, Anthony
> Subject: Re: JAX-RS services - Interceptor
>
> Hi Anthony
> On 05/07/12 11:17, Muller, Anthony wrote:
>> Hello,
>>
>> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>>
>> Example of concurrent calls:
>> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book< 1234> must be locked to avoid concurrent modifications
>> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book< 1234> is currently locked
>>
>> So, I wish to add a CXF interceptor on URL starting by< /books/{bookId}/...>, but I don't see how can I do...
>>
>> (In my case, I can not use Servlet API...)
>>
>
> I think the simplest way is to create a class implementing both
> RequestHandler and ResponseHandler interfaces and have a '@Context
> UriInfo' injected (which is thread safe).
>
> You can use UriInfo.getPath() method to get values like
> 'books/1234/chapters', etc. Perhaps, even simpler, is to do
> RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
> type Message and is available as a method parameter.
>
> This implementation will 'lock' by updating the concurrent cache of some
> sort (Colm done few Ehcache based implementations in CXF for example) in
> its handleRequest method and 'unlock' in its handleResponse if it is
> 'books/1234/chapters'. It can be registered as a jaxrs:provider
>
>
>
> Hope that helps :-)
>
> Sergey
>
>> Can you help ?
>>
>> Thanks and regards,
>> Anthony
>>
>
Re: JAX-RS services - Interceptor
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Anthony
On 05/07/12 12:50, Muller, Anthony wrote:
> Thx Sergey, that seems fine!
>
> I'm trying using UriInfo injection and I'm trying to detect the case where I must lock my resource.
>
> I hope to get the {bookId} easily, but there is nothing into path parameters... Normal?
>
> I wrote something like:
>
> @Override
> public Response handleRequest(final Message m, final ClassResourceInfo resourceClass) {
> System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
>
> if(uriInfo.getPath().contains("/books/")) {
> final MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
> final Set<String> pathParameterNames = pathParameters.keySet();
> for (final String pathParameterName : pathParameterNames) {
> System.out.println(pathParameterName + " : " + pathParameters.getFirst(pathParameterName));
> }
> }
>
> return null;
> }
>
I'm looking at the CXF code and I can confirm that the operation
matching is attempted before the filters are run. So if you have a
method such as
@POST
@Path("{index}")
public void addBook(@PathParam("index") int index, Book book) {}
and a request URI ending with something like /books/123
then UriInfo should return an "index":123 pair
Can you confirm please that in your above case the request URI is
expected to match a method with @PathParam annotations ?
By the way, perhaps there's one option for this case.
Instead of doing the filters, consider creating a custom invoker which
gets the control immediately before and after the matched method is
invoked. For example:
http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java
Custom invokers are registered using a jaxrs:invoker extension. However,
I recall you might be using CXFNonSpringJaxrsServlet - so is not
possible to register invokers from this servlet yet unless you extend
the servlet class and set the invoker on JAXRSServerFactoryBean. I'll
get this specific issue fixed,
But using the filters should also do OK
Sergey
>
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: jeudi 5 juillet 2012 12:49
> To: users@cxf.apache.org
> Cc: Muller, Anthony
> Subject: Re: JAX-RS services - Interceptor
>
> Hi Anthony
> On 05/07/12 11:17, Muller, Anthony wrote:
>> Hello,
>>
>> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>>
>> Example of concurrent calls:
>> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book< 1234> must be locked to avoid concurrent modifications
>> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book< 1234> is currently locked
>>
>> So, I wish to add a CXF interceptor on URL starting by< /books/{bookId}/...>, but I don't see how can I do...
>>
>> (In my case, I can not use Servlet API...)
>>
>
> I think the simplest way is to create a class implementing both
> RequestHandler and ResponseHandler interfaces and have a '@Context
> UriInfo' injected (which is thread safe).
>
> You can use UriInfo.getPath() method to get values like
> 'books/1234/chapters', etc. Perhaps, even simpler, is to do
> RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
> type Message and is available as a method parameter.
>
> This implementation will 'lock' by updating the concurrent cache of some
> sort (Colm done few Ehcache based implementations in CXF for example) in
> its handleRequest method and 'unlock' in its handleResponse if it is
> 'books/1234/chapters'. It can be registered as a jaxrs:provider
>
>
>
> Hope that helps :-)
>
> Sergey
>
>> Can you help ?
>>
>> Thanks and regards,
>> Anthony
>>
>
RE: JAX-RS services - Interceptor
Posted by "Muller, Anthony" <an...@sap.com>.
Thx Sergey, that seems fine!
I'm trying using UriInfo injection and I'm trying to detect the case where I must lock my resource.
I hope to get the {bookId} easily, but there is nothing into path parameters... Normal?
I wrote something like:
@Override
public Response handleRequest(final Message m, final ClassResourceInfo resourceClass) {
System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
if(uriInfo.getPath().contains("/books/")) {
final MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
final Set<String> pathParameterNames = pathParameters.keySet();
for (final String pathParameterName : pathParameterNames) {
System.out.println(pathParameterName + " : " + pathParameters.getFirst(pathParameterName));
}
}
return null;
}
-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
Sent: jeudi 5 juillet 2012 12:49
To: users@cxf.apache.org
Cc: Muller, Anthony
Subject: Re: JAX-RS services - Interceptor
Hi Anthony
On 05/07/12 11:17, Muller, Anthony wrote:
> Hello,
>
> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>
> Example of concurrent calls:
> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book < 1234 > must be locked to avoid concurrent modifications
> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book < 1234 > is currently locked
>
> So, I wish to add a CXF interceptor on URL starting by < /books/{bookId}/... >, but I don't see how can I do...
>
> (In my case, I can not use Servlet API...)
>
I think the simplest way is to create a class implementing both
RequestHandler and ResponseHandler interfaces and have a '@Context
UriInfo' injected (which is thread safe).
You can use UriInfo.getPath() method to get values like
'books/1234/chapters', etc. Perhaps, even simpler, is to do
RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
type Message and is available as a method parameter.
This implementation will 'lock' by updating the concurrent cache of some
sort (Colm done few Ehcache based implementations in CXF for example) in
its handleRequest method and 'unlock' in its handleResponse if it is
'books/1234/chapters'. It can be registered as a jaxrs:provider
Hope that helps :-)
Sergey
> Can you help ?
>
> Thanks and regards,
> Anthony
>
Re: JAX-RS services - Interceptor
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Anthony
On 05/07/12 11:17, Muller, Anthony wrote:
> Hello,
>
> I have a use case when I need to intercept some REST calls to lock a used resource (underlying code doesn't support concurrent access). I wish to use an CXF interceptor to implement the lock mechanism (something else can help ?)
>
> Example of concurrent calls:
> Client 1 : [POST]<baseurl>/books/1234/chapters/ --> Book « 1234 » must be locked to avoid concurrent modifications
> Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph --> Webservice must wait because book « 1234 » is currently locked
>
> So, I wish to add a CXF interceptor on URL starting by « /books/{bookId}/... », but I don't see how can I do...
>
> (In my case, I can not use Servlet API...)
>
I think the simplest way is to create a class implementing both
RequestHandler and ResponseHandler interfaces and have a '@Context
UriInfo' injected (which is thread safe).
You can use UriInfo.getPath() method to get values like
'books/1234/chapters', etc. Perhaps, even simpler, is to do
RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
type Message and is available as a method parameter.
This implementation will 'lock' by updating the concurrent cache of some
sort (Colm done few Ehcache based implementations in CXF for example) in
its handleRequest method and 'unlock' in its handleResponse if it is
'books/1234/chapters'. It can be registered as a jaxrs:provider
Hope that helps :-)
Sergey
> Can you help ?
>
> Thanks and regards,
> Anthony
>