cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Philippe Mouawad <pmoua...@apache.org>
Subject Re: What is the proper way of setting client Timeout per Webservice method ?
Date Mon, 06 May 2013 14:48:51 GMT
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 ?

Regards
Philippe

>
> On Mon, May 6, 2013 at 4:09 PM, Daniel Kulp <dkulp@apache.org> wrote:
>
>>
>> On May 6, 2013, at 10:06 AM, Philippe Mouawad <pmouawad@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 <dkulp@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 <pmouawad@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
>>> dkulp@apache.org - http://dankulp.com/blog
>>> Talend Community Coder - http://coders.talend.com
>>>
>>>
>>
>> --
>> Daniel Kulp
>> dkulp@apache.org - http://dankulp.com/blog
>> Talend Community Coder - http://coders.talend.com
>>
>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message