• 2009-08-15

    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());
            }
        }
    }



  • Comments
    blog comments powered by Disqus