cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: JAX-RS services - Interceptor
Date Thu, 05 Jul 2012 15:37:07 GMT
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

Mime
View raw message