Skip to content

Case Study - Sample Book Delivery App (Spring Boot, Spring Security , Mysql, JUnit, Integration Test, Docker, Test Container, AOP, CI/CD, Prometheus, Grafana, Github Actions)

Notifications You must be signed in to change notification settings

Rapter1990/bookdelivery

Repository files navigation

Case Study - Book Delivery

Main Information

📖 Information

  • Book Delivery is a kind of Spring Boot with covering important and useful features
  • Here is the explanation of the example
      There are 2 roles named Admin and Customer
      Admin handles with creating book, updating stock of book and updating book information, getting all books and book by id, showing statistic by customer's order and all orders while Customer tackle with creating order, showing own orders, getting all books and book by id except for their own authentication process covering the process of register, login, refresh token and logout

Explore Rest APIs

Method Url Description Request Body Header Valid Path Variable No Path Variable
POST /api/v1/auth/register Register of both Admin and Customer SignupRequest
POST /api/v1/auth/login Login of both Admin and Customer LoginRequest
POST /api/v1/auth/refreshtoken Refresh Token of both Admin and Customer TokenRefreshRequest
POST /api/v1/auth/logout Logout of both Admin and Customer token
POST /api/v1/books Create Book from Admin BookCreateRequest
PUT /api/v1/books/stock-amount/{bookId} Update Stock of Book from Admin BookUpdateStockRequest bookId
PUT /api/v1/books/{bookId} Update Book from Admin BookUpdateRequest bookId
PUT /api/v1/books/{bookId} Update Book from Admin BookUpdateRequest bookId
GET /api/v1/books/{bookId} Get Book by Id from Admin and Customer bookId
GET /api/v1/books/{bookId} Get Books from Admin and Customer PaginationRequest
POST /api/v1/customers Create Customer from Admin CustomerCreateRequest
POST /api/v1/orders Create Order from Customer CreateOrderRequest
GET /api/v1/orders/{orderId} Get Order by Id from Admin and Customer orderId
POST /api/v1/orders/{orderId} Get Orders by Customer Id from Admin and Customer PaginationRequest customerId
POST /api/v1/orders/between-dates Get Orders by between dates from Admin and Customer PaginationRequest customerId
POST /api/v1/orders/between-dates Get Orders by between dates from Admin and Customer PaginationRequest
GET /api/v1/statistics/{customerId} Get Order Statistics By CustomerId from Admin and Customer PaginationRequest customerId
GET /api/v1/statistics Get Order Statistics from Admin PaginationRequest

Technologies


  • Java 17
  • Spring Boot 3.0
  • Restful API
  • Lombok
  • Maven
  • Junit5
  • Mockito
  • Integration Tests
  • Docker
  • Docker Compose
  • CI/CD (Github Actions)
  • Prometheus and Grafana
  • Postman
  • Actuator
  • Swagger 3

How to test Pessimistic Lock using ApacheHttpServer?

We implemented a pessimistic lock mechanism to avoid scenarios where multiple users attempt to order books simultaneously, ensuring that their actions are synchronized properly to prevent data conflicts. So with a pessimstic lock, if multiple users attempt to order one last stock of a book, only one of them will be able to order.

Install Apache 2 on Linux & Test

Installation

sudo apt-get install apache2

To test, you need to make requests to the create order endpoint. So you're going to need a valid payload json which is shown below. (Do not forget to change the bookId with a valid one)

{
  "orderDetailSet": [
    {
      "bookId": "3a0e7efc-1e32-404c-9a70-d9fb63262c6e",
      "amount": 1
    }
  ]
}

Now we can test the create order endpoint, and see if the locking mechanism works

  • n represents the number of requests to be made to the URL specified
  • c represents the number of requests to send at a time. Here, it's set to 2, so ApacheBench will send 2 requests concurrently.

Here is the example shown below for testing

ab -n 100 -c 2 -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX0NVU1RPTUVSIl0sInVzZXJGdWxsTmFtZSI6ImN1c3RvbWVyX2Z1bGxuYW1lIiwiaWQiOjIsImVtYWlsIjoiY3VzdG9tZXJAYm9va2RlbGl2ZXJ5LmNvbSIsInVzZXJuYW1lIjoiY3VzdG9tZXJfMSIsInN1YiI6ImN1c3RvbWVyXzEiLCJpYXQiOjE2OTQ4ODkyNTMsImV4cCI6MTY5NDg4OTg1M30.UokFWxgZnSnYZsbAlwbfhQj1F54QrEOU5_5KzHyRmtY" -T "application/json" -p post_data.json http://localhost:1221/api/v1/orders

Swagger

http://localhost:1221/swagger-ui/index.html

Prerequisites

Define Variable in .env file

DATABASE_USERNAME={DATABASE_USERNAME}
DATABASE_PASSWORD={DATABASE_PASSWORD}

  • Maven or Docker

Docker Run

The application can be built and run by the Docker engine. The Dockerfile has multistage build, so you do not need to build and run separately.

Please follow directions shown below in order to build and run the application with Docker Compose file;

$ cd bookdelivery
$ docker-compose up -d

If you change anything in the project and run it on Docker, you can also use this command shown below

$ cd bookdelivery
$ docker-compose up --build

Maven Run

To build and run the application with Maven, please follow the directions shown below;

$ cd bookdelivery
$ mvn clean install
$ mvn spring-boot:run

Screenshots

Click here to show the screenshots of project

Figure 1

Figure 2

Figure 3

Figure 4

Figure 5

Figure 6

Figure 7

Figure 8

Figure 9

Figure 10

Figure 11

Contributors