Monday, December 15, 2008

Configure http connection timeout in CXF

CXF is a great open source web service engine. The things that I like most are

1. Strong integration with Spring framework.
2. Solid support for maven.
3. Highly configuratble.

When we develop web services with cxf, quite often, we want to be able to control the http timeout settings in the web service engine. It's very easy to do this in CXF. what you need is:

1. Create a cxf.xml file and put it on your classpath.
2. Add the following configurations:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<http-conf:conduit
name="{urn:transurban:glide:accountgateway:readtokens}ReadTokensPort.http-conduit">
<http-conf:client ConnectionTimeout="30000" ReceiveTimeout="6000"/>
</http-conf:conduit>
</beans>

Note that the configuration is based on the port type defined in wsdl. This way, you can have different timeout settings for different web services. The most important setting here is "ReceiveTimeout". This indicates how long the engine will wait for http response before it throws exceptions.

3 comments:

Anonymous said...

Does it really work? I've seen several notes around that seem to indicate it dowsn't (due to a bug). I've tried that approach myself but still get a 60 second timeout. The only difference I can se is that I used a wildcard for the service name. And I assumed this should be set on the cxf-client not on the cxf-server.

Larry said...

The settings worked very well when used in client side. I haven't tried to configure http connection in CXF server. It'd be interesting to know...

Brady... said...

Hi Larry,

First place, Thank you very much for your blog.

But in my case I need to catch the Timeout exception. I am catching the Timeout Exception in the Interceptors and I am trying to throw the custom response message.

I have the Wrapped Exception Class and Exception class for the JAXB to use for Marshalling and UnMarshalling, but though I call the Wrapped Exception Class it is not creating the custom message. I am catching the TimeoutException by finding the instance of the cause to WebServiceException. So I tried to modify the Fault Message as below.

Element elementNs3 =
fault.getOrCreateDetail().getOwnerDocument().createElementNS("http://XXX/XXX",
"ns3:ServiceException");

Element messageElement =
fault.getDetail().getOwnerDocument().createElement("messageId");
messageElement.setTextContent("SomeMessage");

Element textElement =
fault.getDetail().getOwnerDocument().createElement("text");
textElement.setTextContent("Server has timedout");

Element variableElement =
fault.getDetail().getOwnerDocument().createElement("variables");
variableElement.setTextContent("ERR_0006");


fault.getDetail().appendChild(elementNs3).appendChild(messageElement);
fault.getDetail().appendChild(elementNs3).appendChild(textElement);

fault.getDetail().appendChild(elementNs3).appendChild(variableElement);

So I am getting the soap fault as below




soap:Server
Could not send Message.


SomeMessage
Server has timedout
ERR_0006






But I need to add

Please can you let me know if the way which I am doing is right and it is as per the standard please can you let me know and if it is the right approach please can you help me how to add the second namespace.

If it is not the right approach please can you help me to know what is the standard way to catch the Timeout Exceptions.

Thank you,

Brady...