Thanks Daniel,
That fixes the concurrent access but In my understanding and tests it does
not allow setting a different timeout depending on method, right ?
Maybe I am not clear enought, here is the call sequence I have where I want
a timeout of 3 secondes for getCustomersByName and default one for
getCustomersById:

CustomerService service = getService();
        long t = System.currentTimeMillis();
        System.out.println("Start time-->" + t);
        try {
            HTTPClientPolicy policy = new HTTPClientPolicy();
            policy.setReceiveTimeout(3000);

((BindingProvider)service).getRequestContext().put("thread.local.request.context",
"true");

((BindingProvider)service).getRequestContext().put(HTTPClientPolicy.class.getName(),
policy);
// Dirty code for demo
            System.out.println(service.getCustomersByName("timeout"));
        } catch (Exception e) {
// Dirty code for demo
            e.printStackTrace();
        }
        org.apache.cxf.endpoint.Client client =
ClientProxy.getClient(service);
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
// Dirty code for demo
        System.out.println(conduit);

        service = getService();
//  THIS ONE IS IMPACTED BY PREVIOUS SETTING AS IT'S IN SAME THREAD
        service.getCustomerById("timeout");

Thanks

On Mon, May 6, 2013 at 6:32 PM, Daniel Kulp <dk...@apache.org> wrote:

>
> On May 6, 2013, at 10:48 AM, Philippe Mouawad <pmoua...@apache.org> wrote:
>
> > Hello Daniel
> >
> > Many thanks for clarifications but what I don't understand is how this
> one
> > would not impact other methods of Webservice.
> > - ((BindingProvider)proxy)
> > getRequestContext().put(HTTPClientPolicy.class.getName(), policy);
> > I made a little test and it seems the second operation getCustomerById is
> > impacted, which seems to me regular as the service is a Spring Bean. Am I
> > missing something ?
>
> Oh.. forgot to mention you would have to flip the request context over to
> be threadsafe/threadlocal first:
>
> From:
> http://cxf.apache.org/faq.html#FAQ-AreJAXWSclientproxiesthreadsafe%3F
>
> ((BindingProvider)proxy).getRequestContext().put("thread.local.request.context",
> "true");
>
> that would then start using a thread local for the context which would
> keep the operations separate.
>
> Dan
>
>
>
>
> >
> > Regards
> > Philippe
> >
> >>
> >> On Mon, May 6, 2013 at 4:09 PM, Daniel Kulp <dk...@apache.org> wrote:
> >>
> >>>
> >>> On May 6, 2013, at 10:06 AM, Philippe Mouawad <pmoua...@apache.org>
> >>> wrote:
> >>>
> >>> Many Thanks Daniel for your clarification.
> >>> And what about the described ways, are they OK to you ?
> >>>
> >>>
> >>> 1&2 is correct.   It would work outside of spring, but would not be
> >>> thread safe.   A pool of client would work though.
> >>>
> >> Great
> >>
> >>>
> >>> 3:  I don't think the interceptor setting the Message.RECEIVE_TIMEOUT
> >>> will work as I don't think that affects the HTTP level timeout, just
> the
> >>> timeout used for the async calls.  I could be wrong though.
> >>>
> >>> It works I tested it and debugged to be sure it does. It follows one of
> >> your explanations ;-) :
> >>
> >>   -
> >>
> http://cxf.547215.n5.nabble.com/Setting-Http-conduit-using-spring-configuration-file-td2644363.html
> >>
> >> I changed it to be this to only affect one operation:
> >>
> >>    @Override
> >>    public void handleMessage(Message message) throws Fault {
> >>        if("{
> >> http://customerservice.example.com/}CustomerServiceServiceSoapBinding
> >> ".equals(
> >>
> >>
> message.getExchange().getBindingOperationInfo().getBinding().getName().toString())
> >> &&
> >>                "{http://customerservice.example.com/}getCustomersByName
> >>
> ".equals(message.getExchange().getBindingOperationInfo().getOperationInfo().getName().toString())
> >>                ) {
> >>
> >>            message.put(Message.RECEIVE_TIMEOUT,
> >> getReceiveTimeout());
> >>        }
> >>    }
> >>
> >>
> >>
> >>> 4:  As you mention, it's an open bug.  Likely should work, but not
> >>> implemented yet.
> >>>
> >>> Great
> >>
> >>>
> >>> Dan
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> Thanks
> >>> Regards
> >>> Philippe
> >>>
> >>> On Mon, May 6, 2013 at 3:57 PM, Daniel Kulp <dk...@apache.org> wrote:
> >>>
> >>>>
> >>>> I think the only way to do it right now is to create a specific
> >>>> HTTPClientPolicy object for your operation and do something like;
> >>>>
> >>>>
> ((BindingProvider)proxy).getRequestContext().put(HTTPClientPolicy.class.getName(),
> >>>> policy);
> >>>>
> >>>> The conduit should pick that up and intersect it with anything
> >>>> configured at the conduit level and then use that.   That should at
> least
> >>>> work with 2.7.x.
> >>>>
> >>>>
> >>>> Dan
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> On May 3, 2013, at 3:57 AM, Philippe Mouawad <pmoua...@apache.org>
> >>>> wrote:
> >>>>
> >>>>> Hello,
> >>>>>
> >>>>> I am working on the right way to configure Client Timeout on client
> >>>> side
> >>>>> and I am kind of confused by what I read:
> >>>>>
> >>>>>  -
> >>>>>
> >>>>
> http://cxf.547215.n5.nabble.com/Setting-Http-conduit-using-spring-configuration-file-td2644363.html
> >>>>>  - https://issues.apache.org/jira/browse/CXF-3011
> >>>>>  -
> >>>>>
> >>>>
> http://stackoverflow.com/questions/3012787/connection-details-timeouts-in-a-java-web-service-client
> >>>>>  -
> >>>>>
> >>>>
> http://stackoverflow.com/questions/3130913/setting-jax-ws-client-timeout/6700210#6700210
> >>>>>  -
> >>>>>
> >>>>
> http://stackoverflow.com/questions/2148915/how-do-i-set-the-timeout-for-a-jax-ws-webservice-client/6700216#6700216
> >>>>>
> >>>>>
> >>>>> So the things that work:
> >>>>>
> >>>>>
> >>>>> 1) Outside of Spring, this one works fine:
> >>>>>
> >>>>> CustomerServiceService customerService = new
> CustomerServiceService(new
> >>>>> URL("http://localhost:8080/pyxis/services/customerService?wsdl";));
> >>>>> CustomerService client = customerService.getCustomerServicePort();
> >>>>> Client cl = ClientProxy.getClient(client);
> >>>>> HTTPConduit http = (HTTPConduit) cl.getConduit();
> >>>>> HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
> >>>>> httpClientPolicy.setConnectionTimeout(5000);
> >>>>> httpClientPolicy.setReceiveTimeout(1500);
> >>>>> http.setClient(httpClientPolicy);
> >>>>>
> >>>>> client.myMethod()
> >>>>>
> >>>>>
> >>>>> Question =>  This would be OK outside of Spring right ?
> >>>>>
> >>>>>
> >>>>> 2) But within Spring, I understand it is not Thread Safe to modify
> the
> >>>>> conduit as the service would be a singleton ?
> >>>>>
> >>>>> Question  => Is it the reason for which it is not fine or did I
> >>>>> misunderstand ?
> >>>>>
> >>>>>
> >>>>> 3) So I coded this Interceptor:
> >>>>>
> >>>>> public class OutTimeoutInterceptor extends
> >>>>> AbstractPhaseInterceptor<Message> {
> >>>>>   private int receiveTimeout;
> >>>>>   public OutTimeoutInterceptor() {
> >>>>>       super(Phase.PREPARE_SEND);
> >>>>>   }
> >>>>>   public OutTimeoutInterceptor(String phase) {
> >>>>>       super(phase);
> >>>>>   }
> >>>>>
> >>>>>   public OutTimeoutInterceptor(String phase, boolean uniqueId) {
> >>>>>       super(phase, uniqueId);
> >>>>>
> >>>>>   }
> >>>>>
> >>>>>   public OutTimeoutInterceptor(String i, String p, boolean uniqueId)
> {
> >>>>>       super(i, p, uniqueId);
> >>>>>
> >>>>>   }
> >>>>>
> >>>>>   public OutTimeoutInterceptor(String i, String p) {
> >>>>>       super(i, p);
> >>>>>
> >>>>>   }
> >>>>>
> >>>>>   @Override
> >>>>>   public void handleMessage(Message message) throws Fault {
> >>>>>       if("{
> >>>>>
> http://customerservice.example.com/}CustomerServiceServiceSoapBinding
> >>>>
> ".equals(message.getExchange().getBindingOperationInfo().getBinding().getName().toString()))
> >>>>> {
> >>>>>           message.put(Message.RECEIVE_TIMEOUT,
> >>>>> getReceiveTimeout());
> >>>>>       }
> >>>>>   }
> >>>>>
> >>>>>   /**
> >>>>>    * @return the receiveTimeout
> >>>>>    */
> >>>>>   public int getReceiveTimeout() {
> >>>>>       return receiveTimeout;
> >>>>>   }
> >>>>>
> >>>>>   /**
> >>>>>    * @param receiveTimeout the receiveTimeout to set
> >>>>>    */
> >>>>>   public void setReceiveTimeout(int receiveTimeout) {
> >>>>>       this.receiveTimeout = receiveTimeout;
> >>>>>   }
> >>>>>
> >>>>> }
> >>>>>
> >>>>>
> >>>>> Configured this:
> >>>>>
> >>>>> <beans xmlns="http://www.springframework.org/schema/beans";
> >>>>>   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
> xmlns:jaxws="
> >>>>> http://cxf.apache.org/jaxws";
> >>>>>   xmlns:jee="http://www.springframework.org/schema/jee";
> >>>> xmlns:http-conf="
> >>>>> http://cxf.apache.org/transports/http/configuration";
> >>>>>   xsi:schemaLocation="http://www.springframework.org/schema/beans
> >>>>> http://www.springframework.org/schema/beans/spring-beans.xsd
> >>>>> http://cxf.apache.org/jaxws
> >>>>> http://cxf.apache.org/schemas/jaxws.xsd
> >>>>> http://cxf.apache.org/core
> >>>>> http://cxf.apache.org/schemas/core.xsd
> >>>>> http://cxf.apache.org/transports/http/configuration
> >>>>> http://cxf.apache.org/schemas/configuration/http-conf.xsd";>
> >>>>>
> >>>>>   <!-- Needed -->
> >>>>>   <!-- When you don't use the imports, when a Bus is needed, it will
> >>>>> create a default
> >>>>> bus which would be using it's own spring context.   When the Bus
> looks
> >>>> for
> >>>>> configuration, it would just look in that spring context since it
> >>>> wouldn't
> >>>>> know about your context.  I THINK if you use a jaxws:client thing
> >>>> instead
> >>>>> of a
> >>>>> spring bean, it MAY wire the current context into the default bus.
>  Not
> >>>>> really
> >>>>> sure though.   However, if you use normal spring beans, not much we
> >>>> can do
> >>>>> unless we create spring specific subclasses (which we could) that
> >>>> would be
> >>>>> Spring ApplicationContextAware to to wire things.   Would be more of
> a
> >>>>> documentation issue of "when to use JaxWsProxyFactoryBean or
> >>>>> SpringJaxWsProxyFactoryBean" and such.
> >>>>>   -->
> >>>>>   <import resource="classpath:META-INF/cxf/cxf.xml" />
> >>>>>   <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
> >>>>>   <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
> >>>>>   <http-conf:conduit
> >>>>>       name="{
> >>>>> http://customerservice.example.com/}CustomerServicePort.http-conduit
> ">
> >>>>>       <http-conf:client ReceiveTimeout="30000" />
> >>>>>   </http-conf:conduit>
> >>>>>
> >>>>>   <bean id="proxyFactory"
> >>>>> class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
> >>>>>       <property name="serviceClass"
> >>>>> value="com.example.customerservice.CustomerService" />
> >>>>>       <property name="wsdlLocation"
> >>>>> value="classpath:/wsdl/CustomerService.wsdl" />
> >>>>>       <property name="address"
> >>>>>           value="
> http://localhost:8080/pyxis/services/customerService";
> >>>> />
> >>>>>       <property name="inInterceptors">
> >>>>>           <list>
> >>>>>               <ref bean="logIn" />
> >>>>>           </list>
> >>>>>       </property>
> >>>>>       <property name="outInterceptors">
> >>>>>           <list>
> >>>>>               <ref bean="logOut" />
> >>>>>
> >>>>> <!-- Set timeout per operation-->
> >>>>>               <ref bean="timeoutSetter" />
> >>>>>           </list>
> >>>>>       </property>
> >>>>>   </bean>
> >>>>>   <bean id="client"
> class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"
> >>>>>       factory-bean="proxyFactory" factory-method="create" />
> >>>>>   <bean id="logIn"
> >>>>> class="org.apache.cxf.interceptor.LoggingInInterceptor" />
> >>>>>   <bean id="logOut"
> >>>>> class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
> >>>>>   <bean id="timeoutSetter"
> >>>>> class="com.adeo.pyxis.poc.cxf.client.OutTimeoutInterceptor">
> >>>>>      <property name="receiveTimeout" value="3000" />
> >>>>>   </bean>
> >>>>>   <bean id="factory"
> >>>> class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean" />
> >>>>> </beans>
> >>>>>
> >>>>>
> >>>>> Question => This works fine but seems to me not that straight, so I
> >>>> wonder
> >>>>> if it's the right way ?
> >>>>>
> >>>>>
> >>>>> 4) I thought the JAXWS way would work reading this:
> >>>>>
> >>>>> http://cxf.apache.org/docs/developing-a-consumer.html
> >>>>>
> >>>>> *Request context* - on the client side, the request context enables
> >>>> you to
> >>>>> set properties that affect outbound messages. Request context
> >>>> properties
> >>>>> are applied to a specific port instance and, once set, the properties
> >>>>> affect every subsequent operation invocation made on the port, until
> >>>> such
> >>>>> time as a property is explicitly cleared. For example, you might use
> a
> >>>>> request context property to set a connection timeout or to initialize
> >>>> data
> >>>>> for sending in a header.
> >>>>>
> >>>>>   Service = new Service();
> >>>>>
> >>>>>   Port = Service.getPort();
> >>>>>
> >>>>>
> >>>>>   ((BindingProvider) Port).getRequestContext().put(
> >>>>>           BindingProviderProperties.CONNECT_TIMEOUT,
> >>>>>           30);
> >>>>>   ((BindingProvider) Port).getRequestContext().put(
> >>>>>           BindingProviderProperties.REQUEST_TIMEOUT,
> >>>>>           30);
> >>>>>
> >>>>> But it does not and I am confused by this Open bug:
> >>>>>
> >>>>> https://issues.apache.org/jira/browse/CXF-3011
> >>>>>
> >>>>>
> >>>>> Question => Is it supposed to work ? Looking into source code I don't
> >>>> find
> >>>>> how but I would like some confirmation ?
> >>>>>
> >>>>>
> >>>>> I will be happy to contribute documentation patch to clarify this as
> it
> >>>>> seems to me kind of difficult to find the right answer.
> >>>>>
> >>>>>
> >>>>> Many thanks for your help and thanks for CXF !
> >>>>>
> >>>>> Regards
> >>>>>
> >>>>> Philippe
> >>>>
> >>>> --
> >>>> Daniel Kulp
> >>>> dk...@apache.org - http://dankulp.com/blog
> >>>> Talend Community Coder - http://coders.talend.com
> >>>>
> >>>>
> >>>
> >>> --
> >>> Daniel Kulp
> >>> dk...@apache.org - http://dankulp.com/blog
> >>> Talend Community Coder - http://coders.talend.com
> >>>
> >>>
> >>
>
> --
> Daniel Kulp
> dk...@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
>
>

Reply via email to