3

I'm writing integration tests for a Mule ESB application which connects to an external API via HTTPS. I'd like to mock the external API and run an end-to-end integration test during the Maven build. My question is about setting up an embedded HTTPS server. I've tried to use Jersey, but it only provides HTTP. I was looking at this example

https://github.com/jersey/jersey/tree/master/examples/https-clientserver-grizzly

and I was wondering if there is still some manual step involved, or if it works automatically setting everything up every time the build is kicked off.

Any suggestions or ideas?

Edit. My final goal is to deploy a JAX-RS service in an embedded server which is accessible via HTTPS. And that needs no client-side keys/certificate configuration.

Edit 2. Now my problem concerns certificates. The point of integration tests is to mock external components and verify that my application works. Now, if I set up an embedded HTTPS server and use a cmd-line built certificate, I need to add SSL configuration in the client (as @Ryan Hoegg pointed out). This is not what I would ideally want: Is there a solution to get it working without having to modify my client application code? This should be a general Java question that goes beyond Mule.

Guido
  • 341
  • 5
  • 18

4 Answers4

2

I use confluex-mock-http for this. Under the hood it uses Jetty, but it does all the configuration for you. Creating the MockHttpsServer immediately starts the HTTPS server:

public static final int PORT = 1443;
private MockHttpsServer mockServer;

@Before
public void initHttps() {
    mockServer = new MockHttpsServer(PORT);
    mockServer.respondTo(get("a-service/resource")).withBody(expectedResponse);
}

You can set up your Mule application to trust the certificate used by the mock server. A JKS formatted truststore is available on the classpath, and you can provide it to your HTTPS connector like so:

<https:connector name="someHttpsConnector">
    <https:tls-server path="confluex-mock.truststore" storePassword="confluex" />
</https:connector>

I think some older versions of mule have trouble with this approach, because I needed to use the workaround here.

EDIT: You can include this configuration for the HTTPS Connector only when tests are running by using a Spring profile:

<spring:beans profile="test">
    <mule>
        <!-- connector configuration goes here -->
    </mule>
</spring:beans>

One way to make sure the profile is indeed active when the tests run is to simply set it in a @BeforeClass method:

@BeforeClass
public void initEnvironment() {
    System.setProperty("spring.profiles.active", "test");
}
Community
  • 1
  • 1
Ryan Hoegg
  • 2,415
  • 2
  • 14
  • 15
  • That looks nice, Thanks. However changing the client (aka the tested application) code slightly defeats the point of integration testing. Is there a way e.g. to add that configuration via properties so that it can reside only in the testing code? See Edit.2 above. – Guido Dec 01 '14 at 11:07
  • I also do not want my application code to require changes in order to run tests. I leverage the test environment for that. Based on your question, I assume the certificate presented in production is signed by a CA that is trusted by default in the JDK. In your scenario, I would use a spring profile to include the connector configuration above only when running integration tests (for example, by defining a system property spring.profiles.active=test). I have updated the answer to reflect this approach. – Ryan Hoegg Dec 01 '14 at 22:01
  • 1
    Note that you can pollute your production code even less by providing a separate mule configuration file in src/test/resources containing the connector configuration and including it in getConfigFiles(). – Ryan Hoegg Dec 01 '14 at 22:07
  • This is exactly what I'm doing at the moment. Although it would be nice to leave the code completely untouched i.e. not having to include separate testing xml at all ;) – Guido Dec 02 '14 at 12:06
  • This is about the outstanding bit http://stackoverflow.com/questions/27255015/mule-https-connectors-that-trust-all-certificates – Guido Dec 02 '14 at 17:09
1

The example you refer works automatically. The only manual part I can think about it's security stores (keystore, truststore) creation. Once you have them you can feed Grizzly HttpServer same way it's done in the example.

alexey
  • 1,959
  • 10
  • 9
0

If you are willing to embed any other server, try Jetty.

For configuration see this question

Community
  • 1
  • 1
dasrohith
  • 533
  • 2
  • 8
  • 21
  • Is there an example on how to configure the Jersey built-in HTTPS server? Basically using one of the following: https://jersey.java.net/documentation/latest/deployment.html#deployment.http [Jersey 1.6] – Guido Nov 27 '14 at 12:48
  • @GuidoN Sorry Guido, I didn't got a chance to use Jersey, that is why I pointed embedding the Jetty server in your scenario(If you are not concerned about the server) – dasrohith Nov 27 '14 at 12:53
  • AFAIK Jersey has a pluggable architecture as the link shows. Which should mean that I can use Grizzly or Jetty. I was just wondering If I could find an HTTPS Jetty-Jersey example :) – Guido Nov 27 '14 at 13:09
  • check this url https://jersey.java.net/documentation/latest/deployment.html#deployment.http – dasrohith Nov 27 '14 at 13:17
  • I'm sorry, that's the link I've just posted. I need a full working example on how to set up a JAX-RS service in an embedded HTTPS server. – Guido Nov 27 '14 at 17:03
  • @GuidoN Sorry, I didn't saw that. Check the [answer](http://stackoverflow.com/a/26397822/227775) for this [SO question](http://stackoverflow.com/q/17953886/227775). Hope this helps – dasrohith Nov 28 '14 at 04:32
0

Why don't you simply use Mule for this task?

Create an additional Mule XML file which exposes the JAX-RS service over HTTPS. The idea is to not include this in the production code (i.e. refer it from mule-context.xml), but rather load it from the test case.

You can submit it as a configuration side-by-side with the production config in the FunctionalTestCase class.

Your mock service could look a bit like this (excluding the JAX-RS annotated bean that provides the actual implementation of course).

<flow name="mock-service">
    <https:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8085" path="mockapi"/>
    <jersey:resources>
        <component>
            <spring-object bean="mockApiBean"/>
        </component>
    </jersey:resources>
</flow>
Petter Nordlander
  • 22,053
  • 5
  • 50
  • 84
  • Thank you. You have a point, although the problem with certificates still persists. See Edit.2 above. – Guido Dec 01 '14 at 11:03
  • 1
    I typically use a mock keystore during integration testing, injected via dependency injection - or switch to HTTP during integration test. – Petter Nordlander Dec 01 '14 at 20:20
  • Now the question would be, how do I make a Mule HTTPS connector (the "client") to "trust everything" by using Mockito? – Guido Dec 02 '14 at 12:11
  • I've created a specific question for the matter http://stackoverflow.com/questions/27255015/mule-https-connectors-that-trust-all-certificates – Guido Dec 02 '14 at 17:09