Test Secure REST services with Chrome Browser Plugin

Most of us want to test out the REST services via Advanced Rest Client or Postman for some reason or debug an issue.

But if the REST services are secure and protected by Ping Access or SiteMinder or any other tool, then we will get a login page. So we have to hard code the browser cookies to bypass the login page.

There is an another way to do that.

If you are using Advanced Rest Client(https://advancedrestclient.com), then you can use ARC cookie exchange plugin.
So this plugin helps ARC plugin to retrieve the browser cookies and send it in the request.

If you are using Postman(https://www.getpostman.com), then you can use Postman interceptor. So the Postman interceptor plugin helps the Postman plugin to use the browser cookies for each service call.

HTTP Caching in REST API

In this post, I am going to show an example which explains the implementation of HTTP caching in REST API.

As we know that REST API services can be cached in the browser whereas SOAP based services are not.

We have two kinds of cache control mechanism

1. Time based cache header
2. Conditional cache header

Time based cache header

Assume that we have a web service and you want to cache the response of that service in client’s browser for 5 min. So to achieve the same, we should have to set the cache control HTTP header appropriately


Cache-Control:private, max-age=300

Here “private” denotes that the response will be cached only in the client mostly by browser and not any intermediate proxy servers

max-age denotes that how long the resource is valid. The value should be given in seconds

Conditional cache header

With the conditional cache header approach, the browser will ask the server whether the response/content has been changed or not. Here the Browser sends out ETag and If-Modified-Since headers[Need to set If-Modified-Since at the client API] to the server and at the server side we should use these headers and implement our logic and send out the response only if its changed or the client side content has been expired.

You can note for the first time, we get the HTTP status 200 and for the subsequent request, we get the HTTP status 304 Not Modified

Please refer the below sample code which shows both approaches



import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;

@Path("/greeter")
public class GreetingResource {

    private static final String HELLO_MESSAGE= "Welcome %s";

    private static final String BIRTHDAY_MESSAGE= "Happy Birthday %s";

    @Context
    private Request request;

    @GET
    @Path("welcome")
    @Produces(MediaType.TEXT_HTML)
    public Response sayWelcomeMessage(@QueryParam("name") String name) {
        System.out.println("sayWelcomeMessage:::::"+ System.currentTimeMillis());
        CacheControl cacheControl = new CacheControl();
        cacheControl.setMaxAge(60);
        cacheControl.setPrivate(true);
        Response.ResponseBuilder builder = Response.ok(String.format(HELLO_MESSAGE, name));
        builder.cacheControl(cacheControl);
        return builder.build();
    }

    @GET
    @Path("bday")
    @Produces(MediaType.TEXT_HTML)
    public Response sayBdayWishesMessage(@QueryParam("name") String name) {

        System.out.println("sayGreetingMessage:::::"+ System.currentTimeMillis());
        CacheControl cacheControl = new CacheControl();
        //60 seconds
        cacheControl.setMaxAge(60);

        String message = String.format(BIRTHDAY_MESSAGE, name);
        EntityTag entityTag = new EntityTag(Integer.toString(message.hashCode()));
        //Browser sends ETag. So we can use this and
        // find out whether the response is expired or not
        Response.ResponseBuilder builder = request.evaluatePreconditions(entityTag);
        // If the build is null, then the content dont match, so the response should be sent
        if (builder == null) {
            builder = Response.ok(message);
            builder.tag(entityTag);
        } else {
            builder.cacheControl(cacheControl).tag(entityTag);
        }
        return builder.build();
    }
}

Rest API to produce message to Kafka using Docker Maven Plugin

I have developed a simple REST API to send the incoming message to Apache Kafka.

I have used Docker Kafka (https://github.com/spotify/docker-kafka) and the Docker Maven Plugin(https://github.com/fabric8io/docker-maven-plugin) to do this.

So before going through this post be familiarize yourself with Docker and Docker Compose

Docker Maven Plugin[Docker Maven Plugin] provides us a nice way to specify multiple images in POM.xml and link it as necessary. We can also use Docker compose for doing this. But I have used this plugin here.

    1. Clone the project (https://github.com/dkbalachandar/kafka-message-sender)
    2. Then go into kafka-message-sender folder
    3. Then enter ‘mvn clean install’
    4. Then enter  ‘mvn docker:start’. Then enter ‘docker ps’ and make sure that there are two containers are running. The name of those containers are kafka, kafka-rest
    5. Then access http://localhost:8080/api/kafka/send?msg=test and confirm that you see message has been sent on the browser
    6. Then enter the below command and make sure that whatever message which you sent is available at Kafka[Kafka Command Line Consumer] or you can also consume via a Flume agent[Kafka Flume Agent Consumer]
docker exec -it kafka /opt/kafka_2.11-0.8.2.1/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning

Rest Assured API for Rest Service Integration testing

We use Rest Assured Api for testing the Rest services. Its very easy to implement. It works based on Given when then approach


public class RestAssuredTest{
    
    @Before
    public void setUp() {
        RestAssured.baseURI = "http://localhost"; //Domain name
        RestAssured.port = 8080; //port number
        RestAssured.basePath = "/api/"; //Service Base URL
    }

    @Test
    public void testRestService() {
        Response res = given().param("QUERY_PARAM", "QUERY_VALUE").get("REST SERVICE PATH");
        assertEquals(200, res.getStatusCode());
        assertNotNull(res.getBody());
res.getBody().asString());     
    }
}

Please refer my another posts for more information Rest Assured – Example and Rest Assured – Test Secure web services