Spring Boot + MongoDB project

 

spring+mongodb

Photo by Maximilian Weisbecker on Unsplash


Code: https://github.com/h-hub/co2stat

The Requirement

  • The service should be able to receive measurements from each sensor at the rate of 1 per minute
  • If the CO2 level exceeds 2000 ppm the sensor status should be set to WARN
  • If the service receives 3 or more consecutive measurements higher than 2000 the sensor status should be set to ALERT
  • When the sensor reaches status ALERT an alert should be stored
  • When the sensor reaches status ALERT it stays in this state until it receives 3 consecutive measurements lower than 2000; then it moves to OK
  • The service should provide the following metrics about each sensor:
    • Average CO2 level for the last 30 days
    • Maximum CO2 Level in the last 30 days
  • It is possible to list all the alerts for a given sensor

APIs to be implemented

Collect sensor mesurements

Collect sensor mesurementsPOST /api/v1/sensors/{uuid}/mesurements
{
  "co2" : 2000,
  "time" : "2019-02-01T18:55:47+00:00"
}
Sensor statusGET /api/v1/sensors/{uuid}
Response:
{
  "status" : "OK" // Possible status OK,WARN,ALERT
}
Sensor metricsGET /api/v1/sensors/{uuid}/metrics
Response:
{
  "maxLast30Days" : 1200,
  "avgLast30Days" : 900
}
Listing alertsGET /api/v1/sensors/{uuid}/alerts
Response:
[
  {
    "startTime" : "2019-02-02T18:55:47+00:00",
    "endTime" : "2019-02-02T20:00:47+00:00",
    "mesurement1" : 2100,
    "mesurement2" : 2200,
    "mesurement3" : 2100
  }
]

The Design

I have followed the DDD approach for this solution. Code and packages are structured so that it is easy to identify the components (entities, services, controllers, etc.), their purpose, and use cases of the system.

This solution follows the Hexagonal architecture with layers such as adapter and Application.

hexagonal-architecture
Hexagonal Architecture

The application layer has ports(use cases). The Service layer will be responsible for implementing those use cases.

The business logic is included in the Domain Classes.

All the input values to the program are validated in the controller layer. Exceptions are thrown accordingly with meaningful messages.


The Solution

  1. The solution is implemented using Spring boot 2.5.5 and Java 11.
  2. The application is a stateless application that can be scaled based on the requirement.
    1. If there are 100K sensors in the system and each sensor sends 1 request per minute, the API should be able to handle 100K requests per minute.
    2. To achieve this, we can release this API to scalable infrastructure and run load tests.
    3. With enough resources, this API should be able to handle more req than that easily.
  3. All the data is stored in MongoDB. Spring boot has excellent support for MongoDB integration.
    1. I decided to use mongo DB since these sensors collect enormous amounts of data within short periods, and MongoDB is capable of handling that.
    2. MongoDB is also a better choice when running queries such as getting the average of millions of records.
  4. To support transactions, I have used MongoDB replica sets.
  5. Application is unit tested to cover the most critical logic and codes using Junit4.

How to execute

  1. Create MongoDB database.
    1. Database name should be co2stat
    2. Mongo db schema
      DB schema
    3. Create three collections. sensoralert and mesurement 
  2. Execute mvn install from the project root folder
  3. Go to the target folder and execute java -jar co2stat-0.0.1-SNAPSHOT.jar
  4. Visit http://localhost:8081/status to check the API status

API Documentation

The API is documented using Open API 3, and it is included in the codebase. Check the file names ApiDocument.json. Then, use Swagger UI or the IntelliJ IDEA plugin to open it.


References

  • https://spring.io/projects/spring-data-mongodb
  • https://docs.mongodb.com/
  • https://leanpub.com/get-your-hands-dirty-on-clean-architecture

Comments