VOOZH about

URL: https://www.javacodegeeks.com/2017/06/vert-x-meets-service-virtualization-hoverfly.html

⇱ Vert.X meets Service Virtualization with Hoverfly - Java Code Geeks


Service Virtualization is a technique using to emulate the behaviour of dependencies of component-based applications.

Hoverfly is a service virtualisation tool written in Go which allows you to emulate HTTP(S) services. It is a proxy which responds to HTTP(S) requests with stored responses, pretending to be it’s real counterpart.

Hoverfly Java is a wrapper around Hoverfly, that let’s you use it in Java world. It provides a native Java DSL to write expectations and a JUnit rule to use it together with JUnit.

But apart from being able to program expectations, you can also use Hoverfly to capture traffic between both services (in both cases are real services) and persist it.

Then in next runs Hoverfly will use these persisted scripts to emulate traffic and not touch the remote service. In this way, instead of programming expectations, which means that you are programming how you understand the system, you are using real communication data.

This can be summarised in next figures:πŸ‘ Image

First time the output traffic is sent though Hoverfly proxy, it is redirected to real service and it generates a response. Then when the response arrives to proxy, both request and response are stored, and the real response is sent back to caller.

Then in next calls of same method:

πŸ‘ Image

The output traffic of Service A is still sent though Hoverfly proxy, but now the response is returned from previous stored responses instead of redirecting to real service.

So, how to connect from HTTP client of Service A to Hoverfly proxy? The quick answer is nothing.

Hoverfly just overrides Java network system properties (https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html) so you don’t need to do anything, all communications (independently of the host you put there) from HTTP client will  go through Hoverfly proxy.

The problem is what’s happening if the API you are using as HTTP client does not honor these system properties? Then obviously all outgoing communications will not pass thorough proxy.

One example is Vert.X and its HTTP client  io.vertx.rxjava.ext.web.client.WebClient. Since WebClient does not honor these properties, you need to configure the client properly in order to use
Hoverfly.

The basic step you need to do is just configure WebClient with proxy options that are set as system properties.

 
 final Optional<ProxyOptions> proxyOptions = useSystemPropertiesProxyOptions();
if (proxyOptions.isPresent()) {
 final WebClientOptions webClientOptions = new WebClientOptions();
 webClientOptions.setProxyOptions(proxyOptions.get());
 client = WebClient.create(vertx, webClientOptions);
} else {
 client = WebClient.create(vertx);
}

private Optional<ProxyOptions> useSystemPropertiesProxyOptions() {
 final String httpsProxy = System.getProperty("https.proxyHost");
 if (httpsProxy != null) {
 return Optional.of(new ProxyOptions()
 .setHost(httpsProxy)
 .setPort(Integer.parseInt(System.getProperty("https.proxyPort", "443"))));
 } else {
 final String httpProxy = System.getProperty("http.proxyHost");
 if (httpProxy != null) {
 return Optional.of(new ProxyOptions()
 .setHost(httpsProxy)
 .setPort(Integer.parseInt(System.getProperty("http.proxyPort", "80"))));
 }
 }
 return Optional.empty();
}

Notice that the only thing that it done here is just checking if system properties regarding network proxy has been configured (by Hoverfly Java) and if it is the case just create a Vert.X ProxyOptions object to configure the HTTP client.

With this change, you can write tests with Hoverfly and Vert.X without any problem

 
public class VillainsVerticleTest {

 private static Vertx vertx;

 private static String RESPONSE = "[\n"
 + " {\n"
 + " \"name\": \"Moon\",\n"
 + " \"villain\": \"Gru\",\n"
 + " \"wiki\": \"https://en.wikipedia.org/wiki/Moon\"\n"
 + " },\n"
 + " {\n"
 + " \"name\": \"Times Square JumboTron\",\n"
 + " \"villain\": \"Gru\",\n"
 + " \"wiki\": \"https://en.wikipedia.org/wiki/One_Times_Square\"\n"
 + " }\n"
 + "]";


 @ClassRule
 public static HoverflyRule hoverflyRule = HoverflyRule.inSimulationMode(dsl(
 service("crimes:9090")
 .get("/crimes/Gru")
 .willReturn(success(RESPONSE, "application/json"))
 ));

 @BeforeClass
 public static void deployVerticle() throws InterruptedException {
 final CountDownLatch waitVerticleDeployed = new CountDownLatch(1);

 new Thread(() -> {
 vertx = Vertx.vertx();
 DeploymentOptions deploymentOptions = new DeploymentOptions().
 setConfig(new JsonObject()
 .put("services.crimes.host", "crimes")
 .put("services.crimes.port", 9090));

 vertx.deployVerticle(VillainsVerticle.class.getName(), deploymentOptions, event -> {
 if (event.failed()) {
 throw new IllegalStateException("Cannot deploy Villains Verticle");
 }
 waitVerticleDeployed.countDown();
 });
 }).start();
 waitVerticleDeployed.await();
 }

 @Test
 public void should_get_villain_information() {
 given()
 .when()
 .get("villains/{villain}", "Gru")
 .then()
 .assertThat()
 .body("name", is("Gru"))
 .body("areaOfInfluence", is("Worldwide"))
 .body("crimes.name", hasItems("Moon", "Times Square JumboTron"));

 }

}

In previous example Hoverfly is used as in simulate mode and the request/response definitions comes in form of DSL instead of an external JSON script. Notice that in this case you are programming that when a request by current service (VillainsVerticle), is done to host crimes and port 9090, using GET HTTP method at /crimes/Gru then the response is returned. For sake of simplicity of current post this method is enough.

You can see source code at https://github.com/arquillian-testing-microservices/villains-service and read about Hoverfly Java at http://hoverfly-java.readthedocs.io/en/latest/

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

πŸ‘ Photo of Alex Soto
Alex Soto
June 23rd, 2017Last Updated: June 23rd, 2017
0 141 3 minutes read
Back to top button
Close
wpDiscuz