How to use WireMock for stubbing web services

WireMock is a library for stubbing and mocking REST Web services. This will be a handy one if we want to test external web services. When we use this, it will start a mock http server on the given port number so it looks like we are connecting to the actual web services.

Lets see how we can use this for writing JUnit test cases. Consider that you have two web services. one if for creating the user and another one is for fetching it. We don’t worry about the actual services. Let’s see how we can stub these services with WireMock.

I am going to use JUnit Rule for this example. Add the below dependencies in the maven pom.xml file.


<dependencies>
        <dependency>
            <groupId>com.github.tomakehurst</groupId>
            <artifactId>wiremock</artifactId>
            <version>2.7.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.18</version>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

Now my test code is given below,


package com.wiremock;

import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.glassfish.jersey.client.JerseyClient;
import org.glassfish.jersey.client.JerseyClientBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import javax.ws.rs.core.Response;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static javax.ws.rs.client.Entity.entity;
import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE;
import static org.junit.Assert.assertEquals;

public class WireMockTest {

    @Rule
    public WireMockRule rule = new WireMockRule(8080);

    private static String GET_USERS = "http://localhost:8080/users/12345";
    private static String POST_USER = "http://localhost:8080/users";
    private static String USER_CONTENT = "12345bala";

    JerseyClient client;

    @Before
    public void setUp() {
        client = JerseyClientBuilder.createClient();
    }

    @After
    public void tearDowm() {
        rule.shutdown();
    }

    private void stubFor(){
      rule.stubFor(post(urlEqualTo("/users")).willReturn(aResponse().withStatus(200));
rule.stubFor(get(urlEqualTo("/users/12345")).willReturn(
                aResponse().withHeader("Content-Type", "application/xml")
                        .withBody(USER_CONTENT)));
    }

    @Test
    public void testAddUser() {
        stubFor();
        client.target(POST_USER).request().post(entity(USER_CONTENT, APPLICATION_XML_TYPE));
        rule.verify(postRequestedFor(urlMatching("/users"))
                            .withRequestBody(matching(USER_CONTENT))
                            .withHeader("Content-Type", matching("application/xml")));

    }

    @Test
    public void testGetUser() {
        stubFor();
        Response response = client.target(GET_USERS).request().get();
        String output = response.readEntity(String.class);
        System.out.println("output: "+output);
        assertEquals(200, response.getStatus());
        assertEquals(USER_CONTENT, output);
    }
}

Explanation:
The first step is to add the WireMockRule and pass the port number on which the mock server is going to be run. You can specify any port number. By default its 8080.

Now the next step is to add the stubFor for both services(getUser, addUser)
For adding user service, the method is POST and it will return the response status as 200. For getting the user service, the method is GET and it will the return the static user response XML.

The next step is to call the services with the REST client object.
The final step is to do the verification. We can do the same kind of verification as such verifying the actual response.

Refer the code @https://github.com/dkbalachandar/java-wiremock-tester

Java 8 – Lambda Predicates

Predicate is a functional interface in java 8. It’s used to hold the lambda expression and takes a value or an object and return a boolean value.

This is very handy if you want to do any validation or filtering anythig.

Refer the below example to know how to use the Predicate for validating the number whether it’s even or not and some more operations.


import java.util.function.Predicate;

public class PredicateMain {

    public static void main(String[] args) {
        // Validate whether the number is even or not.
        System.out.println("Predicates.isEven(2)::" + Predicates.isEven().test(2));
        // Validate whether the number is odd or not.
        System.out.println("Predicates.isOdd(3) ::" + Predicates.isOdd().test(3));
        // Validate whether the number is even and also greater than 100
        System.out.println("Predicates.isEven().and(Predicates.isGreaterThan100(100)) ::"
                + Predicates.isEven().and(Predicates.isGreaterThan100()).test(100));
        // Validate whether the number is even and also greater than 100
        System.out.println("Predicates.isEven().and(Predicates.isGreaterThan100(102)) ::"
                + Predicates.isEven().and(Predicates.isGreaterThan100()).test(102));
        // Validate whether the number is even or greater than 100
        System.out.println("Predicates.isEven().or(Predicates.isGreaterThan100(101)) ::"
                + Predicates.isEven().or(Predicates.isGreaterThan100()).test(101));
        // Validate whether the number is even and negate the result.
        System.out.println("Predicates.isEven().negate(11) ::" + Predicates.isEven().negate().test(11));
    }

    static class Predicates {

        public static Predicate isEven() {
            return number -> number % 2 == 0;
        }

        public static Predicate isOdd() {
            return number -> number % 2 != 0;
        }

        public static Predicate isGreaterThan100() {
            return number -> number > 100;
        }
    }
}


Output:



Predicates.isEven(2)::true
Predicates.isOdd(3) ::true
Predicates.isEven().and(Predicates.isGreaterThan100(100)) ::false
Predicates.isEven().and(Predicates.isGreaterThan100(102)) ::true
Predicates.isEven().or(Predicates.isGreaterThan100(101)) ::true
Predicates.isEven().negate(11) ::true


Refer the below example to know how we can use this for filtering


import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateCollections {

    public static void main(String[] args) {

        List users = Arrays.asList(new User("Bob", 51, 170), new User("john", 52, 80), new User("paul", 45 ,120), new User("alex", 46, 150), new User("scott", 56, 150));

        //All the users whose age are above 50
        List above50Users = filter(users, isAgeAbove50());
        System.out.println("The above 50 age users \n" + above50Users);

        //All the users whose age are below 50
        List below50Users = filter(users, isAgeBelow50());
        System.out.println("The below 50 age users \n"+ below50Users);

        //We can also use the negate expression. Lets see how we can do that
        above50Users = filter(users, isAgeBelow50().negate());
        System.out.println("The above 50 age users \n" + above50Users);

        below50Users = filter(users, isAgeAbove50().negate());
        System.out.println("The below 50 age users \n"+ below50Users);

        //Users whose age is above 50 and weight is more than 100
        List above50AndExcessWeightUsers = filter(users, isAgeAbove50().and(isWeightGtThan100()));
        System.out.println("The above 50 and excess weight users \n"+ above50AndExcessWeightUsers);
    }

    public static Predicate isAgeAbove50() {
        return user -> user.age > 50;
    }

    public static Predicate isAgeBelow50() {
        return user -> user.age < 50;
    }
    public static Predicate isWeightGtThan100() {
        return user -> user.weight > 100;
    }

    public static List filter(List users, Predicate p) {
        return users.stream().filter(p::test).collect(Collectors.toList());
    }

    static class User {

        String name;
        int age;
        int weight;

        User(String name, int age, int weight) {
            this.name = name;
            this.age = age;
            this.weight = weight;
        }

        @Override
        public String toString() {
            return "name:"+name +" age:"+age + " weight:"+weight;
        }
    }
}

Output:


The above 50 age users 
[name:Bob age:51 weight:170, name:john age:52 weight:80, name:scott age:56 weight:150]
The below 50 age users 
[name:paul age:45 weight:120, name:alex age:46 weight:150]
The above 50 age users 
[name:Bob age:51 weight:170, name:john age:52 weight:80, name:scott age:56 weight:150]
The below 50 age users 
[name:paul age:45 weight:120, name:alex age:46 weight:150]
The above 50 and excess weight users 
[name:Bob age:51 weight:170, name:scott age:56 weight:150]


Jersey REST service and Thread Local usage

In this exercise, I am going to provide an example to show how we can use the ThreadLocal with the Jersey REST service.

Consider that it’s a REST application and we need the user details in the application flow many places. The User details will be retrieved with the header information availbale in the HttpServletRequest.
One solution is to pass the HttpServletRequest object whereever its required. But its a tedious job.
So an another way is to use the ContainerRequestFilter and processes the request, then extract out the header and call the back end to get the User details and put into the ThreadLocal storage so that it can be accessible anywhere in that thread flow.

Refer the below sample code to know how to do that. We don’t use the Spring Framework here.

DataHolder:
This class holds the static ThreadLocal variable and it has getter and setter for User object. We will be setting the User Object from the ContainerRequestFilter


package com.utils;

public class DataHolder{

    private static final ThreadLocal userThreadLocal = new ThreadLocal();

    public static void setUser(User user) {
        userThreadLocal.set(user);
    }

    public static User getUser() {
        return userThreadLocal.get();
    }

    public static void remove() {
        userThreadLocal.remove();
    }
}

UserDataCaptureRequestFilter
This filter will intercept the request and extract out the header and retrieve the user details and put it into the ThreadLocal.



package com.filters;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
public class UserDataCaptureRequestFilter implements ContainerRequestFilter {
    @Context
    private HttpServletRequest httpRequest;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        //Get the User data from the back end system with the request header/cookie. I have not given the getUser() method but assume it will get the user details 
        User user = getUser(httpRequest);
        DataHolder.setUser(user);
    }
}


Application
The ResourceConfig class where we can specify the packages to look into for the end points and context


public class Application extends ResourceConfig {
    public Application() {
        packages(true, "com.resource");
        packages(true, "com.filters");
    }
}

 
UserResource
This service returns the User details in JSON format. Here We have not retrived the User Details once again since we already retrieved the data in the filter itself. So the data would be available in the Thread scope. So we could use it


package com.resource;

import com.utils.DataHolder;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("user")
public class UserResource{

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUser() {
       
        return Response.ok().entity(DataHolder.getUser()).type(MediaType.APPLICATION_JSON).build();
    }
}

 

 

Finding the majority Element with Moore’s Voting Algorithm

Leetcode problem:

https://leetcode.com/problems/majority-element/description/

Problem Description:

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exists in the array.

Algorithm Link:

https://www.cs.utexas.edu/~moore/best-ideas/mjrty/index.html

moores-voting-algorithm

Solution:


public class Main {

    public static int majorityElement(int[] nums) {

        int currentElement = 0;
        int counter = 0;
        for (int num : nums) {
            if (counter == 0) {
                currentElement = num;
                counter = 1;
            }
            else {
                if (num == currentElement) {
                    counter++;
                }
                else {
                    counter--;
                }
            }
        }
        return currentElement;
    }

    public static void main(String[] args) {

        int[] nums = new int[] { 1, 3, 4, 5, 5, 1, 1 };
        System.out.println(majorityElement(nums));
    }
}


How to use Mockito ArgumentCaptor

In this post, I am going to explain how we can use ArgumentCaptor to test out an internal object which is getting passed to some other class.

Consider that you have a Main class which has a method called “populateAndSavePersonData” which is used to construct the Person details(Person Object) and calls the “savePersonData” method from Dao class to populate the data into DB.  Now you want to test out the Person object and its values since it’s not getting returned from this class. So we have to either update the class to return the person object or we can use ArgumentCaptor to capture that object.

Refer the below example to know how we can do that.

Person.java


import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import java.io.Serializable;


public class Person implements Serializable {

    private String firstName;

    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public boolean equals(Object o) {
        return EqualsBuilder.reflectionEquals(this, o);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

}

Main.java and Dao.java


public class Main {

    private Dao dao;
    public Main(Dao dao){
        this.dao = dao;
    }
    public void populateAndSavePersonData(String firstName, String lastName) {

        Person person = new Person();
        person.setFirstName(firstName);
        person.setLastName(lastName);
        dao.savePersonData(person);
    }

    public class Dao {

        public void savePersonData(Person person) {
            // Code to save the data into DB
        }
    }
}

MainTest.java
In our test method, We have to create an ArgumentCaptor object and pass the appropriate object which you want to capture(Person). Then you have to call the actual method with the appropriate arguments. After that call “verify” method on Mockito object and pass the dao object and call the appropriate method(“savePersonData”) which gets called in the “populateAndSavePersonData” method. Finally, we have to get the value from ArgumentCaptor and check the value in it.


import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

public class MainTest {

    @Test
    public void populateAndSavePersonData(){
        Main.Dao dao = Mockito.mock(Main.Dao.class);
        Main main = new Main(dao);
        ArgumentCaptor personArgumentCaptor = ArgumentCaptor.forClass(Person.class);
        main.populateAndSavePersonData("Bala","Samy");
        Mockito.verify(dao).savePersonData(personArgumentCaptor.capture());
        Person person = personArgumentCaptor.getValue();
        assertEquals("Bala",person.getFirstName());
        assertEquals("Samy",person.getLastName());
        System.out.println(person);
    }
}

 

HK2 Dependency Injection – Using Iterable provider

HK2 is a light weight, dynamic dependency injection framework. If you don’t want to rely on spring framework for managing the dependencies then you can use this.

In this post, I am going to explain how to use the Iterable provider with an example.

Assume that you have a Jersey REST application and it has an endpoint which is responsible for sending out some details to different systems such as Kafka, Database. There is a class called Emitter which is responsible for emitting the data. There are two classes KafkaProducer which produce the data to Kafka and another one DatabaseProducer which writes the data into DB and both these classes implement the MessageProducer interface.

I am not going to give the exact code to be used for doing this. My main motive is to show how we can use Iterable provider here.

MessageProducer.java


public interface MessageProducer {
    public void produce(String message);
}

DBProducer.java
DBProducer class sends out the message to DB


public class DBProducer implements MessageProducer {

    @Override
    public void produce(String message) {
        //Write code to send out the message to DB
        System.out.println("Producing the message to DB");
    }
}

KafkaProducer.java
KafkaProducer class sends out the message to Kafka



public class KafkaProducer implements MessageProducer {

    @Override
    public void produce(String message) {
        //Write code to send out the message to kafka
        System.out.println("Producing the message to Kafka");
    }
}

DependencyBinder.java
DependencyBinder class to be used for binding. Hence you need to pass this class as an init parameter to the Jersey servlet(Parameter name: javax.ws.rs.Application)


import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;

import javax.inject.Singleton;

public class DependencyBinder extends ResourceConfig {

    public DependencyBinder() {
       //the resource class is available in com/resource folder
        packages(true, "com.resource");
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bind(Emitter.class).to(Emitter.class).in(Singleton.class);
                bind(KafkaProducer.class).to(MessageProducer.class).in(Singleton.class);
                bind(DBProducer.class).to(MessageProducer.class).in(Singleton.class);
            }
        });
    }

 

Finally the Emitter class. This class has to send the message to different systems. So we can’t inject the each class here. We can use IterableProvider to achieve this. So the HK2 framework gets all the classes which implement the interface MessageProducer and injects into this class. In this example, it will return DBProducer and KafkaProducer instances.


import org.glassfish.hk2.api.IterableProvider;

import javax.inject.Inject;

public class Emitter {

    @Inject
    private IterableProvider<MessageProducer> messageProducers;

    public void emitMessage() {

        // Write code to prepare the message
        String message = "Its a new message";
        for (MessageProducer messageProducer : messageProducers) {
            messageProducer.produce(message);
        }
    }
} 

Testing the mail functionality with Fake Smtp Server

In this post, I am going to show how we can integrate the FakeSmtp server with a java application.

Fake SMTP is a dummy SMTP server which is mainly used for testing the emails. It’s useful for the developers as it emits the email content into a local file directory. So we can check the local file content and do the validations.

The Dockerfile for the Fake Smtp is given below,

mail-rest-docker/tree/master/fake-smtp


FROM java:8

RUN mkdir -p /opt && \
  wget -q http://nilhcem.github.com/FakeSMTP/downloads/fakeSMTP-latest.zip && \ 
   unzip fakeSMTP-latest.zip -d /opt && \
   rm fakeSMTP-latest.zip

VOLUME /output

RUN chmod +x /opt/fakeSMTP-2.0.jar

EXPOSE 25

CMD java -jar /opt/fakeSMTP-2.0.jar --start-server --background --output-dir /output --port 25

If you refer the last line of the above file, you can understand that the email content would be written under the /output folder. So we have to mount the local directory accordingly in the docker compose file.

Next one is the REST application code to send out the email to Fake SMTP server.

mail-rest-docker/blob/master/src/main/java/com/resource/MailResource.java


package com.resource;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Properties;

@Path("/sendMail")
public class MailResource {

    Properties properties = System.getProperties();

    public MailResource() {
        properties.put("mail.smtp.host", System.getenv("SMTP_HOST"));
        properties.put("mail.smtp.port", "25");
    }

    @GET
    @Produces(MediaType.TEXT_HTML) public Response sendSimpleHelloMail() throws WebApplicationException {

        String to = "test123@gmail.com";
        String from = "test123@gmail.com";
        Session session = Session.getDefaultInstance(properties);
        try {
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject("Subject");
            message.setContent("<h1>Hello</h1>", "text/html");
            Transport.send(message);
            System.out.println("Sent message successfully....");
        }
        catch (Exception ex) {
            ex.printStackTrace();
            throw new WebApplicationException(ex.getMessage());
        }
        return Response.ok().entity("Mail has been sent successfully").build();
    }
}

The SMTP_HOST enviornmental variable should hold the Fake SMTP server host. In this case, we have to link the Fake SMTP service with the REST container and give that service. Refer the below docker-compose.yml file to know how to do that.

mail-rest-docker/blob/master/docker-compose.yml


rest:
    image: mail-rest:latest
    ports:
        - 8080:8080
    environment:
       - SMTP_HOST=mail
    links:
      - mail:mail
mail:
    image: fake-smtp:latest
    volumes:
     - ./output:/output
    expose:
     - 25

Here we have mounted the local output directory to output folder. so the mail content will be available under the output folder and linked the fake-smtp service and giving that in the SMTP_HOST env variable.

Follow the below steps to run this application,

1. Clone this repository
2. Package the project by running mvn Package
3. Run ‘docker images’ and confirm that the ‘mail-rest’ docker images is available.
3. Then go into fake-smtp folder and build the image by running ‘docker build -t fake-smtp:latest . ” and confirm that the ‘fake-smtp’ docker images is available.

4. Then go to project root folder(java-mail-rest) and run “docker-compose up -d”
5. Access the REST endpoint with http://localhost:8080/api/sendEmail
6. Check the output folder and confirm that there is an eml file created which has the email content

Here is the sample file content

mail-rest-docker/blob/master/output/220717072710377.eml


        Sat, 22 Jul 2017 19:27:10 +0000 (UTC)
From: test123@gmail.com
To: test123@gmail.com
Message-ID: <840194110.01500751630345.JavaMail.root@2c7d28e1a4a2>
Subject: Subject
MIME-Version: 1.0
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<h1>Hello</h1>

Refer the code @ https://github.com/dkbalachandar/mail-rest-docker