diff --git a/README.md b/README.md
new file mode 100644
index 0000000..60719af
--- /dev/null
+++ b/README.md
@@ -0,0 +1,109 @@
+# Case Study - Book Delivery
+
+
+
+
+
+### 📖 Information
+
+
+ - Book Delivery
+ - Here is the explanation of the example
+
+
+
+
+### Explore Rest APIs
+
+
+
+ Method |
+ Url |
+ Description |
+ Valid Path Variable |
+ No Path Variable |
+
+
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+### Technologies
+
+---
+- Java 17
+- Spring Boot 3.0
+- Restful API
+- Lombok
+- Maven
+- Junit5
+- Mockito
+- Integration Tests
+- Docker
+- Docker Compose
+- CI/CD (Github Actions)
+- Prometheues and Grafana
+- Postman
+- Actuator
+- Swagger 3
+
+### Prerequisites
+
+---
+- 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;
+
+```sh
+$ 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
+
+```sh
+$ cd bookdelivery
+$ docker-compose up --build
+```
+
+---
+### Maven Run
+To build and run the application with `Maven`, please follow the directions shown below;
+
+```sh
+$ 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
+
+
+
+
+### Contributors
+
+- [Sercan Noyan Germiyanoğlu](https://github.com/Rapter1990)
+- [Ahmet Aksünger](https://github.com/AhmetAksunger)
+- [Muhammet Oğuzhan Aydoğdu](https://github.com/moaydogdu)
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/controller/BookController.java b/src/main/java/com/example/demo/controller/BookController.java
index 0c2a4ed..2d5dc94 100644
--- a/src/main/java/com/example/demo/controller/BookController.java
+++ b/src/main/java/com/example/demo/controller/BookController.java
@@ -6,7 +6,7 @@
import com.example.demo.payload.request.book.BookCreateRequest;
import com.example.demo.payload.request.book.BookUpdateRequest;
import com.example.demo.payload.request.book.BookUpdateStockRequest;
-import com.example.demo.payload.request.pagination.PaginatedFindAllRequest;
+import com.example.demo.payload.request.pagination.PaginationRequest;
import com.example.demo.payload.response.CustomPageResponse;
import com.example.demo.payload.response.CustomResponse;
import com.example.demo.payload.response.book.BookCreatedResponse;
@@ -104,8 +104,8 @@ public CustomResponse getBookById(@PathVariable("bookId") final
*/
@PostMapping("/all")
@PreAuthorize("hasAnyAuthority('ROLE_ADMIN','ROLE_CUSTOMER')")
- public CustomResponse> getBooks(@RequestBody @Valid PaginatedFindAllRequest paginatedFindAllRequest) {
- final Page bookEntitiesFromDb = bookService.getAllBooks(paginatedFindAllRequest);
+ public CustomResponse> getBooks(@RequestBody @Valid PaginationRequest paginationRequest) {
+ final Page bookEntitiesFromDb = bookService.getAllBooks(paginationRequest);
final CustomPageResponse responses = BookMapper
.toGetResponse(bookEntitiesFromDb);
diff --git a/src/main/java/com/example/demo/payload/request/book/BookUpdateRequest.java b/src/main/java/com/example/demo/payload/request/book/BookUpdateRequest.java
index b01f147..17e5532 100644
--- a/src/main/java/com/example/demo/payload/request/book/BookUpdateRequest.java
+++ b/src/main/java/com/example/demo/payload/request/book/BookUpdateRequest.java
@@ -4,7 +4,10 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
-import lombok.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
import java.math.BigDecimal;
diff --git a/src/main/java/com/example/demo/service/BookService.java b/src/main/java/com/example/demo/service/BookService.java
index 18babf6..0083824 100644
--- a/src/main/java/com/example/demo/service/BookService.java
+++ b/src/main/java/com/example/demo/service/BookService.java
@@ -4,7 +4,7 @@
import com.example.demo.payload.request.book.BookCreateRequest;
import com.example.demo.payload.request.book.BookUpdateRequest;
import com.example.demo.payload.request.book.BookUpdateStockRequest;
-import com.example.demo.payload.request.pagination.PaginatedFindAllRequest;
+import com.example.demo.payload.request.pagination.PaginationRequest;
import org.springframework.data.domain.Page;
/**
@@ -40,10 +40,10 @@ public interface BookService {
/**
* Retrieves a paginated list of all books based on the provided request.
*
- * @param paginatedFindAllRequest The request containing pagination information.
+ * @param paginationRequest The request containing pagination information.
* @return A {@link Page} of {@link BookDTO} objects representing the list of books.
*/
- Page getAllBooks(PaginatedFindAllRequest paginatedFindAllRequest);
+ Page getAllBooks(PaginationRequest paginationRequest);
/**
* Updates a book by its unique identifier.
diff --git a/src/main/java/com/example/demo/service/impl/BookServiceImpl.java b/src/main/java/com/example/demo/service/impl/BookServiceImpl.java
index ae4cefd..cfa1a09 100644
--- a/src/main/java/com/example/demo/service/impl/BookServiceImpl.java
+++ b/src/main/java/com/example/demo/service/impl/BookServiceImpl.java
@@ -8,7 +8,7 @@
import com.example.demo.payload.request.book.BookCreateRequest;
import com.example.demo.payload.request.book.BookUpdateRequest;
import com.example.demo.payload.request.book.BookUpdateStockRequest;
-import com.example.demo.payload.request.pagination.PaginatedFindAllRequest;
+import com.example.demo.payload.request.pagination.PaginationRequest;
import com.example.demo.repository.BookRepository;
import com.example.demo.service.BookService;
import lombok.RequiredArgsConstructor;
@@ -76,14 +76,14 @@ public BookDTO updateBookStockById(String bookId, BookUpdateStockRequest request
/**
* Retrieves a paginated list of all books based on the provided request.
*
- * @param paginatedFindAllRequest The request containing pagination information.
+ * @param paginationRequest The request containing pagination information.
* @return A {@link Page} of {@link BookDTO} objects representing the list of books.
*/
@Override
- public Page getAllBooks(PaginatedFindAllRequest paginatedFindAllRequest) {
+ public Page getAllBooks(PaginationRequest paginationRequest) {
return bookRepository
- .findAll(paginatedFindAllRequest.getPaginationRequest().toPageable())
+ .findAll(paginationRequest.toPageable())
.map(BookMapper::toDTO);
}
diff --git a/src/test/java/com/example/demo/controller/BookControllerTest.java b/src/test/java/com/example/demo/controller/BookControllerTest.java
index 413ef37..6d6f442 100644
--- a/src/test/java/com/example/demo/controller/BookControllerTest.java
+++ b/src/test/java/com/example/demo/controller/BookControllerTest.java
@@ -8,8 +8,6 @@
import com.example.demo.payload.request.book.BookCreateRequest;
import com.example.demo.payload.request.book.BookUpdateRequest;
import com.example.demo.payload.request.book.BookUpdateStockRequest;
-import com.example.demo.payload.request.pagination.DateIntervalRequest;
-import com.example.demo.payload.request.pagination.PaginatedFindAllRequest;
import com.example.demo.payload.request.pagination.PaginationRequest;
import com.example.demo.payload.response.CustomPageResponse;
import com.example.demo.payload.response.CustomResponse;
@@ -27,8 +25,6 @@
import org.springframework.http.MediaType;
import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.util.Calendar;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
@@ -157,30 +153,14 @@ void givenPaginatedFindAllRequest_whenCustomerRoleAndBookListFound_ReturnPageRes
BookDTO bookDTO1 = BookMapper.toDTO(book1);
BookDTO bookDTO2 = BookMapper.toDTO(book2);
- Calendar calendar1 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 10);
-
- Calendar calendar2 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 13);
-
- LocalDateTime startDate = calendar1.getTime().toInstant().atZone(calendar1.getTimeZone().toZoneId()).toLocalDateTime();
- LocalDateTime endDate = calendar2.getTime().toInstant().atZone(calendar2.getTimeZone().toZoneId()).toLocalDateTime();
-
- PaginatedFindAllRequest request = PaginatedFindAllRequest.builder()
- .dateIntervalRequest(new DateIntervalRequest(startDate, endDate))
- .paginationRequest(new PaginationRequest(1, 10))
- .build();
+ PaginationRequest request = new PaginationRequest(1, 10);
Page mockPageOfOrderDTOs = new PageImpl<>(List.of(bookDTO1, bookDTO2));
CustomPageResponse customPageResponseOfBookGetResponse = BookMapper.toGetResponse(mockPageOfOrderDTOs);
// when
- Mockito.when(bookService.getAllBooks(any(PaginatedFindAllRequest.class))).thenReturn(mockPageOfOrderDTOs);
+ Mockito.when(bookService.getAllBooks(any(PaginationRequest.class))).thenReturn(mockPageOfOrderDTOs);
// then
CustomResponse> response = CustomResponse.ok(customPageResponseOfBookGetResponse);
@@ -211,30 +191,14 @@ void givenPaginatedFindAllRequest_whenAdminRoleAndBookListFound_ReturnPageRespon
BookDTO bookDTO1 = BookMapper.toDTO(book1);
BookDTO bookDTO2 = BookMapper.toDTO(book2);
- Calendar calendar1 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 10);
-
- Calendar calendar2 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 13);
-
- LocalDateTime startDate = calendar1.getTime().toInstant().atZone(calendar1.getTimeZone().toZoneId()).toLocalDateTime();
- LocalDateTime endDate = calendar2.getTime().toInstant().atZone(calendar2.getTimeZone().toZoneId()).toLocalDateTime();
-
- PaginatedFindAllRequest request = PaginatedFindAllRequest.builder()
- .dateIntervalRequest(new DateIntervalRequest(startDate, endDate))
- .paginationRequest(new PaginationRequest(1, 10))
- .build();
+ PaginationRequest request = new PaginationRequest(1, 10);
Page mockPageOfOrderDTOs = new PageImpl<>(List.of(bookDTO1, bookDTO2));
CustomPageResponse customPageResponseOfBookGetResponse = BookMapper.toGetResponse(mockPageOfOrderDTOs);
// when
- Mockito.when(bookService.getAllBooks(any(PaginatedFindAllRequest.class))).thenReturn(mockPageOfOrderDTOs);
+ Mockito.when(bookService.getAllBooks(any(PaginationRequest.class))).thenReturn(mockPageOfOrderDTOs);
// then
CustomResponse> response = CustomResponse.ok(customPageResponseOfBookGetResponse);
diff --git a/src/test/java/com/example/demo/service/impl/BookServiceImplTest.java b/src/test/java/com/example/demo/service/impl/BookServiceImplTest.java
index fdd4d6e..3eab29f 100644
--- a/src/test/java/com/example/demo/service/impl/BookServiceImplTest.java
+++ b/src/test/java/com/example/demo/service/impl/BookServiceImplTest.java
@@ -10,8 +10,6 @@
import com.example.demo.payload.request.book.BookCreateRequest;
import com.example.demo.payload.request.book.BookUpdateRequest;
import com.example.demo.payload.request.book.BookUpdateStockRequest;
-import com.example.demo.payload.request.pagination.DateIntervalRequest;
-import com.example.demo.payload.request.pagination.PaginatedFindAllRequest;
import com.example.demo.payload.request.pagination.PaginationRequest;
import com.example.demo.repository.BookRepository;
import com.example.demo.util.RandomUtil;
@@ -25,8 +23,10 @@
import org.springframework.data.domain.Pageable;
import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -169,25 +169,9 @@ void givenValidBookIdAndBookUpdateStockRequest_whenBookNotFound_throwBookNotFoun
@Test
void givenPaginatedFindAllRequest_WhenNoBooksFound_throwBookNotFoundException() {
- // Given
-
- Calendar calendar1 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 10);
-
- Calendar calendar2 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 13);
- LocalDateTime startDate = calendar1.getTime().toInstant().atZone(calendar1.getTimeZone().toZoneId()).toLocalDateTime();
- LocalDateTime endDate = calendar2.getTime().toInstant().atZone(calendar2.getTimeZone().toZoneId()).toLocalDateTime();
-
- PaginatedFindAllRequest request = PaginatedFindAllRequest.builder()
- .dateIntervalRequest(new DateIntervalRequest(startDate, endDate))
- .paginationRequest(new PaginationRequest(1, 10))
- .build();
+ // Given
+ PaginationRequest request = new PaginationRequest(1, 10);
Page emptyPage = new PageImpl<>(Collections.emptyList());
@@ -208,23 +192,8 @@ void givenPaginatedFindAllRequest_WhenNoBooksFound_throwBookNotFoundException()
@Test
void givenPaginatedFindAllRequest_WhenBooksFound_ReturnPageBookList() {
- Calendar calendar1 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 10);
-
- Calendar calendar2 = Calendar.getInstance();
- calendar1.set(Calendar.YEAR, 2000);
- calendar1.set(Calendar.MONTH, Calendar.SEPTEMBER);
- calendar1.set(Calendar.DAY_OF_MONTH, 13);
-
- LocalDateTime startDate = calendar1.getTime().toInstant().atZone(calendar1.getTimeZone().toZoneId()).toLocalDateTime();
- LocalDateTime endDate = calendar2.getTime().toInstant().atZone(calendar2.getTimeZone().toZoneId()).toLocalDateTime();
-
- PaginatedFindAllRequest request = PaginatedFindAllRequest.builder()
- .dateIntervalRequest(new DateIntervalRequest(startDate, endDate))
- .paginationRequest(new PaginationRequest(1, 10))
- .build();
+ // given
+ PaginationRequest request = new PaginationRequest(1, 10);
List books = Arrays.asList(
Book.builder()