Thanks for all these informations Sergey, your help is very appreciated! Anthony
Envoyé de mon iPad Le 5 juil. 2012 à 17:37, "Sergey Beryozkin" <[email protected]> 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: [email protected] >> 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:[email protected]] >> Sent: jeudi 5 juillet 2012 14:17 >> To: Muller, Anthony >> Cc: [email protected] >> 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:[email protected]] >>> Sent: jeudi 5 juillet 2012 12:49 >>> To: [email protected] >>> 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
