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