Tag Archives: spring

cxf, spring and http-conf:client problems…

Question:
Is there a way to shorten the timeout in CXF? (http://incubator.apache.org/cxf/)

Answer:
After looking through the CXF documentation, they state that you through Spring (www.springframework.org) can set a timout.

This is done like this (on the client side):

<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"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd">

	<http-conf:conduit name="*.http-conduit">>
		<http-conf:client ReceiveTimeout="100" />
	</http-conf:conduit>
</beans>


I use name=”*.http-conduit” to make my life more simple

This example is from a larger example about ssl configuration on the client connection. It was found here: http://cwiki.apache.org/CXF20DOC/client-http-transport-including-ssl-support.html
There are some additional information in their javadoc, about the HTTPConduit we are setting through spring.: http://incubator.apache.org/cxf/javadoc/latest/org/apache/cxf/transport/http/HTTPConduit.html

The Tests:
When testing this, I implemented the small “HelloWorld” webservice from the CXF User’s guide (http://cwiki.apache.org/CXF20DOC/a-simple-jax-ws-service.html), which can receive a text through a sayHi service, and sends back the response: “Hello “+text-you’ve-sent

In order to test this, i’ve made a dynamical client (just to try, and their guides show an example of doing this).
In the project at work, we are using a generated client, so I made this also.

The dynamical client was made as follows:

DynamicClientFactory dcf = DynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost/HelloWorld/HelloWorld?wsdl");

Object[] results = client.invoke("sayHi", "tester");
System.out.println("response from ws: "+results[0]);

The generated client was made as follows, using wsdl2java:
wsdl2java -impl -p test.webservice.client http://localhost/HelloWorld/HelloWorld?wsdl

I then wrote a test for the dynamic client and the generated client, just to see if it all worked.

package test;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.webservice.client.HelloWorld;
import test.webservice.client.HelloWorldImplService;

public class TestClient extends TestCase {
	protected void setUp() throws Exception {
		super.setUp();
	}

	public void testHelloWorldDynamically() throws Exception {
		DynamicClientFactory dcf = DynamicClientFactory.newInstance();
		Client client = dcf.createClient("http://localhost/HelloWorld/HelloWorld?wsdl");
		
        	Object[] results = client.invoke("sayHi", "tester");
	        System.out.println("response from ws: "+results[0]);
	}
	
	public void testHelloWorldGenerated() {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"client-beans.xml"});
		HelloWorldImplService service = new HelloWorldImplService();
		HelloWorld port = service.getHelloWorldImplPort();

		String result = port.sayHi("tester2");
		
		System.out.println(result);
	}
}

I then altered the sayHi() method on the webservice, to have a Thread.sleep(5000) in it. This was done, so I could simulate a long service call.

package test.webservice;

import javax.jws.WebService;

@WebService(endpointInterface = "test.webservice.HelloWorld")
public class HelloWorldImpl implements HelloWorld {

	public String sayHi(String text) {
		try {
			Thread.sleep(5000);
		}
		catch(InterruptedException ie) {

		}
		
		return "Hello " + text;
	}
}

After some testing, I discovered that the spring configuration didn’t work. According to http://issues.apache.org/jira/browse/CXF-922 the issue with spring configurations where closed and submitted in cxf-2.0.3
Even after upgrading to cxf-2.0.4 it didn’t work.

I then decided to try and set the configuration manually on the dynamically generated client. Based on the information about the spring configuration, I was looking for a “http conduit” in their javadoc.

Their javadoc states that, the HTTPConduit has a method called getClient(), which returns a HTTPClientPolicy. On this HTTPClientPolicy I can set the ReceiveTimeout manually.

So i’ve made a some changes to the JUnit test to see if it all worked.

package test;

import junit.framework.TestCase;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.webservice.client.HelloWorld;
import test.webservice.client.HelloWorldImplService;

public class HelloWorldClientTest extends TestCase {
    protected void setUp() throws Exception {
		super.setUp();
	}

    public void testHelloWorldDynamically() throws Exception {
        // creating the client
        DynamicClientFactory dcf = DynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://localhost/HelloWorld/HelloWorld?wsdl");
        
        // Testing the current values
        HTTPConduit httpConduit = (HTTPConduit)client.getConduit();
        System.out.println("ReceiveTimeout: "+httpConduit.getClient().getReceiveTimeout());
        
        // setting the new values
        httpConduit.getClient().setReceiveTimeout(100);
        System.out.println("ReceiveTimeout: "+httpConduit.getClient().getReceiveTimeout());
        
        Object[] results = client.invoke("sayHi", "tester");
        System.out.println("response from ws: "+results[0]);
    }
    
    public void testHelloWorldGenerated() {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"client-beans.xml"});
		HelloWorldImplService service = new HelloWorldImplService();
		HelloWorld port = service.getHelloWorldImplPort();
        
		// setting the timeout
		Client c = ClientProxy.getClient(port);
		HTTPConduit httpConduit = (HTTPConduit) c.getConduit();
		httpConduit.getClient().setReceiveTimeout(100);

		String result = port.sayHi("tester2");
		
		System.out.println(result);
	}
}

The tests now throws two java.net.SocketTimeoutException, which means that my changes are now working. Cheers!