Mocking the Camunda Http-Connector

1,048 views
Skip to first unread message

c.we...@xilloc.com

unread,
Apr 21, 2015, 8:20:11 AM4/21/15
to camunda-...@googlegroups.com
Hello,
I have the following problem:
I use the Camunda Connect plugin (especially the http-connector) to send requests to external restful web-services and it works nice.

For testing purposes I'd like to mock the http calls, define the response using the mock and in that manner define the process path thats being tested.

Is there a way to mock the http-connect calls?

Regards
Christian

thorben....@camunda.com

unread,
Apr 23, 2015, 3:56:36 AM4/23/15
to camunda-...@googlegroups.com, c.we...@xilloc.com
Hi Christian,

I think the most simple solution would be to use a library like WireMock [1] to mock HTTP responses. I haven't used this myself in combination with BPMN processes and HTTP connectors but I think it's worth giving a try.

Cheers,
Thorben

[1] http://wiremock.org/

Daniel Meyer

unread,
Apr 23, 2015, 5:08:22 AM4/23/15
to camunda-...@googlegroups.com, c.we...@xilloc.com
Another approach would be to configure an interceptor on the connector which intercepts the calls it performs and resturns a static response.

You have to implement a org.camunda.connect.spi.ConnectorConfigurator
and in the Configurator add an interceptor to the http connector:

public class MockHttpConnectorConfigurator implements ConnectorConfigurator<HttpConnector> {


 
public void configure(HttpConnector connecor) {
    connecor
.addRequestInterceptor(new ConnectorRequestInterceptor() {


     
public Object handleInvocation(ConnectorInvocation invocation) throws Exception {


       
// intercept the call. => do not call invocation.proceed()


       
// Could do validation on the invocation here:
       
// invocation.getRequest() ....


       
// build response using http client api...
       
TestHttpResonse testHttpResonse = new TestHttpResonse();
        testHttpResonse
.setEntity(new StringEntity("{...}", ContentType.APPLICATION_JSON));


       
// return the response
       
return new HttpResponseImpl(testHttpResonse);
     
}
   
});
 
}


 
public Class<HttpConnector> getConnectorClass() {
   
return HttpConnector.class;
 
}

 
static class TestHttpResonse extends BasicHttpResponse implements CloseableHttpResponse {

   
public TestHttpResonse() {
     
super(HttpVersion.HTTP_1_1, 200, "OK");
   
}

   
public void close() throws IOException {
     
// no-op
   
}
 
}

}


Untested but I hope you can see the idea behind it?

Cheers,
Daniel

-- 
Camunda Technical Lead
Twitter: @meyerdan

Christian Lipphardt

unread,
Apr 23, 2015, 5:23:59 AM4/23/15
to camunda-...@googlegroups.com, c.we...@xilloc.com
Hi Christian,

I can recommend the library 'betamax'[1], which allows to record http responses and replies them to the client when an approriate url is found.

Cheers,
Christian

Christian Weding

unread,
Apr 29, 2015, 5:22:25 AM4/29/15
to Daniel Meyer, camunda-...@googlegroups.com
Hi guys,
thanks for your productive answers. I managed to mock the Camunda HttpConnector calls, here's how I did it:

1. Use WireMock by simply using the get started page via the JUnit rule.
2. Since WireMock runs a server for backing the mocks on http://localhost:8089, a call to http://my-service:8089/myresource won't work
Therefore I used a ConnectorConfigurator like @Daniel suggested to intercept all HttpConnector calls and overwrite all hostnames to localhost.

public class MockHttpConnectorConfigurator implements ConnectorConfigurator<HttpConnector> {

    public void configure(HttpConnector connector) {
        connector.addRequestInterceptor(new ConnectorRequestInterceptor() {

            public Object handleInvocation(ConnectorInvocation invocation) throws Exception {
                HttpEntityEnclosingRequestBase httpTarget = ((HttpEntityEnclosingRequestBase) invocation.getTarget());
                URI oldUri = httpTarget.getURI();
                httpTarget.setURI(resetUriToLocalhost(oldUri));
                System.out.println("Http-Connector target url changed from: " + oldUri.toString() + " to: "  + httpTarget.getURI().toString());

                return invocation.proceed();

            }
        });
    }

    public Class<HttpConnector> getConnectorClass() {
        return HttpConnector.class;
    }

    public URI resetUriToLocalhost(URI uri) {
        try {
            URI newUri = new URI(uri.getScheme(), uri.getUserInfo(), "localhost", uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
            return newUri;
        } catch (URISyntaxException e) {
            System.out.println("Updating URI port failed");
            e.printStackTrace();
            return uri;
        }
    }
}

PS: This works only for one mocked service, multiple ones could be managed by using the WireMock API directly instead of the JUnit Rule.

Daniel Meyer

unread,
Apr 29, 2015, 7:14:13 AM4/29/15
to camunda-...@googlegroups.com
Great, thanks for contributing your solution back to the forum.

Cheers,
Daniel
Reply all
Reply to author
Forward
0 new messages