Using DoneDone Web Services with Apache CXF 2.2.x
I ran into an issue while trying to hook into DoneDone’s web services. Apparently all of the session management in .NET web services is done at the header/cookie level, which is not really a SOAP standard. Given that I’m using Java (CXF specifically), I needed to do some horrible hackery to make this work. Here is the net result! Note: please realize that it is 1:40 on Sunday morning - this is quick and dirty; I wanted it to work before I passed out. There is NO elegance to be found here.
Spring Configuration:
<?xml version=”1.0” encoding=”UTF-8”?>
<beans xmlns=”http://www.springframework.org/schema/beans” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd“>
<!— Hook to DoneDone —>
<bean id=”doneDoneClient” class=”com.donedone.DoneDoneSoap” factory-bean=”clientFactory” factory-method=”create”/>
<bean id=”clientFactory” class=”org.apache.cxf.jaxws.JaxWsProxyFactoryBean”>
<property name=”serviceClass” value=”com.donedone.DoneDoneSoap”/>
<property name=”address” value=”https://yourproject.mydonedone.com/api/DoneDone.asmx”/>
</bean>
</beans>
Java Test Code:
package limone.test.donedone;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.donedone.ArrayOfProjectInfo;
import com.donedone.DoneDoneSoap;
import com.donedone.ProjectInfo;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { “classpath:/spring-config.xml” })
public class DoneDoneTest {
private static final Logger log = LoggerFactory.getLogger(DoneDoneTest.class);
@Autowired
private DoneDoneSoap client;
@SuppressWarnings(“unchecked”)
@Test
public void testClient() {
Client cxfClient = ClientProxy.getClient(client);
boolean loginStatus = client.login(“username”, “password”);
Map<String, Object> headers = (Map<String, Object>) cxfClient.getResponseContext().get(“org.apache.cxf.message.Message.PROTOCOL_HEADERS”);
Pattern p = Pattern.compile(“(ASP\.NET_SessionId=\w{1,});.*”);
String cookie = null;
for (String cookies : (List<String>) headers.get(“Set-Cookie”)) {
log.debug(“Processing cookie: {}”, cookies);
Matcher m = p.matcher(cookies);
if (m.matches()) {
cookie = m.group(1);
log.debug(“Cookie: {}”, cookie);
}
}
assertTrue(“Could not login.”, loginStatus);
HTTPConduit conduit = (HTTPConduit) cxfClient.getConduit();
HTTPClientPolicy policy = conduit.getClient();
if (policy == null) {
policy = new HTTPClientPolicy();
conduit.setClient(policy);
}
policy.setCookie(cookie);
ArrayOfProjectInfo projects = client.getProjects();
for (ProjectInfo pi : projects.getProjectInfo()) {
log.debug(“Project: {}”, pi.getName());
}
}
}
