Skip to content

javaplus/PizzaApisKata

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

74 Commits
 
 
 
 

Repository files navigation

SpringBoot and AWS CodePipeline Kata

In this session, you will implement REST Api's using SpringBoot and deploy it as an AWS Elastic Beanstalk application. You will then build a continuous deployment pipeline that allows code checked into GitHub to be automatically tested, packaged, and deployed using an AWS CodePipeline.

We provide many step-by-step instructions for the AWS parts, but more general guidance on the SpringBoot development. However, there are many links to SpringBoot documentation, tutorials, and sample code. You can choose how far you want to go with the SpringBoot development, but the core of this tutorial will introduce you to SpringBoot and then how to set up the code pipeline.

Prerequsites:

  1. Java development Kit (JDK 8) - Download here
  2. Maven 3.x - Download Maven here
  3. An IDE or Text Editor (Use your favorite). Some options if you don't have one: SpringSource Tool Suite - Eclipse based or Visual Studio Code
  4. AWS Account. If you are part of the Learnathon, just sign into the nwmicroservices account. If you are not part of the Learnathon, you need to sign up for an AWS account. The Free tier is should suffice, but you will have to enter a credit card number if you don't have an account already. AWS

The GOAL

The goal is to implement the following OAS/Swagger using SpringBoot RestControllers.: PizzaShop OAS

The data you return can all be mocked if need be as the goal is not necessarily to have a completely working application, but understanding how to work with SpringBoot, RestControllers, and then how to deploy to AWS using CodePipeline.

Getting started

create a starter project

Start by creating a SpringBoot application. Using the Spring Initializr(https://start.spring.io/) is a good way to start. In the Spring Initiliazr, under Search for dependencies be sure to search for and add the Web (SpringMVC) dependency and optionally I'd add Lombok for convenience.

Spring Initializr Picture (Click Here for Screenshot)

After downloading and unziping the starter application, you can attempt to run it by using the following command:

mvn spring-boot:run

This utilizes the spring boot maven plugin

NOTE: By default, Spring Boot using port 8080 to run. So, be sure that port is free.

Creating Your First Rest Controller

You can start by building a simple class annotated with RestController that will be entry point to your application for your Pizza apis. This will have to be a new class that you create.

This will require creating a method that is annotated with the RequestMapping annotation to map an HTTP request to your method. This method could just return a hard coded string to get started with.

Spring RestController class (Click Here to see the simple RestController) **Spoiler Alert**

Helpful Links:

RESTController Tutorial

RequestMapping Tutorial

Test your application

Once you've created your first RestController and RequestMapping to a method, you can run it using the mvn spring-boot:run command or from inside your STS IDE with a right click and Run As->Spring Boot App. Either way, you'll then need to use PostMan, CURL, or some other tool to submit the appropriate HTTP request to your endpoint. Your endpoint should be something like this by default http://localhost:8080/pizzas. Of course, this URL can change depending on how you define your RequestMapping. NOTE: For this first simple GET Request, you can just use your browser to invoke it.

Simple Browser Test Screenshot

Package your application For Deployment

When your first service is tested you can go ahead and attempt to package it and deploy to AWS. To package with maven simply run the following command:

mvn clean package

This will build the application, run any tests, and package it as a fat jar. Spring's Jar Description

This will create a target folder and in that folder you will find your jar. You can test the jar locally by running the following command from the target folder:

java -jar pizza-shop-api-0.0.1-SNAPSHOT.jar

You may have to change the command to specify your jar name.

Going to the Cloud

Create Elastic Beanstalk Application

We will now just have Amazon run our jar using Elastic Beanstalk. To do this, sign into Amazon and go to "Services". Then under "Compute", choose Elastic Beanstalk.

Start the process to create an Elastic Beanstalk instance by clicking the Create New Application link in the top right. The application name can be anything, but since we are in a shared environment, it may be useful to prefix it with your initials. You will have to create an environment. To do this click the Create one now link. Choose a Web Server Environment.

You can add a Domain name to customize your url. Again you may want to prefix it with your initials or make sure it will be unique.

Be sure to set the Platform as Java and choose to Upload your code. Browse to the jar in your target folder choose it to upload. Then click the Upload button at the bottom. STOP! Do not click on the Create button yet! You need to make sure you Configure more options before continuing. See the Screenshot below. It may take a few minutes for the jar to be uploaded. But once it is uploaded, you will be returned back to the previous screen. Choose "Configure more options" before you create the application.

Elastic Beanstalk Creation - Click to see Screenshot

From the Configuration screen, under the Network box click modify. Then add a VPC and select to add a public IP address. You will have to select a region as well.

Elastic VPC Setup - Click to see Screenshot

Once you've selected the jar, modified the network, go ahead and create the application by clicking Create Environment. This will take a few minutes.

Testing in the cloud

Once your app is up and running the Elastic Beanstalk, it should show the URL at the top of the EB Dashboard page.
Remember that your application is running on port 8080. But you'll find out even if you use the new url with the port of 8080 it still won't be reachable. This is because traffic on port 8080 is not allowed through by default. You need to open the port to allow traffic through on port 8080.

Allow traffic on port 8080

To allow traffic through on a specific port address, you need to edit your VPC Security Groups settings.
To do this, on AWS, go to Services, then under Networking and Content Delivery, go to VPC.

On the VPC Dashboard, under Security, click on Security Groups. Check the box next to your Elastic Beanstalk environment at the top and then at the bottom go to the Inbound Rules tab. Click Edit and then Add another rule.

Set the Type to Custom TCP Rule, Set the Port Range to 8080 and the Source to 0.0.0.0/0. Then click Save.

Custom TCP Rule - Click to see Screenshot

This should immediately allow you to test again and get a successful response. If you don't have the URL, just go back to Services->Elastic Beanstalk and your environment should show up. When you click it, you'll be taken to the Dashboard again and the URL will be at the top. Copy it or Right Click and open in a new Tab. Then add port the port and uri ':8080/pizzas' to the url to test.

Building the Code Pipeline

NOTE: This next section is all about creating a continuous Build and Deployment pipeline in AWS. There are quite a few steps to set this up the first time, but we walk you through them. However, if you are more interested in learning more about SpringBoot rather than AWS Code Pipelines, you may want to skip this section and go to the "But Wait there's more" Section near the end where you pick back up with SpringBoot. If you want to do the Code Pipeline, keep reading here...

Before we do anything else with our application code, we are going to create a continuous deployment pipeline using AWS CodePipeline. This will enable an automated way to take our code from source control, test it, build it, and then deploy it. This way, any future changes we make, we can commit the code to our repo and it will automatically be tested, built/packaged, and deployed.

Get to Git

In order for us to start our Code Pipeline, we first need to have the code somewhere that Amazon can access it. Create a Git repo on GitHub.com for your code. (This has to be on GitHub or some other internet facing Git repository in order for AWS to be able to get access to our code).

Basic Instructions for committing your app to GitHub If you don't have a lot of experience using Git or GitHub, feel free to reach out to me and I can walk you through these steps. You will need to have the Git tools installed. Git Install Page

Commit your code to your newly created GitHub.com repo.

Create S3 Bucket for Caching

Before we can create our CodePipeline, we need to create a place to cache our maven and build artifacts. To do this we will create an S3 bucket. So, under Services, go to Storage, then select S3, select Create bucket. Give it a name, something like yourinitials-build-cache.

S3 Bucket Creation - Click to see Screenshot

Start the CodePipeline

In AWS, go to Services, then under Developer Tools, select CodePipeline.

Click Create Pipeline then enter a Pipeline name (can be anything, maybe use YourInitials_PizzaApiPipeline). Under Source Provider choose Github. Click the Connect to GitHub button and use your GitHub credentials to log in. Once you login and Authorize aws-codesuite, choose the newly created Github repo with your code in it under Repository NOTE: The Repository and Branch input's look like text boxes, but they are actually drop downs that should list your repos and branches when you click in them. Set the Branch to master.

Source Location - Click to see Screenshot

Now click Next step.

Under Build provider select AWS CodeBuild, then select Create a new build project

CodeBuild project configuration

Under the AWS CodeBuild section, give a project name (e.g. BT_PizzaAPI_CodeBuild). Under Operating System choose Ubuntu. Runtime:Java, and Version:openjdk-8.

CodeBuild Setup Part 1 - Click to see Screenshot

Under Cache, in the Type drop down, we will have to leave this as No cache for now and then change it in a minute(Seems to be a bug in AWS that you cannot select your S3 bucket at this time. Leave the Create a service role in your account selected and the default Role name should be fine. Leave the other defaults and click the Save build project button at the bottom.

CodeBuild Setup Part 2 - Click to see Screenshot

This should create the build project and take you back to the Create pipeline wizard(NOTE:It may take a few seconds). Before we continue with the pipeline setup, let's set up our Code Build cache.

CodeBuild Setup Part 1 - Click to see Screenshot

Click on the View project details under the CodeBuild project name. This should launch a new tab with your CodeBuild information. Click the Edit project button and then under Cache change the Type to Amazon S3. Select your bucket from the the Bucket drop down. You can leave the Path prefix blank or choose to set it to cache/archives (an AWS tutorial recommends this, but it works without).

CodeBuild Cache Setup - Click to see Screenshot

Now click the Update button to save the cache/S3 bucket changes to your CodeBuild, then close that tab.

Now you should be back on the Create pipeline wizard that is still on Select an existing build project and has your build project under Project name. Click the Next step button.

Setting the deployment provider

Under Deployment Provider select AWS Elastic Beanstalk and under Application name if you click there, it should have your EB application listed. Select it and then select your EB environment under Environment name. Now click Next step.

CodePipeline Deploy - Click to see Screenshot

For AWS Service Role, click the Create role button. This will open a new tab and populate some defaults for creating a new role. Under the Policy Name drop down choose any of the oneClick_AWS-CodePipeline-Service... policies. Then hit the Allow button at the bottom right. This should take you right back to the previous screen with the Role name populated. Just hit the Next step button. You can review your settings and hit Create pipeline.

NOTE: The build will fail and that's expected...

This should create the pipeline and cause it to run right away. However, the build step will fail because we told the CodeBuild process to look for a buildspec.yml file to tell it how to build the application. We must add that to our code base.

Adding a buildspec.yml

At the root of your workspace, (you can do this directly on Github.com) add a new file named buildspec.yml. Put the following lines in it:

version: 0.2

phases:
  build:
    commands:
      - echo Build started on `date`
      - mvn test
  post_build:
    commands:
      - echo Build completed on `date`
      - mvn package
artifacts:
  files:
    - target/pizza-shop-api-0.0.1-SNAPSHOT.jar

NOTE: The last line of your buildspec.yml may be different. The file name may need to be changed for you depending on how you named your project. Check the name of the jar file in your target directory.

Once you commit this file into your master branch, it should kick off your CodePipeline again. If you need to manually kick it off, you can go back to your CodePipeline (Services->Developer tools->CodePipeline) and select your CodePipeline, then select Release change and then click Release. This will force it to try to detect new changes and re-release.

Once this runs again, it should deploy your app again to Elastic Beanstalk. When this is done, test your application again, by going to the same URL you used before.

Make a change

Now that you have a CodePipeline set up, you can make more changes to the app and whenever they are committed to the Master branch, the change will be tested, built, and then deployed.

So, go ahead and just make a simple change to the return value of the method in your RestController. Commit this change and watch the CodePipeline run again and then when it's finished deploying check that your new functionality is up and running in EB.

If this works, you should dance a little. Because now you have a continuous build/deploy pipeline.

But wait there's more!!!

Now is when the fun really happens... ok... maybe that was already too much fun and you are done... that's perfectly fine. However, if you want to get better or learn more about implementing API's in SpringBoot, you can keep going.

However, this is where the guided tour ends... you are now free... no guard rails... explore, learn, create, do cool stuff...

Some suggestions... Implement some of the API's from the Swagger/OAS more fully.

  1. Return JSON from your RestController. (Hint don't work too hard on this... let the framework do the work). Create Classes that represent the types specified in the OAS/Swagger and return the classes.
  2. Figure out how to take a POST request as JSON and convert that to an object. Simple example here. Again, create classes that encapsulate the data coming in and use these classes as input arguments to your methods in your RestController.
  3. Put most of your logic in Service Classes and have spring inject them into your RestControllers.
  4. Create JUnit tests for your RestController. See tutorial here.
  5. Modify the CodeBuild to run when a Pull Request is created, so you can have your tests run on a Pull Request and update GitHub.

Good sample here I've created a small Spring Boot application here as an example. NOTE: This is not a spoiler. It's not the solution, but just another SpringBoot app that exposes REST APIs. My Sample Project for Reference This project has several RestControllers demonstrating different ways of taking input and returning JSON. Look at in the controllers folder for the RestControllers. There's also plenty of JUnit tests as well for reference.

More Helpful Links

Getting Started with Spring Boot

REST Service with Spring Boot

Spring Controller vs RestController

Detailed Spring Boot Rest Controller Tutorial

About

A kata for building REST Api's using SpringBoot

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published