AWS: Part I— Deploy Kotlin Spring Boot Reactive App on Elastic Beanstalk

Sujit Kamthe
Being Professional
Published in
5 min readJan 1, 2021

Let’s build a sample application to learn about different AWS services.

The Practice Problem

For this, we will build a quiz application which will show list of quizzes on home page and on selection of a quiz will present the quiz questions with options to the user where they would be able to select an answer which will be validated on click of a submit button.

In the end we will show all the questions with their right answers and whether user did answer them correctly or not.

The tech stack

  • Backend — Kotlin, Spring Boot Reactive
  • Frontend — VueJS
  • Database — AWS RDS

The beginning

To begin with, we will start with a simple REST API in Spring Boot Reactive to return list of Quizzes. For now we will not fetch data from the database, but will use in memory hard-coded data.

In subsequent articles, we will extend our solution to slowly build and integrate UI and database.

quiz-service

Let’s bootstraps the spring boot app from: https://start.spring.io/

We will use gradle as the build tool, Kotlin as the programming language, and the latest stable version of spring boot.

Select jar as packaging and the JDK version. I am using JDK 8.

Add Spring Reactive Web and Spring Boot Actuator dependency.

Open the project in Intellij / any other IDE and build it.

GET /quizzes

Let’s begin with a test for QuizService.

QuizServiceTest.java

package com.sujit.quiz.serviceimport com.sujit.quiz.domain.Quiz
import org.junit.jupiter.api.Test
import reactor.test.StepVerifier
class QuizServiceTest { @Test
fun `it Should return all quizzes`() {
val quizService = QuizService()
val quizzes = quizService.getAllQuizzes()
val expected = listOf(
Quiz("Kotlin Quiz", "Quiz about Kotlin"),
Quiz("Scala Quiz", "Quiz about Scala")
)
StepVerifier.create(quizzes).expectNextSequence(expected)
}
}

QuizService.java

package com.sujit.quiz.serviceimport com.sujit.quiz.domain.Quiz
import org.springframework.stereotype.Service
import reactor.core.publisher.Flux
@Service
class QuizService {
fun getAllQuizzes(): Flux<Quiz> {
return Flux.fromIterable(listOf(
Quiz("Kotlin Quiz", "Quiz about Kotlin"),
Quiz("Scala Quiz", "Quiz about Scala")
))
}
}

QuizControllerTest.java

package com.sujit.quiz.controllerimport com.sujit.quiz.domain.Quiz
import com.sujit.quiz.service.QuizService
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Test
import reactor.core.publisher.Flux
import reactor.test.StepVerifier
class QuizControllerTest { @Test
fun `it Should return all quizzes`() {
val quizService = mockk<QuizService>()
val quizController = QuizController(quizService)
val expected = listOf(
Quiz("Kotlin Quiz", "Quiz about Kotlin"),
Quiz("Scala Quiz", "Quiz about Scala")
)
every { quizService.getAllQuizzes() } returns Flux.fromIterable(expected) val quizzes = quizController.getAllQuizzes() StepVerifier.create(quizzes).expectNextSequence(expected)
}
}

QuizController.java

package com.sujit.quiz.controllerimport com.sujit.quiz.domain.Quiz
import com.sujit.quiz.service.QuizService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
@RestController
class
QuizController(private val quizService: QuizService) {
@GetMapping("/quizzes")
fun getAllQuizzes(): Flux<Quiz> {
return quizService.getAllQuizzes()
}
}

Run QuizApplication and hit http://localhost:8080/quizzes in browser. It should return the hard coded list of quizzes.

Response of GET /quizzes

Deploy to Elastic Beanstalk

Our first REST API is ready. Let’s manually deploy our application on the AWS Elastic Beanstalk.

1. Build the runnable jar

Run ./gradlew bootJar in project home directory. The runnable Jar would be generated at path build/libs/quiz-0.0.1-SNAPSHOT.jar in the project directory. We will use this file to manually crate an Elastic Beanstalk application.

2. Create a new Elastic Beanstalk application

2.1 Create Elastic Beanstalk application

Go to AWS management console and select Elastic Beanstalk. Click on Create application.

  • Enter Application Name
  • Enter appropriate tags
  • Select Java as platform
  • Select Java 8 running 64bit Amazon Linux as platform branch.
  • Select the recommended version of the platform.
  • In source code origin, upload the runnable jar file we generated earlier.

Note: We need to do additional configurations to be able to successfully deploy and access the quiz service. If you create application at this stage without configuring some of the settings we are going to see next, the application might not be accessible and you might see a standard nginx error page: 502 Bad Gateway

This happens because the application load balancer by default points to the Port 80 of the nginx server in EC2 instance. The nginx is configured to forward requests to Port 5000 by default, whereas out application server runs on Port 8080.

Wrong nginx configuration causing bad gateway
Expected correct configuration of nginx

This can be achieved by configuring an Environment Property named PORT pointing to 8080, while creating the beanstalk application.

Refer: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-se-nginx.html

2.2 Configure More Options

  1. Edit software configuration

Edit software configuration and add an Environment Property named PORT and point it to the port on which the application server is running (8080).

Add PORT environment property and set it to the port of application server

Click on Save and Create Application.

It will take some time to elastic beanstalk to create the environment.

Creating the quiz-service beanstalk environment

After some time the environment will be created successfully

2.3 Hit the environment URL

Check the health of the service by hitting /actuator/health on the environment url

e.g. http://quizservice-env-1.eba-5b72tmpp.ap-south-1.elasticbeanstalk.com/ is the quiz-service of our environment

health actuator endpoint on the elastic beanstalk environment url return UP

2.4. Test the /quizzes endpoint

/quizzes api returns the data

Next Steps…

In this article we created a micro service using Spring Boot Reactive Web and Kotlin and successfully deployed it on Elastic Beanstalk environment on AWS.

In the next article (https://medium.com/beingprofessional/aws-part-ii-deploy-kotlin-spring-boot-reactive-app-on-elastic-beanstalk-using-codepipeline-dec01267db6a) we will create a CodePipeline to automate the build and deployment of the quiz-service on the elastic beanstalk.

--

--