You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Sergey Beryozkin <sb...@gmail.com> on 2013/08/02 14:02:03 UTC

Re: CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

On 30/07/13 17:01, Sergey Beryozkin wrote:
> On 30/07/13 16:51, Tom Hartwell wrote:
>> Thanks so much Sergey, that did the trick. While I'm happy that my test
>> now works, I feel like this violates the Principle of Least Surprise in
>> setting up a Client in this way. Is there any compelling reason to not
>> set this property normally?
> Hmm, good point. Local transport module has been created long before we
> started supporting RS communications and with WS a request payload is
> available in most cases so I guess I worked just fine with the
> piped-style approach.
> I'll start a dev thread, seems like using a direct dispatch style by
> default can simplify things a bit so I'll update the code unless there
> are known reasons for not doing it

FYI, Dan has fixed it such that requests with empty payloads will work 
with or without this property being set up.

Cheers, Sergey

>
>>
>> Thanks again for identifying my problem!
>>
>> -Tom
>>
>>
>> On Tue, Jul 30, 2013 at 3:40 AM, Sergey Beryozkin <sberyozkin@gmail.com
>> <ma...@gmail.com>> wrote:
>>
>>     Actually the wiki mentions that property so I won't update it.
>>     But, at the moment, you can't set that property in jaxrs:client
>>     because LocalConduit does not check for message contextual
>>     properties, I've just got it fixed but in meantime please set the
>>     property from the code
>>
>>     Cheers, Sergey
>>
>>     On 30/07/13 10:52, Sergey Beryozkin wrote:
>>
>>         Hi
>>
>>         I've spotted you use a local transport. Yes, it is a test setup
>>         issue.
>>         Specifically, you use 'piped' local transport which as far as I
>>         recall
>>         assumes a payload is available and in case of GET/DELETE it is
>>         not so
>>         you have the code hanging.
>>         Add this property to your proxy (in
>>         jaxrs:client/jaxrs:properties)__:
>>         "org.apache.cxf.transport.__local.LocalConduit.__directDispatch"
>>         : true
>>
>>         I can see that LocalTransport handler uses Boolean.TRUE to
>>         compare, so
>>         that property value needs to be a proper boolean.
>>         Will do a minor update so that users can use String "true"...
>>
>>         Or you can set that property directly from the code,
>>
>>
>> WebClient.getConfig(__myServiceInterface).__getRequestContext().put(__LocalConduit.DIRECT_DISPATCH,
>>
>>         Boolean.TRUE);
>>
>>         I'll update the docs re the need to use this property with
>> requests
>>         having no payloads when Local transport is used.
>>
>>         Cheers, Sergey
>>
>>         On 30/07/13 00:30, Tom Hartwell wrote:
>>
>>             I'm using CXF 2.6.6 and have not found an open issue
>>             regarding the
>>             problem
>>             I'm seeing so I'm thinking it may be misconfiguration on my
>>             part.
>>
>>             I'm trying to use a CXF client in my application where I
>>             have my app
>>             wired
>>             via Spring in XML:
>>
>>             test-context.xml
>>
>>             <beans
>>             xmlns="http://www.__springframework.org/schema/__beans
>>             <http://www.springframework.org/schema/beans>"
>>                   xmlns:xsi="http://www.w3.org/__2001/XMLSchema-instance
>>             <http://www.w3.org/2001/XMLSchema-instance>" xmlns:jaxrs="
>>             http://cxf.apache.org/jaxrs"
>>                   xsi:schemaLocation="
>>             http://www.springframework.__org/schema/beans
>>             <http://www.springframework.org/schema/beans>
>>
>> http://www.springframework.__org/schema/beans/spring-beans-__2.0.xsd
>>
>> <http://www.springframework.org/schema/beans/spring-beans-2.0.xsd>
>>             http://cxf.apache.org/jaxrs
>>             http://cxf.apache.org/schemas/__jaxrs.xsd
>>             <http://cxf.apache.org/schemas/jaxrs.xsd>
>>             ">
>>
>>
>>                   <bean id="dataSource"
>>             class="org.apache.commons.__dbcp.BasicDataSource"
>>                       destroy-method="close">
>>                       <property />
>>                       .....
>>                   </bean>
>>
>>                   <bean id="myService" class="com.MyService">
>>                       <property name="dataSource" ref="dataSource" />
>>                       <property name="queries">
>>                           <map>
>>                               <entry key="SAVE">
>>                                   <value>INSERT INTO ....</value>
>>                               </entry>
>>                               <entry key="UPDATE">
>>                                   <value>UPDATE ...</value>
>>                               </entry>
>>                               <entry key="GET">
>>                                   <value>SELECT ...</value>
>>                               </entry>
>>                               <entry key="DELETE">
>>                                   <value>DELETE from ...</value>
>>                               </entry>
>>                           </map>
>>                       </property>
>>                   </bean>
>>
>>                   <import resource="classpath:META-INF/__cxf/cxf.xml" />
>>                   <import
>>             resource="classpath:META-INF/__cxf/cxf-servlet.xml" />
>>
>>                   <bean id="jacksonMapper"
>>             class="com.fasterxml.jackson.__databind.ObjectMapper" />
>>
>>                   <jaxrs:server id="myServer"
>>             address="local://localservice/__">
>>                       <jaxrs:serviceBeans>
>>                           <ref bean="myService" />
>>                       </jaxrs:serviceBeans>
>>                       <jaxrs:providers>
>>                           <bean
>>
>> class="com.fasterxml.jackson.__jaxrs.json.__JacksonJsonProvider">
>>                               <property name="mapper"
>> ref="jacksonMapper" />
>>                           </bean>
>>                       </jaxrs:providers>
>>                   </jaxrs:server>
>>
>>
>>                   <jaxrs:client id="myClient"
>>             address="local://localservice/__"
>>                       serviceClass="com.__MyServiceInterface"
>>                       inheritHeaders="true">
>>                       <jaxrs:headers>
>>                           <entry key="Accept" value="application/json" />
>>                           <entry key="ContentType"
>>             value="application/json" />
>>                       </jaxrs:headers>
>>                       <jaxrs:providers>
>>                           <bean
>>
>> class="com.fasterxml.jackson.__jaxrs.json.__JacksonJaxbJsonProvider">
>>                               <property name="mapper"
>> ref="jacksonMapper" />
>>                           </bean>
>>                       </jaxrs:providers>
>>                   </jaxrs:client>
>>             </beans>
>>
>>             And my Jax-RS interface is as follows:
>>
>>             @Path("/")
>>             public interface MyServiceInterface {
>>
>>                   @GET
>>                   @Path("/{id}")
>>                   @Produces("application/json")
>>                   MyObject retreiveMyObject(@PathParam("__id") int id);
>>
>>                   @POST
>>                   @Path("/")
>>                   @Consumes("application/json")
>>                   @Produces("application/json")
>>                   Integer saveMyObject(MyObject myObject);
>>
>>                   @PUT
>>                   @Path("/{id}")
>>                   @Consumes("application/json")
>>                   @Produces("application/json")
>>                   Integer updateMyObject(@PathParam("id"__) int id,
>>             MyObject myObject);
>>
>>                   @DELETE
>>                   @Path("/{id}")
>>                   @Produces("application/json")
>>                   Integer deleteMyObject(@PathParam("id"__) int id);
>>             }
>>
>>             public class MyService implements MyServiceInterface {
>>             ...
>>             }
>>
>>             And the test
>>
>>             @RunWith(__SpringJUnit4ClassRunner.class)
>>             @ContextConfiguration(__locations={"test-context.xml"}__)
>>             public class MyServiceTest extends Assert implements
>>             ApplicationContextAware {
>>
>>                   private final Logger logger =
>>             LoggerFactory.getLogger(__MyServiceTest
>>             .class);
>>
>>                   ApplicationContext ctx;
>>                   @Override
>>                   public void setApplicationContext(__ApplicationContext
>>             context) throws
>>             BeansException {
>>                       this.ctx = context;
>>                   }
>>
>>                   @Autowired
>>                   @Qualifier("myClient")
>>                   public MyServiceInterface myServiceInterface;
>>
>>                   @Test
>>                   public void testCrud() {
>>                       MyObject myObject = new
>>             MyObject().setAttr1("127.0.0.__1").setAttr2(new Date());
>>
>>                       // THIS WORKS THROUGH THE CLIENT
>>
>>
>> myObject.setId(__myServiceInterface.__saveMyObject(myObject));
>>
>>                       // THIS WORKS THROUGH THE CLIENT TOO
>>
>>               myServiceInterface.__updateMyObject(myObject.getId(__),
>>             myObject
>>             .setX(1.23f).setY(4.56f));
>>
>>                       // THIS DOES NOT HANG!!
>>
>>
>> ((MyServiceInterface)ctx.__getBean("myService")).__deleteMyObject(1);
>>
>>
>>                       // THIS HANGS
>>                       logger.debug("BEGIN THE RETRIEVAL");
>>                       MyObject persistedMyObject =
>>             myServiceInterface.__retrieveMyObject(
>>             myObject.getId());
>>                       assertEquals(1.23f, persistedMyObject.getX(),
>> 0.05);
>>                       assertEquals(4.56f, persistedMyObject.getY(),
>> 0.05);
>>
>>                       // THIS HANGS TOO??
>>
>>               myServiceInterface.__deleteMyObject(roomAlarm.__getId());
>>                       MyObject deletedMyObject =
>>             myServiceInterface.__retrieveMyObject(
>>             persistedMyObject.getId());
>>
>>                       assertNull(deletedMyObject);
>>                   }
>>             }
>>
>>             The log reads:
>>             1728 [main] DEBUG com.MyObjectTest  - *BEGIN THE RETRIEVAL*
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>             org.apache.cxf.ws.policy.__PolicyOutInterceptor@55e29b99 to
>>             phase
>>             setup
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>>             to
>>             phase prepare-send
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>>             to
>>             phase prepare-send
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Chain
>>             org.apache.cxf.phase.__PhaseInterceptorChain@7691a4fb was
>>             created. Current
>>             flow:
>>                 setup [PolicyOutInterceptor]
>>                 prepare-send [MessageSenderInterceptor]
>>
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>>             handleMessage on interceptor
>>             org.apache.cxf.ws.policy.__PolicyOutInterceptor@55e29b99
>>             1729 [main] DEBUG
>>             org.apache.cxf.ws.policy.__PolicyOutInterceptor  - No
>>             binding operation info.
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>>             handleMessage on interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor$__MessageSenderEndingInterceptor__@68d36ff3to
>>
>>
>>             phase prepare-send-ending
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Chain
>>             org.apache.cxf.phase.__PhaseInterceptorChain@7691a4fb was
>>             modified. Current
>>             flow:
>>                 setup [PolicyOutInterceptor]
>>                 prepare-send [MessageSenderInterceptor]
>>                 prepare-send-ending [__MessageSenderEndingInterceptor__]
>>
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>>             handleMessage on interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor$__MessageSenderEndingInterceptor__@68d36ff3
>>
>>
>>
>>             The save and update work just fine, and the retrieve and
>>             delete don't.
>>             If I
>>             call the service class directly I can retrieve and delete
>>             just fine, so I
>>             have a feeling it has to do with my configuration, but I've
>>             tried a
>>             ton of
>>             different things to no avail.
>>
>>             Thanks in advance,
>>             Tom
>>
>>
>>
>>
>>
>>     --
>>     Sergey Beryozkin
>>
>>     Talend Community Coders
>>     http://coders.talend.com/
>>
>>     Blog: http://sberyozkin.blogspot.com
>>
>>
>