Setting up Localstack and creating SQS Queues and SNS Topics

What is Localstack?
Localstack is a fully functional local AWS cloud stack which enables you to develop and test your cloud apps offline! In this post I will teach you how to install it, and how to create SQS Queues and SNS Topics that reside on localstack.

How do we install Localstack?
We can install localstack by running this command on our terminal:
pip install localstack

If you don't want to install the prerequisites needed to run localstack, we can use docker to pull localstack without manually installing the dependencies ourselves. This will save us a lot of time and hair! Just pull the localstack repository from github!
git clone https://github.com/localstack/localstack.git

How do we run Localstack?
To run localstack, just enter this command on the terminal:
localstack start
If you went with docker, we can use this command:
cd path/to/localstack
docker-compose up
Wait for the word "ready", that's when you know that it's up and running.
Starting localstack_localstack_1 ... 
Starting localstack_localstack_1 ... done
Attaching to localstack_localstack_1
localstack_1  | 2018-11-16 08:35:13,572 CRIT Supervisor running as root (no user in config file)
localstack_1  | 2018-11-16 08:35:13,597 INFO supervisord started with pid 1
localstack_1  | 2018-11-16 08:35:14,600 INFO spawned: 'dashboard' with pid 11
localstack_1  | 2018-11-16 08:35:14,602 INFO spawned: 'infra' with pid 12
localstack_1  | (. .venv/bin/activate; bin/localstack web)
localstack_1  | (. .venv/bin/activate; exec bin/localstack start)
localstack_1  | 2018-11-16 08:35:15,632 INFO success: dashboard entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
localstack_1  | 2018-11-16 08:35:15,633 INFO success: infra entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
localstack_1  | Starting local dev environment. CTRL-C to quit.
localstack_1  | 2018-11-16T08:35:21:INFO:werkzeug:  * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
localstack_1  | 2018-11-16T08:35:21:INFO:werkzeug:  * Restarting with stat
localstack_1  | 2018-11-16T08:35:22:WARNING:werkzeug:  * Debugger is active!
localstack_1  | 2018-11-16T08:35:22:INFO:werkzeug:  * Debugger PIN: 228-822-518
localstack_1  | Starting mock API Gateway (http port 4567)...
localstack_1  | Starting mock DynamoDB (http port 4569)...
localstack_1  | Starting mock SES (http port 4579)...
localstack_1  | Starting mock Kinesis (http port 4568)...
localstack_1  | Starting mock Redshift (http port 4577)...
localstack_1  | Starting mock S3 (http port 4572)...
localstack_1  | Starting mock CloudWatch (http port 4582)...
localstack_1  | Starting mock CloudFormation (http port 4581)...
localstack_1  | Starting mock SSM (http port 4583)...
localstack_1  | Starting mock SQS (http port 4576)...
localstack_1  | Starting mock Secrets Manager (http port 4584)...
localstack_1  | Starting local Elasticsearch (http port 4571)...
localstack_1  | Starting mock SNS (http port 4575)...
localstack_1  | Starting mock DynamoDB Streams service (http port 4570)...
localstack_1  | Starting mock Firehose service (http port 4573)...
localstack_1  | Starting mock Route53 (http port 4580)...
localstack_1  | Starting mock ES service (http port 4578)...
localstack_1  | Starting mock Lambda service (http port 4574)...
localstack_1  | Ready.

How do we run Localstack on a different port?
As you will see above, when localstack is running it will try to use port 8080. It's a pretty common port for most apps, and we might not want to run it on that port. So how do we run it with a different port you ask? Well, let's say you want to run it on port 9182, just use this command:
PORT_WEB_UI=9182 docker-compose up

How do we create aws resources with localstack?
Creating an aws resource with localstack is very easy. All you have to do is refer to AWS CLI documentation and use the --endpoint-url option. So in this post, we'll try to create an SQS queue and subscribe to a topic. Take note, that the resources we'll be creating will not be created on AWS, you will not see them on your AWS console/website, it will just reside on your local machine. Also, whenever you close localstack, the resources will get deleted, so you'll have to recreate them again each run.

Create SQS queue
Below is the command to create an SQS queue. Notice how we used http://localhost:4576 as the endpoint-url? If you don't know what port to use, you can refer to the logs that localstack outputs each time it runs. It lists the service and ports there. Isn't it great?
aws --endpoint-url=http://localhost:4576 sqs create-queue --queue-name my-queue-001

Create SNS Topic
To create an SNS topic, we'll have to use the command below. Similar to the command above, we used http://localhost:4575 to indicate that the resource should be created in localstack.
aws --endpoint-url=http://localhost:4575 sns create-topic --name my-topic-name

Subscribing a queue to our topic
Finally, to subscribe a queue to our topic, we'll have to use this command:
aws --endpoint-url=http://localhost:4575 sns subscribe --topic-arn arn:aws:sns:us-east-1:123456789012:my-topic-name --protocol sqs --notification-endpoint http://localhost:4576/queue/my-queue-001

As you can see, using localstack is very convenient and easy, what's even better is you can save on cost. Instead of testing stuff on your actual aws account, you can test it locally with localstack.

Creating your own Annotation in Java and Testing them with Spock

Creating your own annotation in Java is really simple. Let's create one example. Say, we want to have a String that we are going to transform into a LocalDate and we want to make sure that String is set in the future. Let's call our annotation DateStringOnFutureConstraintAnnotation. It will take in a valid pattern, and a message that we will display if the date happens to be invalid. Our annotation will look like this when applied to a String.
@DateStringOnFutureConstraintAnnotation(
    pattern = "yyyy-MM-d",
    message = "Invalid expiry date. Please make sure it's set in the future."
)
private String expiryDate;

Next we will need an interface that will define our annotation. Notice that this interface will not contain any logic. The logic will be placed in another class, and in order to let the interface know which logic it should use, we will have to define that with @Constraint(validatedBy = OurValidator.class). In this case our validator will be DateStringOnFutureValidator.
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({ElementType.FIELD, 
        ElementType.METHOD, 
        ElementType.PARAMETER, 
        ElementType.ANNOTATION_TYPE 
})
@Retention(RUNTIME)
@Constraint(validatedBy = DateStringOnFutureValidator.class)
@Documented
public @interface DateStringOnFutureConstraintAnnotation {
    String message() default "Invalid date. Date should be set on the future.";

    Class[] groups() default { };

    Class[] payload() default { };

    String pattern();
}

We don't really have to test this interface since it doesn't really contain any logic. Next we will have to define our validator: DateStringOnFutureValidator which implements ConstraintValidator. We will have to override the initialize method and isValid method for this. The initialize method will take the value of the pattern from our annotation, so that we could use it in our isValid method. For our is valid method, we will return true:
* if the date is blank or null
* if the date has a valid format and the value is set in the future.
Otherwise we will be returning false. Below is the sample code of what we want to achieve above.
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class DateStringOnFutureValidator implements ConstraintValidator {
    private String pattern;

    @Override
    public void initialize(
            DateStringOnFutureConstraintAnnotation constraintAnnotation) {
        this.pattern = constraintAnnotation.pattern();
    }

    @Override
    public boolean isValid(String dateString, ConstraintValidatorContext context) {
        if (dateString == null || dateString.trim().length() == 0) {
            return true;
        }

        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
            LocalDate dateValue = LocalDate.parse(dateString, formatter);
            return dateValue.isAfter(LocalDate.now());
        } catch (DateTimeParseException e) {
            return false;
        }
    }
}

So, how do we test this Validator on spock? All we have to do is create a new instance of DateStringOnFutureValidator and Mock ConstraintValidatorContext like so:
DateStringOnFutureValidator validator = new DateStringOnFutureValidator()
ConstraintValidatorContext constraintValidatorContext = Mock(ConstraintValidatorContext)
Once we've done that setup, we can use it in our tests. Here is an example:
import spock.lang.Specification
import spock.lang.Unroll

import javax.validation.ConstraintValidatorContext
import java.time.LocalDate;

class DateStringOnFutureValidatorSpec extends Specification {

    DateStringOnFutureValidator validator = new DateStringOnFutureValidator()
    ConstraintValidatorContext constraintValidatorContext = Mock(ConstraintValidatorContext)

    def "validate should return false if the dateString is not set in the future."() {
        given:
        DateStringOnFutureConstraintAnnotation constraintAnnotation = Mock()
        constraintAnnotation.pattern() >> "yyyy-MM-d"
        String yesterday = LocalDate.now().minusDays(1).toString()

        when:
        validator.initialize(constraintAnnotation)
        boolean result = validator.isValid(yesterday, constraintValidatorContext)

        then:
        assert !result
    }

    def "validate should return true if the dateString is set in the future."() {
        given:
        DateStringOnFutureConstraintAnnotation constraintAnnotation = Mock()
        constraintAnnotation.pattern() >> "yyyy-MM-d"
        String yesterday = LocalDate.now().plusDays(1).toString()

        when:
        validator.initialize(constraintAnnotation)
        boolean result = validator.isValid(yesterday, constraintValidatorContext)

        then:
        assert result
    }


    @Unroll
    def "validate should return true if the dateString is #condition ."() {
        given:
        DateStringOnFutureConstraintAnnotation constraintAnnotation = Mock()
        constraintAnnotation.pattern() >> "yyyy-MM-d"

        when:
        validator.initialize(constraintAnnotation)
        boolean result = validator.isValid(dateValue, constraintValidatorContext)

        then:
        assert result

        where:
        condition   | dateValue
        "null"      | null
        "blank"     | ""
        "space"     | " "
    }
}
See! It's very easy and intuitive. Once all these steps are done, we can now use the new annotation we just created.

Running Groovy Files with Gradle

How do you run groovy files with gradle?

Running groovy files in gradle is very easy. Here is a complete example.
For this tutorial you will need the following:

* Gradle 3.4.1
* Groovy 2.4.7
* Java 8 or higher

First we will need to create the groovy file that we will execute. In our example, let's call it MyMainClass.groovy. In this file we're just printing a basic hello world example.
Then we will need a build.gradle file. In this file, we will have to define our dependencies. Next, we have defined a task called execute. This task will call main.groovy.MyMainClass when run.
To run the script, we can do this in the terminal:

That's it! You should be able to see hello world on the terminal!


Saigon Day 1: Discovering the Cu Chi Tunnels

After walking around Saigon and seeing the usual tourist spots for half a day, we went next to the Cu Chi Tunnels. I'm not sure if anyone can just go there without booking a tour, but for convenience, we booked a half day tour through the Singh Tourist. The tour cost us around 84,000 VND per person. Pretty cheap if you ask me.

The receipt we got after online registration. Don't forget to bring this if you plan to go there.

The tour starts at 1pm, and we had to be at their office, in De Tham street, 30 minutes ahead to confirm our booking. When we arrived at their office, we were not the only guests around. There were other people joining the tour too. I could say that the total number of people could fill an entire bus. We got what we paid for, I guess!

Vietnam's country side.

So, they boarded us into this big bus and it vroomed its way towards the outskirts of the city for what seemed like hours. What they didn't tell us was that we had to stop by a local lacquerware factory. Our tour guide, Tony, said that the people who work in the factory were disabled, and buying their products is one way of supporting them. When we went inside the shop, we didn't see any disabled people, but we did see their works, which were god damn pretty to be honest! We bought cute Saigon doll magnets for 84,000 VND.

Can you believe that the decorations on this tray is made of egg shells?

Arriving at the Cu Chi Tunnels

After touring the factory, we headed back to the bus. It was long ride, I was relieved when we finally arrived at our destination. Our guide's english was so-so, but there were times when I never understood what he said. Our tour started with the traps used by Viet Cong during the war. These traps were used for hunting at first, but when the war broke out, the Viet Cong used it on the Americans. They sharpened bamboo shoots and used them as stakes. They also filled the traps with human excrement to infect the victims faster. Yikes!



He also talked about the architecture of the tunnels. The Cu Chi tunnels are just part of a large interconnecting tunnel under Vietnam. I think I heard our guide said the tunnel goes as far as the border of Cambodia. The government has preserved the tunnels and even expanded some of them to fit the physique of most western tourists. We even got a chance to go inside!



Oh! They also have a firing range where gun lovers can fire an AK47 and a machine gun. I'm no gun lover, so I never even dared to enter the range. I just looked around the souvenir shop and ate ice cream. At the very end of the trip, we watched a short film about the Cu Chi tunnels. It was little bit hard to understand, not just because of the narrator's accent, but also because the video was very old. Can you imagine? It was in gray scale! In my honest opinion, they have to update that film. Maybe improve the sound quality a bit so that it's audible? With that said, I'll leave you a picture of a diorama of soldiers.


It was around 5pm when we finished the tour and by 6pm we were back in Pham Ngu Lao. I really enjoyed my trip in the Cu Chi tunnels. It was very insightful and something that I don't get to see everyday. Do you want to read more about my adventures in Ho Chi Minh? Click here to read about our day 2 trip. Did you miss part one of our trip? Read about it here! :)

Saigon Day 1: Touring the City on Foot, and Discovering the Cu Chi Tunnels


For our first stop in 2015, my friends and I went to Ho Chi Minh City (formerly known as Saigon). Ho Chi Minh is the capital city of Vietnam, a well known country for budget travellers and the world famous Pho. In this post, I will tell you what happened on our first day, where we went, what we did and how much it cost.

We spent two nights in a humble hostel in the Pham Ngu Lao area. The name of our hostel was Phan Lan 2 hostel. We rented a double room for only 23 usd per night. Click here for a review of the hostel itself.



On our first day, we went around the city on foot. It wasn't very difficult to go around Saigon. The streets were lined with trees which gave shade to pedestrians. There were spacious foot paths and flowers were in full bloom as they surround huge parks. I originally thought it would be hot as fuck, but nope, the trees provided ample amount of shade from the sun and the wind gave us enough breeze that I felt so cool while walking. I never felt my pits sweat. Never!


The grass is greener in Saigon.

Notre dame cathedral (Nhà thờ Đức Bà Sài Gòn)

First stop is the Notre dame cathedral (Nhà thờ Đức Bà Sài Gòn). This cathedral was established by the French between 1863 and 1880. The neo-romanesque style attract locals and tourists alike. This iconic basilica made me feel like I was strolling in the streets of France. Unfortunately, we were not able to go inside. I don't think they let people in, but I do know the basilica holds mass every sunday.



Post Office (Bưu điện Việt Nam)

Right next to the Basilica, is the Post Office. It was built built between 1886 and 1891 by renowned architect Gustave Eiffel, the same guy whose company built the Eiffel Tower. The architecture looks so grand, and so beautiful, I wouldn't think I'm on Asia. When we stepped inside, I felt like we traveled back in time, for it looked like a train station, the only thing missing was the train! The walls decorated with hand made paintings of maps. They also have a number of phone booths and a lot of post cards for sale.



War Remnants Museum (Bảo tàng chứng tích chiến tranh)

The War Remnants Museum exhibits a range of information about the wars that have ravaged Vietnam over the years. They even have a display of military equipment such as tanks, helicopters, fighter jets and bombs. Inside the building, you will find dioramas of what prison cells looked like back then, there are artworks, and several exhibits with captions both in Vietnamese and English. It's a good read about Vietnam's history, though some of it are a bit one sided and may cross the realm of propaganda. If you want an unbiased story, read up about Vietnam's history before hitting the Museum.




Bến Thành Market

Bến Thành Market is large marketplace found at the heart of Ho Chi Minh City. You can find all sorts of stuff here: food, clothing, watches, meat, spices, bags, alcohol etc. At night, the Market closes and vendors start putting up their stalls on the surrounding streets, kinda like a night market! Most of the stuff you will find are most likely overpriced, so try your best to haggle at least half the price! It's not rude to haggle, it's expected.



Another tip, don't go around asking for the price of something that you don't intend to buy. One of my friends made the mistake of asking how much a magnet was, and the vendor just wouldn't let her go until she bought the item. So if you don't want to be trapped, don't ask and just politely turn down any point of conversation unless you are sure you really want to buy that thing.



End

That wraps up our walking tour for this trip! There are a lot of other places you can visit in Ho Chi Minh on foot. Unfortunately, we only had half a day to spend for exploring the city. The other half, we spent on a trip to the Cu Chi Tunnels (Read about our Cu Chi Tunnel adventure here).

Ten Vietnamese Dishes for the Meatlover in you!

In this list, I will show you different Vietnamese cuisines that packs more meat into your meals! This will definitely fulfill your meaty cravings!

1. Sườn Nướng (Grilled Pork Ribs)
source: webnauan


2. Bo Luc Lac (Vietnamese Shaking Beef)
Bo means beef, and luc lac refers to the tossing motion of the wok, back and forth, as the chef sautes and sears the beef.
source: theravenouscouple
3. bò sốt tiêu đen (Pepper Steak)
source: foodvintage.wordpress.com
4. cánh gà chiên nước mắm (Chicken Wings in Sweet and Spicy Sweet Sauce)
source: benchef
5. Heo quay (Crispy Roasted Pork)
source: Helen's Recipes
6. bạch tuộc nướng (Grilled Octopus)
source: bunnyforver.wordpress.com
7. Chao Tom (Grilled Shrimp on Sugarcane)
source: skyscrapercity
8. Thit heo kho (Pork and Eggs Simmered with Coconut Juice )
source: tintuc.vatgia.com
9. Cánh gà nướng sả kiểu (Grilled Chicken with Lemon Grass)
source: eva.vn
10. Nem nướng (Grilled Pork Meatballs)
source: vaobepnauan

Macau Adventure: A Slice of Portugal in Asia

On our second day in Hong Kong, we decided to visit Macau since it's just one ferry ride from the city. One turbojet ferry ticket (Economy class) from Hong Kong to Macau cost us HKD159.00. The return ticket costs cheaper though. The fare matrix can be found on TurboJet's official website.

When we arrived at the Macau ferry terminal, we already had an idea of where to go. Unfortunately, one of the our colleagues asked a tour guide where to board the buses and he got an advertisement instead. The tour guide kept telling us that it was better if we booked a tour with her because Macau doesn't have an MTR, and all they have are buses, she on the other hand has a car that can take us all over the place. Plus, she was gonna give us a discount!

I declined several times because it wasn't part of our budget, but our colleagues still kept listening to the tour guide, and the tour guide kept lowering the price. From HKD1,600 she told us she was gonna give us a HKD600 discount and we only had to pay HKD1000. There were four of us, so that's HKD250 each. My colleagues told me it seemed like a good deal. I wasn't convinced, but I went along anyway since my feet were already sore from walking the streets of Hong Kong. Our tour guide's name is Rosa!

Senado Square, Macau
A Bit of History
The architecture of the buildings in Macau tells a lot about it's history. Macau became a colony of Portugal in 1557, and it was handed back to China in 1999. That's a REALLY long time! As a result, most of the buildings you'll see in Macau will resemble stuff that you see in the alleys of most European countries. Our first stop was Senado Square. It is one of the biggest squares in Macau.

St. Paul Ruins
Next, we were taken to the Ruins of St. Paul. Built from 1582 to 1602, it was once the largest church in Asia. But it was destroyed by a fire in the middle of a typhoon. Can you believe that? Now, only the facade remains. Right across the ruins are several shops that offer pastries, food, and souvenirs. I suggest you grab a bite of their egg tarts! They were delicious, I wanted to buy an entire box, but sadly all my budget went to the tour guide. lol.

One of the shops right across St. Paul Ruins.
Of course, before the Portuguese came, Macau was inhabited by the Chinese. Rosa took us to A-ma temple, one of the oldest taoist temple in Macau. When Portuguese sailors first came, they landed at the coast of A-ma temple. They asked the locals what is the name of the place, and the locals simply replied: "Maa Gok". Since then, the Portuguese have called the place Macau.

A tree surrounded by prayer cards.
Macau Tower, the tallest building in the city. They offer bungy jumping, but I don't want to end my life yet, so, no thanks. 
Gambling in Macau has been legal since 1850. That's why they have a LOT of casinos that attract foreigners from all corners of the world. Macau's economy relies highly on gambling. 40% of it's GDP is from gambling. To date, they have 33 casinos, the biggest of which is "the Venetian". Rosa took us to a lot of Casinos, but since none of us were gamblers, we simply stayed in the lobby, took pictures of whatever was interesting and stayed for a couple of minutes. My favorite was "The Venetian"!

I think the Grand Lisboa is the most horrible  building I have ever seen. Eh, but what do I know?
Fierce dragon sculpture hanging at the ceiling of Hard Rock Hotel.
Light show every 2:30 pm in the Lobby of Galaxy Casino.
The Venetian is the biggest Casino in Macau, and one of the things that really made me want to visit it is the Venice themed shopping strip. The attention to detail was a big visual treat for us! They had gondolas in the canals, and of course people can ride it and have the boat guy serenade them.




I find it quite refreshing that westerners are hired to serenade on the gondola. It makes the entire setup surreal.
I enjoyed my one day stay in Macau! It was a very a informative trip; a true delight both for the eyes and the brain. Getting the tour guide was a good deal in the end because some of those venues never came up on my searches, and the entire city was REALLY hot! Kudos to Rosa for being a wonderful host! I think Macau deserves a trip of it's own, and I meant actually staying there for a couple of days. I'd love to see the skyline at night!