About Me

My photo
Senior Java Engineer, Wavecell Pte Ltd. Singapore

Wednesday, November 8, 2017

Handling POST request using akka-http in a akka-actor system

Akka-htp is a well known module for providing full server side as well as client side http stack currently supporting Scala and Java language bindings. Among other Java Rest frameworks/libraries such as Spring-boot, Play Framework, JAX-RS, Jersy or Scalatra, akka-http is more preferable in applications where high throughput and concurrency is expected.

Akka-http is not a full MVC framework like Play or not require a container to run like scalatra. As it is based on akka-actor and akka-stream modules inherently reactive and works well with message driven systems. As it supports for different levels(low level and high levl) of APIs makes it easy to adopt and ease of deployment.

Here is a simple example of using Akka-http high level API in Java in a akka-actor system.

First we need following dependencies to be included in our project.




Here we initialize the http server and bind with the akka system. 

We can define our router class by extending 'AllDirectives' class as follows. We use this to get a Route object while initializing the 'routeFlow' as above.

import akka.http.javadsl.model.ContentTypes;
import akka.http.javadsl.model.HttpResponse;
import akka.http.javadsl.server.AllDirectives;
import akka.http.javadsl.server.Route;

import static akka.http.javadsl.server.PathMatchers.integerSegment;
import static akka.http.javadsl.server.PathMatchers.segment;

public class Router extends AllDirectives {

    //host:port/api/{userId}/{resourceId}
    public Route createRoute() {
        return route(
                pathPrefix(segment("api"),
                        () -> pathPrefix(integerSegment(),
                                userId -> pathPrefix(segment(),
                                        resourceId -> pathEndOrSingleSlash(
                                            () -> processRequest(userId, resourceId))
                                )
                        )
               )
        );
    }

}

In the processRequest method we provide the POST request handler which returns a 'akka.http.javadsl.server.Route' instance.
    private Route processRequest(args...) {
        return post(() -> entity(handler...)
        );
    }

Based on the request body (Content-Type) we can use a specific Unmarshaller to access request body data. As an example in order to parse the JSON request body we can use a Unmarshaller provided by 'akka.http.javadsl.unmarshalling.Unmarshaller' , 'akka-http-jackson-experimental_2.11' package, Gson etc.

Using akka.http.javadsl.marshallers.jackson.Jackson;
      {
         "name": "Sam"
         "count" : 10
      }
     public class Request {
       String name;
       int count;
     }
import akka.http.javadsl.marshallers.jackson.Jackson;

public Route processRequestUsingJackson(int userId,String resourceId) {

        return post(() -> entity(Jackson.unmarshaller(Request.class),
                                    content ->
                                        completeWithFuture(
                                            CompletableFuture.completedFuture(
                                                HttpResponse.create()
                                                .withEntity(ContentTypes.APPLICATION_JSON, "{\"msg\":\"Success\"}")
                                            )
                                        )
                                )
        );
    }

Here we use default akka Unmarshaller package to parse entity to string and then Gson to get the Java object.

import akka.http.javadsl.unmarshalling.Unmarshaller;
import com.google.gson.Gson;

private Route processRequestUsingGson(int userId,String resourceId) {

        return post(() -> entity(Unmarshaller.entityToString(), content -> {

                    final Gson gson = new Gson();
                    final Request requestBody = gson.fromJson(content, Request.class);

                    return completeWithFuture(
                                CompletableFuture.completedFuture(
                                        HttpResponse.create()
                                        .withEntity(ContentTypes.APPLICATION_JSON, "{\"msg\":\"Success\"}")
                                )
                    );
                }
            )
        );
    }

Monday, October 30, 2017

Uploading maven artifacts to a ftp location using SFTP protocol.

Apache Maven Wagon is a set of plugins developed to provides a transport abstraction for handling maven artifacts and repositories. Shown below is the way to use 'wagon-ssh' plugin to upload maven artifacts to a ftp location using the SFTP protocol.

This is quite straight forward and requires few elements to be configured in the pom.xml as follows.

1. Configure repository location of the wagon-git plugin.


        
            synergian-repo
            https://raw.github.com/synergian/wagon-git/releases
        

2. Include the 'wagon-ssh' plugin extension configuration inside the 'build' element.


        
            
                org.apache.maven.wagon
                wagon-ssh
                2.8
            
        

3. Finally we need to include our ftp location using the 'distributionmanagement' element. During the build process artifacts will be uploaded in to following location.


        
            mvn-ftp-server
            sftp://ftp.aravinda-sites.com/my-ftp-repo
        

In order to use SFTP protocol maven settings.xml need to be updated with the ftp server access keys. Here the 'id' defined in the repository should match with the server id.


    
      mvn-ftp-server
      /Users/aravinda/.ssh/id_rsa
      passPhrase
  

Now you can execute,
'
mvn deploy

command to upload the artifacts.

Handling POST request using akka-http in a akka-actor system

Akka-htp is a well known module for providing full server side as well as client side http stack currently supporting Scala and Java langua...