AWS CDK Intro

During the last few years, we have been hearing about a lot of new practices applying to Software Development and DevOps. One of these topics is Infrastructure as Code. Probably, in this space, two of the most well-known solutions are Terraform and CloudFormation.

We have already discussed Terraform on this blog previously. If we take a look to the basic code on the example on this blog or you are already using it, probably, you are aware that when the infrastructure grows, the Terraform code, been quite verbose, grows fast too and, unless we have a very good code structure it can get very messy. The same can be said about CloudFomation. In addition, they are not as developer-friendly as common programming languages are and, they need to be learned as a new language.

To solve the first problem, code turning messing over time, there are some measures to split the Terraform code like creating modules but, for much of the projects I have been taken a look and articles I have read about it, it seems there is no agreement about the best way to split the code and, usually, if you do not work regularly with this kind of projects, it is very hard to find things and move around.

Trying to solve this problem and the second one, using languages well know by developers, there are projects like Pulumi trying to bring infrastructure code to use familiar programming languages and tools, including packaging and APIs.

Investigating a little bit about this, I have found another one, AWS Cloud Development Kit (AWS CDK), which is a software development framework for defining cloud infrastructure in code and provisioning it through AWS CloudFormation. As said, initially AWS CDK is designed for CloudFormation but, there is an implementation to generate Terraform code.

Today’s purpose is just to play a little bit with this technology, just the one that generates CloudFormation code and not to compare them (I do not know enough about it to compare them…yet).

I was going to write a long post with examples but, I have found a great introduction workshop offered by AWS that it does the job nicely. For this reason, I am just leaving here my project on Github.

One of the nice things I have found about AWS CDK is that support multiple languages:

  • Typescript
  • Javascript
  • Python
  • Java
  • C#

And, after writing a few lines, it feels very comfortable to be writing code using Java APIs and using all the power of the multiple tools that exist on the Java ecosystem. Ond, of course, be using Java packages to sort the infrastructure code.

Just another alternative in our toolbox that seems worth it to explore.

AWS CDK Intro

Spark + Freemarker basic example

Today, we are going to develop a little web page with a form using Spark and Freemarker. The purpose is simply to know how they are used together and how to manage GET and POST request. In addition, I am going to add Bootstrap to learn how to combine Freemarker with CSS.

As its web page describes “Spark – A tiny Sinatra inspired framework for creating web applications in Java 8 with minimal effort“. You can see a previous example I implemented in this blog called: Quick REST demo with Spark.

In the same way, as its web page describes “FreeMarker is a “template engine”; a generic tool to generate text output (anything from HTML to autogenerated source code) based on templates

The project has these requirements:

  • JDK 8
  • Maven
  • IDE. I have used IntelliJ IDEA CE, but you can use NetBeans, Eclipse or your favorite one.

The final structure for our project will be:

./pom.xml
./src/main/java/com/wordpress/binarycoders/SayMyName.java
./src/main/resources/css/bootstrap.css
./src/main/resources/templates/form.ftl
./src/main/resources/templates/result.ftl

The first step is to create a simple maven java project, obtaining in this way a pom.xml and a basic project structure. We should assign groupId, artifactId and version.

After that, we should edit our pom.xml file to add the dependencies that we are going to use to implement our example:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-core</artifactId>
    <version>2.1</version>
</dependency>
 
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.22</version>
</dependency>

As I have said at the beginning of this post, Freemarker is a template engine, then, the next step is to write the templates. We are going to write two templates:

  • form.ftl: This is going to be the first page of our application and it is going to show us a form to introduce “user” and “email“.
  • result.ftl: This page is going to show us the information introduced in the form.

The first template: form.ftl

<html>
    <head>
        <title>Welcome</title>
 
        <link href="css/bootstrap.css" rel="stylesheet" />
    </head>
    <body>
        <form class="form-inline" method="POST" action="/sait">
            <div class="form-group">
                <label for="name">Name</label>
                <input type="text"
                       class="form-control"
                       id="name"
                       name="name"
                       placeholder="John Doe">
            </div>
            <div class="form-group">
                <label for="email">Email</label>
                <input type="email"
                       class="form-control"
                       id="email"
                       name="email"
                       placeholder="john.doe@example.org">
            </div>
            <button type="submit" class="btn btn-default">Send invitation</button>
        </form>
    <body>
</html>

The second template: result.ftl

<html>
    <head>
        <title>Said</title>
    </head>
    <body>
        <h1> Your name is ${name}</h1>
        <br>
        <h1> Your email is ${email}</h1>
    </body>
</html>

It is very important to remember in this point that to be allowed to recover our form parameters in the Java code we need to add the name attribute to our inputs. It is not enough with the id attribute.

In this point, we should add Bootstrap CSS file to our project.

And finally, we need to implement our main class that it is going to process the GET and the POST requests.

package com.wordpress.binarycoders;
 
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import spark.Spark;
 
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
 
public class SayMyName {
 
    public static void main(String[] args) {
        final Configuration configuration = new Configuration(new Version(2, 3, 0));
        configuration.setClassForTemplateLoading(SayMyName.class, "/");
 
        Spark.get("/", (request, response) -> {
 
            StringWriter writer = new StringWriter();
 
            try {
                Template formTemplate = configuration.getTemplate("templates/form.ftl");
 
                formTemplate.process(null, writer);
            } catch (Exception e) {
                Spark.halt(500);
            }
 
            return writer;
        });
 
        Spark.post("/sait", (request, response) -> {
            StringWriter writer = new StringWriter();
 
            try {
                String name = request.queryParams("name") != null ? request.queryParams("name") : "anonymous";
                String email = request.queryParams("email") != null ? request.queryParams("email") : "unknown";
 
                Template resultTemplate = configuration.getTemplate("templates/result.ftl");
 
                Map<String, Object> map = new HashMap<>();
                map.put("name", name);
                map.put("email", email);
 
                resultTemplate.process(map, writer);
            } catch (Exception e) {
                Spark.halt(500);
            }
 
            return writer;
        });
    }
}

Now, we only need to run this main class and… that’s all. We can go to our browser and introduce the URL:

http://localhost:4567

We should see our form with our Bootstrap style. If we introduce a username and an email, and we submit the form, we will see in the next page two messages with our form data.

Probably, as you have notice, we have not needed a server and this is because the Spark framework have an embedded Jetty server.

See you.

Spark + Freemarker basic example

Quick REST demo with Spark

What is Spark? If we take a look to the project’s web page, it says something like “Spark is a simple and lightweight Java web framework built for rapid development“. In other words, it proposes us a simple way to build web applications without dealing with XML or annotations.

I recognize I do not usually use it but I have found it very useful when I need to prepare some REST services for a quick demo. Do not missunderstanding me, I think that use the Java EE platform is amazing and you can develop with it very fast, but you need a server, a couple of classes with the JAX-RS configuration and a few annotations to make everything work. With Spark, you only need to add a dependency in you .pom file and write a few lines of code.

For the example, I am going to implement a little application offering REST services with the CRUD operations for a User. This entity is going to have:

  • id
  • name
  • surname

In first place, we should create a java application in our favorite IDE using maven.

In second place, we are going to add the correct maven dependency for the Spark library.

<dependencies>
    <dependency>
        <groupId>com.sparkjava</groupId>
        <artifactId>spark-core</artifactId>
        <version>2.1</version>
    </dependency>
</dependencies>

In third place, we should create our entity object.

public class User {
    private String id;
    private String name;
    private String surname;
     
    // Getters and setters
}

Now, we need to start to write our main class. In this main class we are going to add a couple of things:

  • A Map to simulate our data store.
  • A main method that it is going to contain our REST services.

The main class looks like:

public class Users {
    private static Map<String, User> users = new HashMap<String, User>();
 
    public static void main(String[] args) {
        final Random random = new Random();
         
        // Services here
    }
}

Now, we are going to start with the services.

/users?name=Foo&surname=Bar (POST)

Spark.post("/users", (request, response) -> {
    String name = request.queryParams("name");
    String surname = request.queryParams("surname");
 
    User user = new User(name, surname);
    int id = random.nextInt(Integer.MAX_VALUE);
     
    users.put(String.valueOf(id), user);
 
    response.status(201); // 201 Created
     
    return id;
});

/users/:id (GET)

Spark.get("/users/:id", (request, response) -> {
    User user = users.get(request.params(":id"));
    if (user != null) {
        return "Name: " + user.getName() + ", Surname: " + user.getSurname();
    } else {
        response.status(404); // 404 Not found
        return "User not found.";
    }
});

/users/:id (PUT)

Spark.put("/users/:id", (request, response) -> {
    String id = request.params(":id");
    User user = users.get(id);
    if (user != null) {
        String newName = request.queryParams("name");
        String newSurname = request.queryParams("surname");
        if (newName != null) {
            user.setName(newName);
        }
        if (newSurname != null) {
            user.setSurname(newSurname);
        }
        return "User with id '" + id + "' has been updated.";
    } else {
        response.status(404); // 404 Not found
        return "User not found.";
    }
});

/users/:id (DELETE)

Spark.delete("/users/:id", (request, response) -> {
    String id = request.params(":id");
 
    User user = users.remove(id);
 
    if (user != null) {
        return "User with id '" + id + "'has been deleted";
    } else {
        response.status(404); // 404 Not found
        return "User not found.";
    }
});

/users (GET)

Spark.get("/users", (request, response) -> {
    String ids = "";
 
    for (String id : users.keySet()) {
        ids += id + " ";
    }
     
    return ids;
});

Now, we only need to execute our application and check if everything is working correctly. To do this, we can use cURL or our browser with the URL:

http://localhost:4567/users

The next steps are on you. Implement a front-end with Javascript or consuming the services with a mobile app or… whatever you prefer.

See you.

Quick REST demo with Spark