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

Cheers, Sergey


Thanks again for identifying my problem!

-Tom


On Tue, Jul 30, 2013 at 3:40 AM, Sergey Beryozkin <[email protected]
<mailto:[email protected]>> 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



Reply via email to