This system allows to create and get Booking Requests for an important tourism company.
Currently, the registration of reservations is done through email or telephone calls with consultants, which has caused inconvenience to some clients due to the fact that some requests take a long time to confirm. The technology area requires implementing a system that allows the registration of reservations using a message broker (Kafka, Rabbit MQ, etc.) which will reduce the current waiting time. Good handling of possible errors must be taken into account, whether due to a message with invalid information or possible problems in the network.
This system is composed of the next components:
The general architecture pattern used is Microservices, but also, the event-oriented architectural style was used to handle the Publisher/Subscriber pattern.
This component exposes an API to receive the following requests from the Client:
- Get all the Booking Requests.
- Get a specific Booking Request.
- Create a Booking Request.
In the next diagram, you can check how it is sharing data with the other components.
This component consumes the events published from the Publisher component using the RabbitMQ Broker and sends the request to the API to finally create the Booking Requests. See the following diagram.
Broker used to define the publish/subscriptor pattern. This helps to set an event-oriented architecture. Also, a Dead Letter Queue was implemented to catch events with exceptions and retry them.
This is the final interface, where the data is validated and stored. A REST API (with hateoas) is exposed to get the following actions:
- Get all the Booking Requests
- Get a specific Booking Request
- Create a Booking Request
This component was defined using the layers' architectural style. The components in each layer were organized as the following diagram shows.
Database engine used to handle the data from the API
The C4 model was used to represent the architecture at different abstraction levels:
- System: shows the external systems used and the interaction with users
- Container: shows the high-level components interacting to complete a request.
- Component: shows how is organized a specific component.
The technologies used to deploy easily all the components in the development environment were the next:
- Maven: to install the dependencies and package into .jar files
- Docker: to ease the deployment process
- Bash: to create a script to automate the deployment process
You have to set up the application.properties file to the following SpringBoot projects:
#Remove of this file the .example extension and set the values in <>
#DATABASE setup
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${DATABASE_HOST:localhost}:${DATABASE_PORT:3307}/${DATABASE_NAME:booking_app_db}
spring.datasource.username=${DATABASE_USER:root}
spring.datasource.password=${DATABASE_PASSWORD:12345678}
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
#spring.jpa.show-sql: true
#MAIL setup
spring.mail.host=smtp.gmail.com
spring.mail.port=587
#Need a configured gmail account. Please check https://support.google.com/accounts/answer/185833
spring.mail.username=${MAIL_USERNAME:<USERNAME>}
spring.mail.password=${MAIL_PASSWORD:<APP_PASSWORD>}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
You need to have a Gmail account properly configured to get an app password. Please visit this link
spring.main.web-application-type=none
spring.rabbitmq.listener.simple.retry.enabled: true
spring.rabbitmq.listener.simple.retry.initial-interval: 3s
spring.rabbitmq.listener.simple.retry.max-attempts: 5
spring.rabbitmq.listener.simple.retry.max-interval: 10s
spring.rabbitmq.listener.simple.retry.multiplier: 2
spring.rabbitmq.host:${RABBITMQ_HOST:localhost}
spring.rabbitmq.port:${RABBITMQ_PORT:5672}
server.port=8081
spring.rabbitmq.host:${RABBITMQ_HOST:localhost}
spring.rabbitmq.port:${RABBITMQ_PORT:5672}
In the terminal run the following command:
sh deploy.sh
Check the next Postman Collection to test the endpoints.
The convention to name endpoints was followed. No actions in URI, just subjects.
Backend Port: 8080 Producer Port: 8081
- Get all Booking Requests: GET /bookingRequests
- Get by ID: GET /bookingRequests/1
- Create a Booking Requests: POST /bookingRequests
Body to create the Booking Requests:
{
"checkInDate": "2022-01-04",
"checkOutDate": "2022-01-05",
"holderEmail": "[email protected]",
"holderName": "Santiago",
"numberOfPeople":"2",
"numberOfRooms": "1",
"numberOfMinors": "1"
}
Santiago Hyun Dorado. @sahydo