Spring Boot Native/Reactive Microservice with OAuth2 and Quartz for ECS Fargate using AWS Copilot CLI.
- Author: Andres Solorzano.
- Level: Advanced.
- Technologies: Java 17, Spring Boot 3, Spring Native, Spring WebFlux, Spring OAuth2, Quartz, Flyway, AWS Copilot CLI, Testcontainers, Aurora Postgres, DynamoDB, Elastic Load Balancer (ELB), and Docker.
You can read the full article on my Medium Blog for more details.
This project uses the Spring Boot Framework to manage Quartz Jobs in a Spring Native microservice with the use of reactive programing using Spring WebFlux. The Quartz library is configured for clustered environments, so its needs the help of Postgres database to manage the cron Jobs execution. When a Job is executed, the calling method retrieves the Device item from DynamoDB to change its state. To perform these activities, the users must be logged into the OIDC Service that its deployed using the AWS Cognito service. All test cases using the TDD methodology from the beginning of the development phase, and only Integration Tests are executed with the support of Testcontainers because Unit Testing does not cover real world scenarios. This project also uses Docker Compose to deploy a local cluster alongside the other required services by the Spring Boot application.
Execute the following command to get your Cognito User Pool ID:
aws cognito-idp list-user-pools --max-results 10
Then, modify the utils/docker/compose/tasks-api-dev.env
file and replace the <cognito_user_pool_id>
with the corresponding one.
Now, you can execute the following command from the project's root directory to deploy the Docker cluster locally:
docker compose up --build
Execute the following command:
aws dynamodb scan \
--table-name Devices \
--endpoint-url http://localhost:4566
Use this option if you want to explore more features such as running your tests in a native image.
IMPORTANT: The GraalVM native-image
compiler should be installed and configured on your machine.
Deploy the required services using Docker Compose command:
docker compose up tasks-postgres tasks-localstack
Open a new terminal window and export the following environment variables:
export SPRING_PROFILES_ACTIVE=dev
export CITY_TASKS_DB_CLUSTER_SECRET='{"dbClusterIdentifier":"hiperium-city-tasks-db-cluster","password":"postgres123","dbname":"CityTasksDB","engine":"postgres","port":5432,"host":"localhost","username":"postgres"}'
export CITY_IDP_ENDPOINT='https://cognito-idp.us-east-1.amazonaws.com/<copilot_user_pool_id>'
export CITY_TASKS_TIME_ZONE='-05:00'
export AWS_DEFAULT_REGION='ap-southeast-2'
export AWS_ACCESS_KEY_ID='DUMMY'
export AWS_SECRET_ACCESS_KEY='DUMMY'
export AWS_ENDPOINT_OVERRIDE='http://localhost:4566'
Then, create and run the native executable from the project's root directory:
$ ./mvnw clean native:compile -Pnative spring-boot:run
Use the following script to deploy the application into AWS:
./run-scripts.sh
This script shows a menu with the following options:
Choose option 1 to deploy the application into AWS. You don't need to have exported the environment variables because the script will ask you for them:
List all of your AWS Copilot applications.
copilot app ls
Show information about the environments and services in your application.
copilot app show
Show information about your environments.
copilot env ls
Show information about the service, including endpoints, capacity and related resources.
copilot svc show
List of all the services in an application.
copilot svc ls
Show logs of a deployed service.
copilot svc logs --app city-tasks --name api --env dev --since 1h --follow
Show service status.
copilot svc status
To delete and clean-up all created resources.
copilot app delete --yes
For further reference, please consider the following sections:
- Official Apache Maven documentation
- Spring Boot Maven Plugin Reference Guide
- Create an OCI image
- GraalVM Native Image Support
- Testcontainers
- Testcontainers Postgres Module Reference Guide
- Spring Reactive Web
- Spring Data JPA
- OAuth2 Resource Server
- Quartz Scheduler
- Flyway Migration
The following guides illustrate how to use some features concretely:
These additional references should also help you:
This project has been configured to let you generate either a lightweight container or a native executable. It is also possible to run your tests in a native image.
If you're already familiar with Spring Boot container images support, this is the easiest way to get started. Docker should be installed and configured on your machine prior to creating the image.
To create the image, run the following goal:
$ ./mvnw spring-boot:build-image -Pnative -DskipTests
Then, you can run the app like any other container:
$ docker run --rm city-tasks-api:1.5.0
Use this option if you want to explore more options such as running your tests in a native image.
The GraalVM native-image
compiler should be installed and configured on your machine.
NOTE: GraalVM 22.3+ is required.
To create the executable, run the following goal:
$ ./mvnw native:compile -Pnative -DskipTests
Then, you can run the app as follows:
$ target/city-tasks-spring-boot-aws-copilot
You can also run your existing tests suite in a native image. This is an efficient way to validate the compatibility of your application.
To run your existing tests in a native image, run the following goal:
$ ./mvnw test -PnativeTest