Generic implementation of an order management service for an ecommerce, built with Docker, SpringBoot, Mongodb and Kafka. Applying the fundamental principles of microservices, this application allows you to manage user orders.
Use the utility script scripts/build_and_deploy.sh
to do all the stuff, or do it manually:
cd orders
docker build --no-cache -t unict/ordermanager:1.0.0 -f Dockerfile .
cd ../scripts
docker-compose -p order-service -f docker-compose.yaml --env-file .env up -d
Remember to customize .env file properly.
Order Service REST API supports following operations:
Method | URI | Description | Parameters |
---|---|---|---|
POST |
/orders | Adds a new order for the user indicated in the header | |
GET |
/orders | List all user orders. Supports pagination | int per_page, int page |
GET |
/orders/{id} | Returns a specific order based on its id | UUID id |
Requests must have the header HTTP X-User-ID . The userId 0 will represent an admin, any other userId will represent a generic user.
Order Service is also producer and consumer on the topic orders of the following messages:
- When a new order is created successfully, this message is produced and forwarded on the topics orders and notifications :
key = order_completed
value = {
orderId: id,
products: [ { product_id: quantity }, "..." ],
total: amount,
shippingAddress: {...},
billingAddress: {...},
userId: :id,
extraArgs: {}
}
- When this message is consumed, if the status_code received is not 0, the corresponding order status is set to Abort
key = order_validation
value = {
timestamp: UnixTimestamp
orderId: id,
status: status_code,
extraArgs: {}
}
- When this message is consumed, it is verified that the triple orderId, userId, amountPaid exists. If it exists, the order status is set to Paid and the same message is forwarded on the topics notifications , invoicing. Otherwise, the order status is set to Abort , and the message is forwarded on the topic logging whit key = order_paid_validation_failure , and one of the following extraArgs :
- Order not found:
extraArgs: {error: "ORDER_NOT_FOUND"}
- Wrong amount paid:
extraArgs: {error: "WRONG_AMOUNT_PAID"}
- Order not found:
key = order_paid
value = {
timestamp: UnixTimestamp
userId: userId,
amountPaid: amountPaid,
extraArgs: {...}
}
When a request fails and an exception is raised, the following kafka message is forwarded on the topic logging:
key = http_errors
value = {
timestamp: UnixTimestamp
sourceIp: sourceIp,
service: ordermanager,
request: path + method,
error: {...}
}
If the error is of type 50x , error contains the stack trace. If the error is of type 40x , error contains the raw http status code.
Order Service implements a custom healt-check strategy, heart-beat like. Periodically, it makes a POST
request whit the following request body:
{
"service": ordermanager,
"serviceStatus": "up|down",
"dbStatus": "up|down"
}
The endpoint is customizable as an environment variable (For tests reasons, the request is made to itself).
For testing and debugging purposes, it is useful to have a fake producer to populate topics whit messages. In the scripts folder you can find a Dockerfile to build an interactive python environment, to use an utility script: kafka_producer_interactive.py
. Using the option --network
you can launch it inside your docker network.
docker build --no-cache -t unict/fake_producer:0.0.1 -f Dockerfile .
docker run -it --network order-service_default unict/fake_producer:0.0.1
>>> import kafka_producer_interactive as kpi
>>> send = kpi.producer(topic='orders')
>>> send('order_validation', value={'myStr': 'myValue'})