Wednesday, May 20, 2015

Develop RESTFul services using Dropwizard Java framework


This document will guide you through the process of creating a simple Dropwizard project: Hello World.

Overview:

Dropwizard is a Java framework for developing ops-friendly, high-performance, RESTful web services. This framework bundles with Jetty for http sever, Jersey for REST and Jackson for JSON mapping. It offers some additional few other additional features like Metrics.

Setting up Maven:

I recommend you use Maven for new Dropwizard applications. Current version of Dropwizard 0.8.1.

<dependency>
  <groupId>io.dropwizard</groupId>
  <artifactId>dropwizard-core</artifactId>
  <version>0.8.0</version>
</dependency>

Creating A Configuration Class

Each Dropwizard application has its own subclass of the Configuration class which specifies environment-specific parameters. These parameters are specified in a YAML configuration file which is deserialized to an instance of your application’s configuration class and validated

import io.dropwizard.Configuration;
public class HelloWorldConfiguration extends Configuration {
// Add your own configuration variables
}

Creating a Representation class:

This class will be look like Model class and it designed for generating the JSON response. Representation class will be look like below.

import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.Length;
public class Saying {
    private long id;

    @Length(max = 3)
    private String content;
    public Saying() {
    }
    public Saying(long id, String content) {
        this.id = id;
        this.content = content;
    }
    @JsonProperty
    public long getId() {
        return id;
    }
    @JsonProperty
    public String getContent() {
        return content;
    }
}

Creating  Resource Class:

You need a resource which returns Saying instances from the URI /hello-world, so our resource class will look like this:

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.MediaType;

import model.Saying;
import java.util.concurrent.atomic.AtomicLong;
@Path("/hello-world")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
    private final AtomicLong counter;
    public HelloWorldResource() {
        this.counter = new AtomicLong();
    }
    @GET
    public Saying sayHello(@QueryParam("name") String name) {
        final String value = name;
        return new Saying(counter.incrementAndGet(), value);
    }
}

Creating An Application Class

Application going to be the Main class for your application. It will register your resource class. It will be look like below.

import configuration.HelloWorldConfiguration;
import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import resources.HelloWorldResource;
public class HelloWorldApplication extends Application<HelloWorldConfiguration> {
    public static void main(String[] args) throws Exception {
        new HelloWorldApplication().run(args);
    }
    @Override
    public String getName() {
        return "hello-world";
    }
    @Override
    public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
        // nothing to do yet
    }
    @Override
    public void run(HelloWorldConfiguration configuration,
                    Environment environment) {
                final HelloWorldResource resource = new HelloWorldResource();
                environment.jersey().register(resource);
    }
}

Create a YMAL file and place it your resource folder. It will be look like below

server:
#  softNofileLimit: 1000
#  hardNofileLimit: 1000
  applicationConnectors:
    - type: http
      port: 8085

# this requires the alpn-boot library on the JVM's boot classpath
#    - type: spdy3
#      port: 8445
#      keyStorePath: example.keystore
#      keyStorePassword: example
#      validateCerts: false
  adminConnectors:
    - type: http
      port: 8086

Finally the run the Application class which will have main method from your eclipse and pass the below parameters to your main class.


server <YML_file_path>

Wednesday, May 13, 2015

Apache Camel Framework and S3 Integration

In this blog, I am going to demonstrate how to integrate AWS S3 in your Java application using Apache Camel Framework.

Introduction about S3:

AWS S3 provides developers and IT teams with secure, durable, highly-scalable object storage. Amazon S3 is easy to use, with a simple web services interface to store and retrieve any amount of data from anywhere on the web. With Amazon S3, you pay only for the storage you actually use. There is no minimum fee and no setup cost.
In this section I will demonstrate how to upload and download to the AWS S3 bucker with the working code.

Refer my previous “Apache Camel Framework and SQS Integration” blog for the code execution environment setup. 

Upload file to S3 bucket:

The camel component for the S3 activity is aws-s3 and in this example I given bucket name as camelblogs3. All you need is Camel producer template object and File object. Camel S3 component will take care of rest. You don’t need to learn the AWS Java API’s to send files to S3 buckets.

AmazonS3 client = new AmazonS3Client( new DefaultAWSCredentialsProviderChain() ); 
client.setRegion( Region.getRegion(Regions.US_WEST_2));
SimpleRegistry registry = new SimpleRegistry();
registry.put("client", client);
CamelContext camelContext = new DefaultCamelContext(registry);
ProducerTemplate template = camelContext.createProducerTemplate();
File file = new File( "<INSERT_FILE_LOCATION>");
template.sendBodyAndHeader("aws-s3://camelblogs3?amazonS3Client=#client", file , S3Constants.KEY, file.getName());

Download file from S3 bucket:

Don’t remember to pass “deleteAfterRead=false” parameter in the Camel endpoint. 

AmazonS3 client = new AmazonS3Client( new DefaultAWSCredentialsProviderChain() ); 
client.setRegion( Region.getRegion(Regions.US_WEST_2));
SimpleRegistry registry = new SimpleRegistry();
registry.put("client", client);
CamelContext camelContext = new DefaultCamelContext(registry);
ConsumerTemplate consumer = camelContext.createConsumerTemplate();
S3ObjectInputStream s3inputStream = (S3ObjectInputStream)consumer.receiveBody("aws-s3://camelblogs3?amazonS3Client=#client&deleteAfterRead=false&fileName=hello.txt");
String outPutFile = "<INSER_FILE_LOCATION>";
FileWriter writer = new FileWriter(outPutFile);
String thisLine = "";
InputStream fileStream = new BufferedInputStream( s3inputStream);
BufferedReader buffered = new BufferedReader(new InputStreamReader(fileStream, "UTF-8"));
while ( (thisLine = buffered.readLine() ) != null ){
writer.write(thisLine+'\n');
}
writer.close();

Tuesday, May 12, 2015

Apache Camel Framework and SQS Integration

In this blog, I am going to demonstrate how to integrate AWS SQS in your Java application using Apache Camel Framework.

Little Introduction about Camel Framework:

Apache Camel is an open source Java framework that focuses on making integration easier. It's a complete production-ready framework for people who want to implement their solution to follow the Enterprise integration pattern. Camel will help you to:
1) Consume data from any source/format
2) Process this data
3) Output data to any source/format

In this section I will demonstrate how to send and receive message to the AWS SQS queue with the sample working code.

Follow below instructions to setup code execution environment.

1.  Download the latest Eclipse and install AWS SDK

      a) Open Help → Install New Software….
      b) Enter http://aws.amazon.com/eclipse in the text box labeled “Work with” at the top of the               dialog.
      c) Select “AWS Toolkit for Eclipse” from the list below.
      d) Click “Next.” Eclipse guides you through the remaining installation steps.

2.  Create a Maven project and update the pom.xml for camel library and log4j, 

3.  Create a SQS queue & setup IAM user and assign “AmazonSQSFullAccess” to the IAM user. Then generate the Access and Secret Key.

4. Update the Access Key or Secret Key in the Eclipse AWS Toolkit. For more details
http://docs.aws.amazon.com/AWSToolkitEclipse/latest/GettingStartedGuide/Welcome.html

Sending message to the SQS queue:

First you need a SQSClient object and then register it in the Camel Registry. ProducerTemplate will send message to Camel component. In this example aws-sqs is the camel component and camelblogs is the SQS queue name. Sample working code is below

AmazonSQS client = new AmazonSQSClient( new DefaultAWSCredentialsProviderChain() );  client.setRegion( Region.getRegion(Regions.US_WEST_2)); // Setting the Region, you can set your assigned regions
SimpleRegistry registry = new SimpleRegistry();
registry.put("client", client);       
CamelContext camelContext = new DefaultCamelContext(registry);
ProducerTemplate template = camelContext.createProducerTemplate();
camelContext.start();
String json = "{'message':'Hello World'}";
template.sendBody("aws-sqs://camelblogs?amazonSQSClient=#client", json );


Receive the Message from SQS:

While retrieving the message first you need to define the Camel router with aws-sqs end point and define the processor to process the message. Once you define the Camel router add them into the Camel Context. You can still define the routes using xml configuration. The below example just demonstrate without xml configuration.Sample working code below

AmazonSQS client = new AmazonSQSClient( new DefaultAWSCredentialsProviderChain() ); 
client.setRegion( Region.getRegion(Regions.US_WEST_2)); // Setting the Region, you can set your own selected regions
SimpleRegistry registry = new SimpleRegistry();
registry.put("client", client);
final Processor processor = new Processor(){
public void process(Exchange exchange) throws Exception {
                // TODO Auto-generated method stub
                System.out.println("Received message: " + exchange.getIn().getBody(String.class));
}
};
CamelContext camelContext = new DefaultCamelContext(registry);
camelContext.addRoutes(new RouteBuilder(){
@Override
public void configure() throws Exception {
                System.out.println("CamelContext routers about to add.");
                // TODO Auto-generated method stub
                from ("aws-sqs://camelblogs?amazonSQSClient=#client").process( processor);
}
});
camelContext.start();
System.out.println("CamelContext about to stop.");
Thread.sleep(30000);
camelContext.stop();

Debugging tips:

1) Enable the logger by creating the log4j.properties file in the resource folder.
2) Make sure that SQSClient object picks the Access and SecretKey using log statements
3) Make sure that you have set the AWS region for your sqs queue in the code.