From 43ee051da17871a7786c0c91c699f7b793dee57b Mon Sep 17 00:00:00 2001 From: Steve Davis Date: Wed, 20 Jul 2022 17:10:29 +0100 Subject: [PATCH 1/7] Add CosmosDB persistence to WebAPI --- java/pom.xml | 8 + java/sonar-project.properties | 5 +- .../menu/api/v1/CategoryController.java | 16 +- .../workloads/menu/api/v1/ItemController.java | 16 +- .../workloads/menu/api/v1/MenuController.java | 30 +-- .../v1/dto/request/GenerateTokenRequest.java | 30 --- .../api/v1/dto/request/UpdateMenuRequest.java | 2 - .../menu/api/v1/dto/response/ItemDTO.java | 2 - .../v1/dto/response/SearchMenuResultItem.java | 2 - .../menu/api/v2/MenuControllerV2.java | 8 +- .../workloads/menu/domain/Category.java | 13 - .../stacks/workloads/menu/domain/Menu.java | 13 - .../CategoryAlreadyExistsException.java | 20 ++ .../CategoryDoesNotExistException.java | 20 ++ .../exception/ItemAlreadyExistsException.java | 21 ++ .../exception/ItemDoesNotExistsException.java | 23 ++ .../exception/MenuAlreadyExistsException.java | 20 ++ .../menu/exception/MenuApiException.java | 17 ++ .../menu/exception/MenuNotFoundException.java | 17 ++ .../handler/MenuApiExceptionHandler.java | 68 ++++++ .../wrappers/CreateCategoryMapper.java | 13 + .../mappers/wrappers/CreateItemMapper.java | 13 + .../mappers/wrappers/CreateMenuMapper.java | 23 ++ .../wrappers/UpdateCategoryMapper.java | 13 + .../mappers/wrappers/UpdateItemMapper.java | 13 + .../mappers/wrappers/UpdateMenuMapper.java | 13 + .../menu/repository/MenuRepository.java | 56 +++++ .../service/data/CosmosMenuQueryService.java | 76 ++++++ .../menu/service/data/MenuQueryService.java | 61 +++++ .../menu/service/v1/CategoryService.java | 79 +++++- .../menu/service/v1/ItemService.java | 83 ++++++- .../menu/service/v1/MenuService.java | 122 +++++++--- .../service/v1/utility/MenuHelperService.java | 110 +++++++++ .../menu/service/v2/MenuServiceV2.java | 31 ++- java/src/main/resources/application.yml | 6 +- java/src/main/resources/lombok.config | 1 + .../workloads/actuator/ActuatorTest.java | 19 +- .../menu/api/v1/CategoryControllerTest.java | 100 +++++++- .../menu/api/v1/ItemControllerTest.java | 89 ++++++- .../menu/api/v1/MenuControllerTest.java | 224 +++++++++++++++++- .../menu/api/v2/MenuControllerV2Test.java | 24 +- .../workloads/menu/domain/MenuHelper.java | 6 +- .../data/CosmosMenuQueryServiceTest.java | 144 +++++++++++ 43 files changed, 1473 insertions(+), 197 deletions(-) delete mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/GenerateTokenRequest.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateCategoryMapper.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateItemMapper.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateMenuMapper.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateCategoryMapper.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateItemMapper.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateMenuMapper.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/repository/MenuRepository.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryService.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/service/data/MenuQueryService.java create mode 100644 java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java create mode 100644 java/src/main/resources/lombok.config create mode 100644 java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java diff --git a/java/pom.xml b/java/pom.xml index 6a6f1a92..d9bba81a 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -22,11 +22,13 @@ 1.0.2.2-RELEASE 1.0.3 + 1.0.0 11 1.18.0 1.6.1 2.6.4 + 3.6.0 3.6.0 2.13.0 4.1.0 @@ -106,6 +108,12 @@ ${stacks.core.commons.version} + + com.amido.stacks.modules + stacks-azure-cosmos + ${stacks.azure.cosmos.version} + + org.springframework.boot spring-boot-starter-actuator diff --git a/java/sonar-project.properties b/java/sonar-project.properties index f5691ee6..34693065 100644 --- a/java/sonar-project.properties +++ b/java/sonar-project.properties @@ -6,7 +6,6 @@ # sonar.login=${env.SONAR_TOKEN} # sonar.organization=${env.SONAR_ORGANIZATION} sonar.sourceEncoding=UTF-8 - ################################### # Branch and PR Analysis Variables # These are all supplied by the Pipeline @@ -20,7 +19,6 @@ sonar.sourceEncoding=UTF-8 # sonar.pullrequest.github.repository=${env.SONAR_GITHUB_REPO} # sonar.pullrequest.base=${env.SONAR_TARGET_BRANCH} ################################### - sonar.sources=src/main sonar.java.binaries=target sonar.java.libraries=.m2 @@ -28,6 +26,5 @@ sonar.junit.reportPaths=target/surefire-reports sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml sonar.language=java sonar.java.source=11 - sonar.cpd.exclusions=**/model/* -sonar.coverage.exclusions=**/AuthControllerImpl*,**/ApplicationConfig* +sonar.coverage.exclusions=**/AuthControllerImpl*,**/ApplicationConfig*,**/exception/** diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java index 4cbc63ab..f4b2ae99 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java @@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -45,10 +44,9 @@ public class CategoryController { @CreateAPIResponses ResponseEntity createCategory( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, - @Valid @RequestBody CreateCategoryRequest body, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + @Valid @RequestBody CreateCategoryRequest body) { - return new ResponseEntity<>(categoryService.create(body, correlationId), HttpStatus.CREATED); + return new ResponseEntity<>(categoryService.create(menuId, body), HttpStatus.CREATED); } @PutMapping("/{categoryId}") @@ -62,11 +60,9 @@ ResponseEntity updateCategory( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, - @Valid @RequestBody UpdateCategoryRequest body, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + @Valid @RequestBody UpdateCategoryRequest body) { - return new ResponseEntity<>( - categoryService.update(menuId, categoryId, body, correlationId), OK); + return new ResponseEntity<>(categoryService.update(menuId, categoryId, body), OK); } @DeleteMapping("/{categoryId}") @@ -79,9 +75,9 @@ ResponseEntity updateCategory( ResponseEntity deleteCategory( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") - UUID categoryId, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + UUID categoryId) { + categoryService.delete(menuId, categoryId); return new ResponseEntity<>(OK); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java index c21ab46b..5f411dec 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java @@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -47,11 +46,9 @@ ResponseEntity createItem( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, - @Valid @RequestBody CreateItemRequest body, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + @Valid @RequestBody CreateItemRequest body) { - return new ResponseEntity<>( - itemService.create(menuId, categoryId, body, correlationId), HttpStatus.CREATED); + return new ResponseEntity<>(itemService.create(menuId, categoryId, body), HttpStatus.CREATED); } @PutMapping("/{itemId}") @@ -66,11 +63,10 @@ ResponseEntity updateItem( @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, @Parameter(description = "Item id", required = true) @PathVariable("itemId") UUID itemId, - @Valid @RequestBody UpdateItemRequest body, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + @Valid @RequestBody UpdateItemRequest body) { return new ResponseEntity<>( - itemService.update(menuId, categoryId, body, correlationId), HttpStatus.OK); + itemService.update(menuId, categoryId, itemId, body), HttpStatus.OK); } @DeleteMapping("/{itemId}") @@ -84,9 +80,9 @@ ResponseEntity deleteItem( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, - @Parameter(description = "Item id", required = true) @PathVariable("itemId") UUID itemId, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + @Parameter(description = "Item id", required = true) @PathVariable("itemId") UUID itemId) { + itemService.delete(menuId, categoryId, itemId); return new ResponseEntity<>(OK); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java index 8fffba5e..7636f18c 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java @@ -1,14 +1,10 @@ package com.amido.stacks.workloads.menu.api.v1; -import static org.springframework.http.HttpStatus.OK; - import com.amido.stacks.core.api.annotations.CreateAPIResponses; import com.amido.stacks.core.api.annotations.DeleteAPIResponses; import com.amido.stacks.core.api.annotations.ReadAPIResponses; import com.amido.stacks.core.api.annotations.SearchAPIResponses; import com.amido.stacks.core.api.annotations.UpdateAPIResponses; -import com.amido.stacks.core.api.dto.response.ResourceCreatedResponse; -import com.amido.stacks.core.api.dto.response.ResourceUpdatedResponse; import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateMenuRequest; import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateMenuRequest; import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; @@ -30,7 +26,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -50,11 +45,9 @@ public class MenuController { description = "Adds a menu", operationId = "CreateMenu") @CreateAPIResponses - ResponseEntity createMenu( - @Valid @RequestBody CreateMenuRequest body, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + ResponseEntity createMenu(@Valid @RequestBody CreateMenuRequest dto) { - return new ResponseEntity<>(menuService.create(body, correlationId), HttpStatus.CREATED); + return new ResponseEntity<>(menuService.create(dto), HttpStatus.CREATED); } @GetMapping @@ -95,11 +88,9 @@ ResponseEntity searchMenu( mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = MenuDTO.class))) @ReadAPIResponses - ResponseEntity getMenu( - @PathVariable(name = "id") UUID id, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + ResponseEntity getMenu(@PathVariable(name = "id") UUID id) { - return ResponseEntity.ok(menuService.get(id, correlationId)); + return ResponseEntity.ok(menuService.get(id)); } @PutMapping(value = "/{id}") @@ -108,12 +99,11 @@ ResponseEntity getMenu( summary = "Update a menu", description = "Update a menu with new information") @UpdateAPIResponses - ResponseEntity updateMenu( + ResponseEntity updateMenu( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, - @Valid @RequestBody UpdateMenuRequest body, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + @Valid @RequestBody UpdateMenuRequest body) { - return new ResponseEntity<>(menuService.update(body, correlationId), HttpStatus.OK); + return new ResponseEntity<>(menuService.update(menuId, body), HttpStatus.OK); } @DeleteMapping(value = "/{id}") @@ -124,9 +114,9 @@ ResponseEntity updateMenu( operationId = "DeleteMenu") @DeleteAPIResponses ResponseEntity deleteMenu( - @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId) { - return new ResponseEntity<>(OK); + menuService.delete(menuId); + return new ResponseEntity<>(HttpStatus.OK); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/GenerateTokenRequest.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/GenerateTokenRequest.java deleted file mode 100644 index 973b8369..00000000 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/GenerateTokenRequest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.amido.stacks.workloads.menu.api.v1.dto.request; - -import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class GenerateTokenRequest { - - @JsonProperty("client_id") - @NotBlank - private String client_id = null; - - @JsonProperty("client_secret") - @NotBlank - private String client_secret = null; - - @JsonProperty("audience") - @NotNull - private String audience = null; - - @JsonProperty("grant_type") - @NotNull - private String grant_type = null; -} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/UpdateMenuRequest.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/UpdateMenuRequest.java index 0be7ee9c..b92a80e7 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/UpdateMenuRequest.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/request/UpdateMenuRequest.java @@ -3,13 +3,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor -@AllArgsConstructor public class UpdateMenuRequest { @JsonProperty("name") diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/ItemDTO.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/ItemDTO.java index 53642a3a..6a399a83 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/ItemDTO.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/ItemDTO.java @@ -2,13 +2,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor -@AllArgsConstructor @Schema(name = "Item") public class ItemDTO { diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/SearchMenuResultItem.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/SearchMenuResultItem.java index e03cefb8..77684b33 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/SearchMenuResultItem.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/dto/response/SearchMenuResultItem.java @@ -2,13 +2,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.UUID; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor -@AllArgsConstructor public class SearchMenuResultItem { @JsonProperty("id") diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java index a53e562a..fb6772d0 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java @@ -4,7 +4,6 @@ import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; import com.amido.stacks.workloads.menu.service.v2.MenuServiceV2; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -14,7 +13,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -40,10 +38,8 @@ public class MenuControllerV2 { mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = MenuDTO.class))) @ReadAPIResponses - ResponseEntity getMenu( - @PathVariable(name = "id") UUID id, - @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + ResponseEntity getMenu(@PathVariable(name = "id") UUID id) { - return ResponseEntity.ok(menuServiceV2.get(id, correlationId)); + return ResponseEntity.ok(menuServiceV2.get(id)); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/domain/Category.java b/java/src/main/java/com/amido/stacks/workloads/menu/domain/Category.java index defe4f81..9e967172 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/domain/Category.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/domain/Category.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -18,16 +17,4 @@ public class Category { private String description; @Builder.Default private List items = new ArrayList<>(); - - public Category addOrUpdateItem(Item item) { - if (this.items == null) { - this.items = new ArrayList<>(); - } - this.items = - this.items.stream() - .filter(c -> !c.getId().equals(item.getId())) - .collect(Collectors.toList()); - this.items.add(item); - return this; - } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/domain/Menu.java b/java/src/main/java/com/amido/stacks/workloads/menu/domain/Menu.java index 775189dd..ded01d5d 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/domain/Menu.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/domain/Menu.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -24,16 +23,4 @@ public class Menu { @Builder.Default private List categories = new ArrayList<>(); private Boolean enabled; - - public Menu addOrUpdateCategory(Category category) { - if (this.categories == null) { - this.categories = new ArrayList<>(); - } - this.categories = - this.categories.stream() - .filter(c -> !c.getId().equals(category.getId())) - .collect(Collectors.toList()); - this.categories.add(category); - return this; - } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java new file mode 100644 index 00000000..689c583c --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java @@ -0,0 +1,20 @@ +package com.amido.stacks.workloads.menu.exception; + +import java.util.UUID; + +public class CategoryAlreadyExistsException extends MenuApiException { + + private static final int EXCEPTION_CODE = 11409; + + public CategoryAlreadyExistsException(UUID menuId, String name) { + super( + String.format( + "A category with the name '%s' already exists for the menu with id '%s'.", + name, menuId)); + } + + @Override + public int getExceptionCode() { + return EXCEPTION_CODE; + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java new file mode 100644 index 00000000..f7b3be0f --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java @@ -0,0 +1,20 @@ +package com.amido.stacks.workloads.menu.exception; + +import java.util.UUID; + +public class CategoryDoesNotExistException extends MenuApiException { + + private static final int EXCEPTION_CODE = 11404; + + public CategoryDoesNotExistException(UUID menuId, UUID categoryId) { + super( + String.format( + "A category with the id '%s' does not exist for menu with id '%s'.", + categoryId, menuId)); + } + + @Override + public int getExceptionCode() { + return EXCEPTION_CODE; + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java new file mode 100644 index 00000000..334cd827 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java @@ -0,0 +1,21 @@ +package com.amido.stacks.workloads.menu.exception; + +import java.util.UUID; + +public class ItemAlreadyExistsException extends MenuApiException { + + private static final int EXCEPTION_CODE = 12409; + + public ItemAlreadyExistsException(UUID menuId, UUID categoryId, String name) { + super( + String.format( + "An item with the name '%s' already exists for the category '%s' in menu with " + + "id '%s'.", + name, categoryId, menuId)); + } + + @Override + public int getExceptionCode() { + return EXCEPTION_CODE; + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java new file mode 100644 index 00000000..4dabc7d7 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java @@ -0,0 +1,23 @@ +package com.amido.stacks.workloads.menu.exception; + +import java.util.UUID; + +/** + * @author ArathyKrishna + */ +public class ItemDoesNotExistsException extends MenuApiException { + + private static final int EXCEPTION_CODE = 12404; + + public ItemDoesNotExistsException(UUID menuId, UUID categoryId, UUID itemId) { + super( + String.format( + "An item with the id '%s' does not exists for category with the id '%s' and for menu with id '%s'.", + itemId, categoryId, menuId)); + } + + @Override + public int getExceptionCode() { + return EXCEPTION_CODE; + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java new file mode 100644 index 00000000..f8d9c682 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java @@ -0,0 +1,20 @@ +package com.amido.stacks.workloads.menu.exception; + +import java.util.UUID; + +public class MenuAlreadyExistsException extends MenuApiException { + + private static final int EXCEPTION_CODE = 10409; + + public MenuAlreadyExistsException(UUID restaurantId, String name) { + super( + String.format( + "A Menu with the name '%s' already exists for the restaurant with id '%s'.", + name, restaurantId)); + } + + @Override + public int getExceptionCode() { + return EXCEPTION_CODE; + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java new file mode 100644 index 00000000..67e1c9df --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java @@ -0,0 +1,17 @@ +package com.amido.stacks.workloads.menu.exception; + +import com.amido.stacks.core.api.exception.ApiException; + +public class MenuApiException extends ApiException { + + private static final int EXCEPTION_CODE = 10000; + + public MenuApiException(String message) { + super(message, 0, ""); + } + + @Override + public int getExceptionCode() { + return EXCEPTION_CODE; + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java new file mode 100644 index 00000000..bfad753c --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java @@ -0,0 +1,17 @@ +package com.amido.stacks.workloads.menu.exception; + +import java.util.UUID; + +public class MenuNotFoundException extends MenuApiException { + + private static final int EXCEPTION_CODE = 10404; + + public MenuNotFoundException(UUID menuId) { + super(String.format("A menu with id '%s' does not exist.", menuId)); + } + + @Override + public int getExceptionCode() { + return EXCEPTION_CODE; + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java new file mode 100644 index 00000000..8f46d902 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java @@ -0,0 +1,68 @@ +package com.amido.stacks.workloads.menu.exception.handler; + +import com.amido.stacks.core.api.dto.ErrorResponse; +import com.amido.stacks.workloads.menu.exception.CategoryAlreadyExistsException; +import com.amido.stacks.workloads.menu.exception.CategoryDoesNotExistException; +import com.amido.stacks.workloads.menu.exception.ItemAlreadyExistsException; +import com.amido.stacks.workloads.menu.exception.ItemDoesNotExistsException; +import com.amido.stacks.workloads.menu.exception.MenuAlreadyExistsException; +import com.amido.stacks.workloads.menu.exception.MenuNotFoundException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +@RequestMapping(produces = "application/json") +public class MenuApiExceptionHandler { + + @ResponseBody + @ExceptionHandler(MenuAlreadyExistsException.class) + @ResponseStatus(HttpStatus.CONFLICT) + ErrorResponse menuAlreadyExistsExceptionHandler(MenuAlreadyExistsException ex) { + return new ErrorResponse( + ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + } + + @ResponseBody + @ExceptionHandler(MenuNotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + ErrorResponse menuNotFoundExceptionHandler(MenuNotFoundException ex) { + return new ErrorResponse( + ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + } + + @ResponseBody + @ExceptionHandler(CategoryAlreadyExistsException.class) + @ResponseStatus(HttpStatus.CONFLICT) + ErrorResponse categoryAlreadyExistsExceptionHandler(CategoryAlreadyExistsException ex) { + return new ErrorResponse( + ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + } + + @ResponseBody + @ExceptionHandler(CategoryDoesNotExistException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + ErrorResponse categoryNotFoundExceptionHandler(CategoryDoesNotExistException ex) { + return new ErrorResponse( + ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + } + + @ResponseBody + @ExceptionHandler(ItemAlreadyExistsException.class) + @ResponseStatus(HttpStatus.CONFLICT) + ErrorResponse itemAlreadyExistsExceptionHandler(ItemAlreadyExistsException ex) { + return new ErrorResponse( + ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + } + + @ResponseBody + @ExceptionHandler(ItemDoesNotExistsException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + ErrorResponse itemDontNotExistsExceptionHandler(ItemDoesNotExistsException ex) { + return new ErrorResponse( + ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateCategoryMapper.java b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateCategoryMapper.java new file mode 100644 index 00000000..7c6db8e9 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateCategoryMapper.java @@ -0,0 +1,13 @@ +package com.amido.stacks.workloads.menu.mappers.wrappers; + +import com.amido.stacks.core.mapping.BaseMapper; +import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateCategoryRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.CategoryDTO; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; + +@Mapper( + componentModel = "spring", + uses = {}, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface CreateCategoryMapper extends BaseMapper {} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateItemMapper.java b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateItemMapper.java new file mode 100644 index 00000000..26c5706c --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateItemMapper.java @@ -0,0 +1,13 @@ +package com.amido.stacks.workloads.menu.mappers.wrappers; + +import com.amido.stacks.core.mapping.BaseMapper; +import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateItemRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.ItemDTO; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; + +@Mapper( + componentModel = "spring", + uses = {}, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface CreateItemMapper extends BaseMapper {} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateMenuMapper.java b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateMenuMapper.java new file mode 100644 index 00000000..b22cf321 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/CreateMenuMapper.java @@ -0,0 +1,23 @@ +package com.amido.stacks.workloads.menu.mappers.wrappers; + +import com.amido.stacks.core.mapping.BaseMapper; +import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateMenuRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; + +@Mapper( + componentModel = "spring", + uses = {}, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface CreateMenuMapper extends BaseMapper { + + @Override + @Mapping(source = "restaurantId", target = "tenantId") + CreateMenuRequest toDto(MenuDTO command); + + @Override + @Mapping(source = "tenantId", target = "restaurantId") + MenuDTO fromDto(CreateMenuRequest request); +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateCategoryMapper.java b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateCategoryMapper.java new file mode 100644 index 00000000..33f0c251 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateCategoryMapper.java @@ -0,0 +1,13 @@ +package com.amido.stacks.workloads.menu.mappers.wrappers; + +import com.amido.stacks.core.mapping.BaseMapper; +import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateCategoryRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.CategoryDTO; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; + +@Mapper( + componentModel = "spring", + uses = {}, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface UpdateCategoryMapper extends BaseMapper {} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateItemMapper.java b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateItemMapper.java new file mode 100644 index 00000000..0b7b1c97 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateItemMapper.java @@ -0,0 +1,13 @@ +package com.amido.stacks.workloads.menu.mappers.wrappers; + +import com.amido.stacks.core.mapping.BaseMapper; +import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateItemRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.ItemDTO; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; + +@Mapper( + componentModel = "spring", + uses = {}, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface UpdateItemMapper extends BaseMapper {} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateMenuMapper.java b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateMenuMapper.java new file mode 100644 index 00000000..6034db81 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/mappers/wrappers/UpdateMenuMapper.java @@ -0,0 +1,13 @@ +package com.amido.stacks.workloads.menu.mappers.wrappers; + +import com.amido.stacks.core.mapping.BaseMapper; +import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateMenuRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; + +@Mapper( + componentModel = "spring", + uses = {}, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface UpdateMenuMapper extends BaseMapper {} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/repository/MenuRepository.java b/java/src/main/java/com/amido/stacks/workloads/menu/repository/MenuRepository.java new file mode 100644 index 00000000..aabd549d --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/repository/MenuRepository.java @@ -0,0 +1,56 @@ +package com.amido.stacks.workloads.menu.repository; + +import com.amido.stacks.workloads.menu.domain.Menu; +import com.azure.spring.data.cosmos.repository.CosmosRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Repository; + +@Repository +public interface MenuRepository extends CosmosRepository { + + @Override + Menu save(Menu menu); + + /** + * Query is constructed OOTB- out of the box, executed and results are fetched based param + * restaurantId. Pagination and sorting is done by spring data JPA. + * + * @param restaurantId tenantID/RestaurantId + * @return page of menu + */ + Page findAllByRestaurantId(String restaurantId, Pageable pageable); + + /** + * Query is constructed OOTB - out of the box, executed and results are fetched based param + * searchTerm. Pagination and sorting is done by spring data JPA. + * + * @param searchTerm Menu name + * @param pageable pagination + * @return page of menu + */ + Page findAllByNameContaining(String searchTerm, Pageable pageable); + + /** + * Query is constructed OOTB - out of the box, executed and results are fetched based param + * restaurantId and searchTerm. Pagination and sorting is done by spring data JPA. + * + * @param restaurantId tenantID/RestaurantId + * @param searchTerm Menu name + * @param pageable pagination + * @return page of menu + */ + Page findAllByRestaurantIdAndNameContaining( + String restaurantId, String searchTerm, Pageable pageable); + + /** + * Query is constructed OOTB - out of the box, executed and results are fetched based param + * restaurantId and searchTerm. Pagination and sorting is done by spring data JPA. + * + * @param restaurantId + * @param name + * @param pageable + * @return + */ + Page findAllByRestaurantIdAndName(String restaurantId, String name, Pageable pageable); +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryService.java new file mode 100644 index 00000000..faa2e74f --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryService.java @@ -0,0 +1,76 @@ +package com.amido.stacks.workloads.menu.service.data; + +import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class CosmosMenuQueryService implements MenuQueryService { + + private static final String NAME = "name"; + + private final MenuRepository menuRepository; + + @Override + public Optional findById(UUID id) { + return menuRepository.findById(id.toString()); + } + + @Override + public List findAll(int pageNumber, int pageSize) { + + Page page = + menuRepository.findAll(PageRequest.of(0, pageSize, Sort.by(Sort.Direction.ASC, NAME))); + + // This is specific and needed due to the way in which CosmosDB handles pagination + // using a continuationToken and a limitation in the Swagger Specification. + // See https://github.com/Azure/azure-sdk-for-java/issues/12726 + int currentPage = 0; + while (currentPage < pageNumber && page.hasNext()) { + currentPage++; + Pageable nextPageable = page.nextPageable(); + page = menuRepository.findAll(nextPageable); + } + return page.getContent(); + } + + @Override + public List findAllByRestaurantId(UUID restaurantId, Integer pageSize, Integer pageNumber) { + + return menuRepository + .findAllByRestaurantId( + restaurantId.toString(), PageRequest.of(0, pageSize, Sort.by(Sort.Direction.ASC, NAME))) + .getContent(); + } + + @Override + public List findAllByNameContaining( + String searchTerm, Integer pageSize, Integer pageNumber) { + + return menuRepository + .findAllByNameContaining( + searchTerm, PageRequest.of(0, pageSize, Sort.by(Sort.Direction.ASC, NAME))) + .getContent(); + } + + @Override + public List findAllByRestaurantIdAndNameContaining( + UUID restaurantId, String searchTerm, Integer pageSize, Integer pageNumber) { + + return menuRepository + .findAllByRestaurantIdAndNameContaining( + restaurantId.toString(), + searchTerm, + PageRequest.of(0, pageSize, Sort.by(Sort.Direction.ASC, NAME))) + .getContent(); + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/data/MenuQueryService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/data/MenuQueryService.java new file mode 100644 index 00000000..7ab88441 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/data/MenuQueryService.java @@ -0,0 +1,61 @@ +package com.amido.stacks.workloads.menu.service.data; + +import com.amido.stacks.workloads.menu.domain.Menu; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface MenuQueryService { + + /** + * Retrieve list of all available Menus + * + * @param pageNumber pageNo + * @param pageSize page Size + * @return List of MenuDTO + */ + List findAll(int pageNumber, int pageSize); + + /** + * Retrieve MenuDTO by MenuDTO Id + * + * @param id menu Id + * @return Optional MenuDTO + */ + Optional findById(UUID id); + + /** + * Retrieve MenuDTO by Restaurant Id Pagination and sorting is done by spring data JPA. + * + * @param restaurantId restaurant id + * @param pageSize page size + * @param pageNumber page no + * @return List of MenuDTO + */ + public List findAllByRestaurantId(UUID restaurantId, Integer pageSize, Integer pageNumber); + + /** + * Retrieve MenuDTO's by matching the name (Contains operation) Pagination and sorting is done by + * spring data JPA. + * + * @param searchTerm menu name + * @param pageSize page size + * @param pageNumber page no + * @return List of MenuDTO + */ + public List findAllByNameContaining( + String searchTerm, Integer pageSize, Integer pageNumber); + + /** + * Retrieve MenuDTO's by matching the name and the restaurantId (Contains operation) Pagination + * and sorting is done by spring data JPA. + * + * @param restaurantId restaurant id + * @param searchTerm menu name + * @param pageSize page size + * @param pageNumber page no + * @return List of MenuDTO + */ + List findAllByRestaurantIdAndNameContaining( + UUID restaurantId, String searchTerm, Integer pageSize, Integer pageNumber); +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java index 772ded52..62abcd73 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java @@ -1,9 +1,21 @@ package com.amido.stacks.workloads.menu.service.v1; +import static java.util.UUID.randomUUID; + import com.amido.stacks.core.api.dto.response.ResourceCreatedResponse; import com.amido.stacks.core.api.dto.response.ResourceUpdatedResponse; import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateCategoryRequest; import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateCategoryRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.CategoryDTO; +import com.amido.stacks.workloads.menu.domain.Category; +import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.exception.MenuNotFoundException; +import com.amido.stacks.workloads.menu.mappers.CategoryMapper; +import com.amido.stacks.workloads.menu.mappers.wrappers.CreateCategoryMapper; +import com.amido.stacks.workloads.menu.mappers.wrappers.UpdateCategoryMapper; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; +import com.amido.stacks.workloads.menu.service.v1.utility.MenuHelperService; +import java.util.Optional; import java.util.UUID; import javax.validation.Valid; import lombok.RequiredArgsConstructor; @@ -13,12 +25,71 @@ @RequiredArgsConstructor public class CategoryService { - public ResourceCreatedResponse create(@Valid CreateCategoryRequest body, String correlationId) { - return new ResourceCreatedResponse(UUID.randomUUID()); + private final MenuQueryService menuQueryService; + + private final MenuHelperService menuHelperService; + + private final CategoryMapper categoryMapper; + + private final CreateCategoryMapper createCategoryMapper; + + private final UpdateCategoryMapper updateCategoryMapper; + + public ResourceCreatedResponse create(UUID menuId, @Valid CreateCategoryRequest body) { + + Menu menu = getMenu(menuId); + + UUID categoryId = randomUUID(); + + menuHelperService.verifyCategoryNameNotAlreadyExisting(menu, categoryId, body.getName()); + + CategoryDTO categoryDTO = createCategoryMapper.fromDto(body); + categoryDTO.setId(categoryId.toString()); + + menuHelperService.addOrUpdateCategory(menu, categoryMapper.fromDto(categoryDTO)); + menuHelperService.save(menu); + + return new ResourceCreatedResponse(categoryId); } public ResourceUpdatedResponse update( - UUID menuId, UUID categoryId, @Valid UpdateCategoryRequest body, String correlationId) { - return new ResourceUpdatedResponse(UUID.randomUUID()); + UUID menuId, UUID categoryId, @Valid UpdateCategoryRequest body) { + + Menu menu = getMenu(menuId); + + Category category = menuHelperService.checkCategoryExistsById(menu, categoryId); + + menuHelperService.verifyCategoryNameNotAlreadyExisting(menu, categoryId, body.getName()); + + CategoryDTO updatedDTO = updateCategoryMapper.fromDto(body); + updatedDTO.setId(categoryId.toString()); + + Category updatedCategory = categoryMapper.fromDto(updatedDTO); + updatedCategory.setItems(category.getItems()); + + menuHelperService.addOrUpdateCategory(menu, updatedCategory); + menuHelperService.save(menu); + + return new ResourceUpdatedResponse(categoryId); + } + + public void delete(UUID menuId, UUID categoryId) { + + Menu menu = getMenu(menuId); + + menuHelperService.checkCategoryExistsById(menu, categoryId); + + menuHelperService.removeCategory(menu, categoryId); + menuHelperService.save(menu); + } + + private Menu getMenu(UUID menuId) { + Optional optMenu = menuQueryService.findById(menuId); + + if (optMenu.isEmpty()) { + throw new MenuNotFoundException(menuId); + } + + return optMenu.get(); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java index 46d25bce..60b799f9 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java @@ -4,20 +4,95 @@ import com.amido.stacks.core.api.dto.response.ResourceUpdatedResponse; import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateItemRequest; import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateItemRequest; +import com.amido.stacks.workloads.menu.api.v1.dto.response.ItemDTO; +import com.amido.stacks.workloads.menu.domain.Category; +import com.amido.stacks.workloads.menu.domain.Item; +import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.exception.MenuNotFoundException; +import com.amido.stacks.workloads.menu.mappers.ItemMapper; +import com.amido.stacks.workloads.menu.mappers.wrappers.CreateItemMapper; +import com.amido.stacks.workloads.menu.mappers.wrappers.UpdateItemMapper; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; +import com.amido.stacks.workloads.menu.service.v1.utility.MenuHelperService; +import java.util.Optional; import java.util.UUID; import javax.validation.Valid; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @Service +@RequiredArgsConstructor public class ItemService { + private final MenuQueryService menuQueryService; + + private final MenuHelperService menuHelperService; + + private final CreateItemMapper createItemMapper; + + private final UpdateItemMapper updateItemMapper; + + private final ItemMapper itemMapper; + public ResourceCreatedResponse create( - UUID menuId, UUID categoryId, @Valid CreateItemRequest body, String correlationId) { - return new ResourceCreatedResponse(UUID.randomUUID()); + UUID menuId, UUID categoryId, @Valid CreateItemRequest body) { + + Menu menu = getMenu(menuId); + + Category category = menuHelperService.checkCategoryExistsById(menu, categoryId); + + UUID itemId = UUID.randomUUID(); + + menuHelperService.verifyItemNameNotAlreadyExisting(menuId, category, itemId, body.getName()); + + ItemDTO itemDTO = createItemMapper.fromDto(body); + itemDTO.setId(itemId.toString()); + + menuHelperService.addOrUpdateItem(category, itemMapper.fromDto(itemDTO)); + menuHelperService.save(menu); + + return new ResourceCreatedResponse(itemId); } public ResourceUpdatedResponse update( - UUID menuId, UUID categoryId, @Valid UpdateItemRequest body, String correlationId) { - return new ResourceUpdatedResponse(UUID.randomUUID()); + UUID menuId, UUID categoryId, UUID itemId, @Valid UpdateItemRequest body) { + + Menu menu = getMenu(menuId); + + Category category = menuHelperService.checkCategoryExistsById(menu, categoryId); + + Item item = menuHelperService.checkItemExistsById(menuId, category, itemId); + + menuHelperService.verifyItemNameNotAlreadyExisting(menuId, category, itemId, body.getName()); + + ItemDTO itemDTO = updateItemMapper.fromDto(body); + itemDTO.setId(item.getId()); + + menuHelperService.addOrUpdateItem(category, itemMapper.fromDto(itemDTO)); + menuHelperService.save(menu); + + return new ResourceUpdatedResponse(itemId); + } + + public void delete(UUID menuId, UUID categoryId, UUID itemId) { + + Menu menu = getMenu(menuId); + + Category category = menuHelperService.checkCategoryExistsById(menu, categoryId); + + menuHelperService.checkItemExistsById(menuId, category, itemId); + + menuHelperService.removeItem(category, itemId); + menuHelperService.save(menu); + } + + private Menu getMenu(UUID menuId) { + Optional optMenu = menuQueryService.findById(menuId); + + if (optMenu.isEmpty()) { + throw new MenuNotFoundException(menuId); + } + + return optMenu.get(); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java index 36f57b67..30ff4fec 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java @@ -1,84 +1,130 @@ package com.amido.stacks.workloads.menu.service.v1; -import com.amido.stacks.core.api.dto.response.ResourceCreatedResponse; -import com.amido.stacks.core.api.dto.response.ResourceUpdatedResponse; +import static java.util.Objects.nonNull; +import static java.util.UUID.fromString; +import static java.util.UUID.randomUUID; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; + import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateMenuRequest; import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateMenuRequest; import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; import com.amido.stacks.workloads.menu.api.v1.dto.response.SearchMenuResult; -import com.amido.stacks.workloads.menu.domain.Category; -import com.amido.stacks.workloads.menu.domain.Item; import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.exception.MenuAlreadyExistsException; +import com.amido.stacks.workloads.menu.exception.MenuNotFoundException; import com.amido.stacks.workloads.menu.mappers.MenuMapper; import com.amido.stacks.workloads.menu.mappers.SearchMenuResultItemMapper; -import java.util.ArrayList; +import com.amido.stacks.workloads.menu.mappers.wrappers.CreateMenuMapper; +import com.amido.stacks.workloads.menu.mappers.wrappers.UpdateMenuMapper; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; import java.util.List; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import javax.validation.Valid; -import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class MenuService { - @Getter private final MenuMapper menuMapper; + private final MenuRepository menuRepository; + + private final MenuQueryService menuQueryService; + + private final MenuMapper menuMapper; + + private final CreateMenuMapper createMenuMapper; + + private final UpdateMenuMapper updateMenuMapper; private final SearchMenuResultItemMapper searchMenuResultItemMapper; - public ResourceCreatedResponse create(@Valid CreateMenuRequest body, String correlationId) { + public MenuDTO create(@Valid CreateMenuRequest dto) { + + verifyMenuNotAlreadyExisting(dto.getTenantId(), dto.getName()); + + MenuDTO menuDTO = createMenuMapper.fromDto(dto); + menuDTO.setId(randomUUID()); - return new ResourceCreatedResponse(UUID.randomUUID()); + return (menuMapper.toDto(menuRepository.save(menuMapper.fromDto(menuDTO)))); } public SearchMenuResult search( String searchTerm, UUID restaurantId, Integer pageSize, Integer pageNumber) { - List menuList = new ArrayList<>(); + List menuList; - final String menuId = "d5785e28-306b-4e23-add0-3f9092d395f8"; - - Menu mockMenu; - if (restaurantId == null) { - mockMenu = - new Menu( - menuId, - "58a1df85-6bdc-412a-a118-0f0e394c1342", - "name", - "description", - new ArrayList<>(), - true); + if (isNotEmpty(searchTerm) && nonNull(restaurantId)) { + menuList = + this.menuQueryService.findAllByRestaurantIdAndNameContaining( + restaurantId, searchTerm, pageSize, pageNumber); + } else if (isNotEmpty(searchTerm)) { + menuList = this.menuQueryService.findAllByNameContaining(searchTerm, pageSize, pageNumber); + } else if (nonNull(restaurantId)) { + menuList = this.menuQueryService.findAllByRestaurantId(restaurantId, pageSize, pageNumber); } else { - mockMenu = - new Menu(menuId, restaurantId.toString(), "name", "description", new ArrayList<>(), true); + menuList = this.menuQueryService.findAll(pageNumber, pageSize); } - menuList.add(mockMenu); - return new SearchMenuResult( pageSize, pageNumber, menuList.stream().map(searchMenuResultItemMapper::toDto).collect(Collectors.toList())); } - public MenuDTO get(UUID id, String correlationId) { + public MenuDTO get(UUID menuId) { - final String restaurantId = "58a1df85-6bdc-412a-a118-0f0e394c1342"; - final String categoryId = "2c43dbda-7d4d-46fb-b246-bec2bd348ca1"; - final String itemId = "7e46a698-080b-45e6-a529-2c196d00791c"; + Optional optMenu = menuQueryService.findById(menuId); - Menu menu = - new Menu(id.toString(), restaurantId, "name", "description", new ArrayList<>(), true); - Item item = new Item(itemId, "item name", "item description", 5.99d, true); - Category category = new Category(categoryId, "cat name", "cat description", List.of(item)); - menu.addOrUpdateCategory(category); + if (optMenu.isPresent()) { + return menuMapper.toDto(optMenu.get()); + } - return menuMapper.toDto(menu); + throw new MenuNotFoundException(menuId); } - public ResourceUpdatedResponse update(@Valid UpdateMenuRequest body, String correlationId) { - return new ResourceUpdatedResponse(UUID.randomUUID()); + public MenuDTO update(UUID menuId, @Valid UpdateMenuRequest dto) { + + Optional optMenu = menuQueryService.findById(menuId); + + if (optMenu.isPresent()) { + + MenuDTO menuDTO = updateMenuMapper.fromDto(dto); + menuDTO.setId(menuId); + menuDTO.setRestaurantId(fromString(optMenu.get().getRestaurantId())); + + menuRepository.save(menuMapper.fromDto(menuDTO)); + + return get(menuId); + } + + throw new MenuNotFoundException(menuId); + } + + public void verifyMenuNotAlreadyExisting(UUID restaurantId, String name) { + Page existing = + menuRepository.findAllByRestaurantIdAndName( + restaurantId.toString(), name, PageRequest.of(0, 1)); + + if (!existing.getContent().isEmpty() + && existing.get().anyMatch(m -> m.getName().equals(name))) { + throw new MenuAlreadyExistsException(restaurantId, name); + } + } + + public void delete(UUID menuId) { + + Optional optMenu = menuQueryService.findById(menuId); + + if (optMenu.isEmpty()) { + throw new MenuNotFoundException(menuId); + } + + menuRepository.delete(optMenu.get()); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java new file mode 100644 index 00000000..c8e07b71 --- /dev/null +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java @@ -0,0 +1,110 @@ +package com.amido.stacks.workloads.menu.service.v1.utility; + +import com.amido.stacks.workloads.menu.domain.Category; +import com.amido.stacks.workloads.menu.domain.Item; +import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.exception.CategoryAlreadyExistsException; +import com.amido.stacks.workloads.menu.exception.CategoryDoesNotExistException; +import com.amido.stacks.workloads.menu.exception.ItemAlreadyExistsException; +import com.amido.stacks.workloads.menu.exception.ItemDoesNotExistsException; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MenuHelperService { + + private final MenuRepository menuRepository; + + public void addOrUpdateCategory(Menu menu, Category category) { + if (menu.getCategories() == null) { + menu.setCategories(new ArrayList<>()); + } + + List newCategories = + menu.getCategories().stream() + .filter(c -> !c.getId().equals(category.getId())) + .collect(Collectors.toList()); + + newCategories.add(category); + + menu.setCategories(newCategories); + } + + public void addOrUpdateItem(Category category, Item item) { + + if (category.getItems() == null) { + category.setItems(new ArrayList<>()); + } + + List newItems = + category.getItems().stream() + .filter(c -> !c.getId().equals(item.getId())) + .collect(Collectors.toList()); + + newItems.add(item); + + category.setItems(newItems); + } + + public Category checkCategoryExistsById(Menu menu, UUID categoryId) { + Optional optCategory = + menu.getCategories().stream() + .filter(c -> categoryId.toString().equals(c.getId())) + .findFirst(); + + if (optCategory.isEmpty()) { + throw new CategoryDoesNotExistException(UUID.fromString(menu.getId()), categoryId); + } + + return optCategory.get(); + } + + public Item checkItemExistsById(UUID menuId, Category category, UUID itemId) { + Optional optItem = + category.getItems().stream().filter(i -> itemId.toString().equals(i.getId())).findFirst(); + + if (optItem.isEmpty()) { + throw new ItemDoesNotExistsException(menuId, UUID.fromString(category.getId()), itemId); + } + + return optItem.get(); + } + + public void verifyCategoryNameNotAlreadyExisting(Menu menu, UUID categoryId, String name) { + Optional optCategory = + menu.getCategories().stream().filter(c -> c.getName().equals(name)).findFirst(); + + if (optCategory.isPresent() && !optCategory.get().getId().equals(categoryId.toString())) { + throw new CategoryAlreadyExistsException(UUID.fromString(menu.getId()), name); + } + } + + public void verifyItemNameNotAlreadyExisting( + UUID menuId, Category category, UUID itemId, String name) { + Optional optItem = + category.getItems().stream().filter(c -> c.getName().equals(name)).findFirst(); + + if (optItem.isPresent() && !optItem.get().getId().equals(itemId.toString())) { + throw new ItemAlreadyExistsException(menuId, UUID.fromString(category.getId()), name); + } + } + + public void removeItem(Category category, UUID itemId) { + category.getItems().removeIf(i -> i.getId().equals(itemId.toString())); + } + + public void removeCategory(Menu menu, UUID categoryId) { + menu.getCategories().removeIf(c -> c.getId().equals(categoryId.toString())); + } + + public Menu save(Menu menu) { + return menuRepository.save(menu); + } +} diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java index a1614641..f24da897 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java @@ -1,11 +1,13 @@ package com.amido.stacks.workloads.menu.service.v2; import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; -import com.amido.stacks.workloads.menu.domain.Menu; import com.amido.stacks.workloads.menu.mappers.MenuMapper; import com.amido.stacks.workloads.menu.mappers.SearchMenuResultItemMapper; +import com.amido.stacks.workloads.menu.mappers.wrappers.CreateMenuMapper; +import com.amido.stacks.workloads.menu.mappers.wrappers.UpdateMenuMapper; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; import com.amido.stacks.workloads.menu.service.v1.MenuService; -import java.util.ArrayList; import java.util.UUID; import org.springframework.stereotype.Service; @@ -13,19 +15,24 @@ public class MenuServiceV2 extends MenuService { public MenuServiceV2( - MenuMapper menuMapper, SearchMenuResultItemMapper searchMenuResultItemMapper) { - super(menuMapper, searchMenuResultItemMapper); + MenuRepository menuRepository, + MenuQueryService menuQueryService, + MenuMapper menuMapper, + CreateMenuMapper createMenuMapper, + UpdateMenuMapper updateMenuMapper, + SearchMenuResultItemMapper searchMenuResultItemMapper) { + super( + menuRepository, + menuQueryService, + menuMapper, + createMenuMapper, + updateMenuMapper, + searchMenuResultItemMapper); } @Override - public MenuDTO get(UUID id, String correlationId) { + public MenuDTO get(UUID id) { - String restaurantId = "3930ddff-82ce-4f7e-b910-b0709b276cf0"; - - Menu menu = - new Menu( - id.toString(), restaurantId, "0 Menu", "0 Menu Description", new ArrayList<>(), true); - - return getMenuMapper().toDto(menu); + return super.get(id); } } diff --git a/java/src/main/resources/application.yml b/java/src/main/resources/application.yml index 524dda51..befb04a1 100644 --- a/java/src/main/resources/application.yml +++ b/java/src/main/resources/application.yml @@ -33,6 +33,10 @@ springdoc: path: /swagger/oas-json azure: + cosmos: + uri: https://localhost:8081 + database: Stacks + key: ${COSMOSDB_KEY} application-insights: instrumentation-key: xxxxxx enabled: true @@ -41,4 +45,4 @@ azure: uri: https://amido-stacks-tmp.vault.azure.net/ client-id: xxxxxx client-key: xxxxxx - tenant-id: xxxxxx + tenant-id: xxxxxx \ No newline at end of file diff --git a/java/src/main/resources/lombok.config b/java/src/main/resources/lombok.config new file mode 100644 index 00000000..7a21e880 --- /dev/null +++ b/java/src/main/resources/lombok.config @@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation = true diff --git a/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java b/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java index db8f210d..6e43486e 100644 --- a/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java +++ b/java/src/test/java/com/amido/stacks/workloads/actuator/ActuatorTest.java @@ -3,6 +3,11 @@ import static com.amido.stacks.workloads.util.TestHelper.getBaseURL; import static org.assertj.core.api.BDDAssertions.then; +import com.amido.stacks.workloads.Application; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import com.azure.spring.autoconfigure.cosmos.CosmosAutoConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosHealthConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosRepositoriesAutoConfiguration; import java.util.Map; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -10,13 +15,21 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.test.context.TestPropertySource; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = Application.class) @TestPropertySource(properties = {"management.port=0"}) -@EnableAutoConfiguration +@EnableAutoConfiguration( + exclude = { + CosmosRepositoriesAutoConfiguration.class, + CosmosAutoConfiguration.class, + CosmosHealthConfiguration.class + }) @Tag("Component") class ActuatorTest { @@ -25,6 +38,8 @@ class ActuatorTest { @Autowired private TestRestTemplate testRestTemplate; + @MockBean private MenuRepository menuRepository; + @Test void shouldReturn200WhenSendingRequestToHealthEndpoint() { diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/CategoryControllerTest.java b/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/CategoryControllerTest.java index 687b048d..8c329e74 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/CategoryControllerTest.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/CategoryControllerTest.java @@ -8,22 +8,38 @@ import static com.amido.stacks.workloads.util.TestHelper.getRequestHttpEntity; import static java.util.UUID.fromString; import static org.assertj.core.api.BDDAssertions.then; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.NOT_FOUND; import static org.springframework.http.HttpStatus.OK; import com.amido.stacks.core.api.dto.ErrorResponse; import com.amido.stacks.core.api.dto.response.ResourceCreatedResponse; import com.amido.stacks.core.api.dto.response.ResourceUpdatedResponse; +import com.amido.stacks.workloads.Application; import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateCategoryRequest; import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateCategoryRequest; import com.amido.stacks.workloads.menu.domain.Category; import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; +import com.amido.stacks.workloads.menu.service.v1.CategoryService; +import com.amido.stacks.workloads.menu.service.v1.utility.MenuHelperService; +import com.azure.spring.autoconfigure.cosmos.CosmosAutoConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosHealthConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosRepositoriesAutoConfiguration; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpEntity; @@ -31,8 +47,15 @@ import org.springframework.http.HttpStatus; import org.springframework.test.context.ActiveProfiles; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnableAutoConfiguration +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = {Application.class}) +@EnableAutoConfiguration( + exclude = { + CosmosRepositoriesAutoConfiguration.class, + CosmosAutoConfiguration.class, + CosmosHealthConfiguration.class + }) @Tag("Integration") @ActiveProfiles("test") public class CategoryControllerTest { @@ -47,8 +70,16 @@ public class CategoryControllerTest { @Autowired private TestRestTemplate testRestTemplate; + @Autowired private CategoryService categoryService; + + @Autowired private MenuHelperService menuHelperService; + + @MockBean private MenuRepository menuRepository; + + @MockBean private MenuQueryService menuQueryService; + @Test - void testInvalidMenuIdWilThrowBadRequest() { + void testInvalidMenuIdWillThrowBadRequest() { // Given CreateCategoryRequest request = new CreateCategoryRequest("test Category Name", ""); @@ -72,6 +103,9 @@ void testAddCategory() { CreateCategoryRequest request = new CreateCategoryRequest("test Category Name", "test Category Description"); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + // When var response = this.testRestTemplate.postForEntity( @@ -90,10 +124,13 @@ void testUpdateCategorySuccess() { // Given Menu menu = createMenu(0); Category category = createCategory(0); - menu.addOrUpdateCategory(category); + menuHelperService.addOrUpdateCategory(menu, category); UpdateCategoryRequest request = new UpdateCategoryRequest("new Category", "new Description"); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + // When String requestUrl = String.format( @@ -114,6 +151,38 @@ void testUpdateCategorySuccess() { then(response.getStatusCode()).isEqualTo(OK); } + @Test + void testUpdateCategoryFailure() { + // Given + Menu menu = createMenu(0); + Category category = createCategory(0); + menuHelperService.addOrUpdateCategory(menu, category); + + UpdateCategoryRequest request = new UpdateCategoryRequest("new Category", "new Description"); + + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.empty()); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + + // When + String requestUrl = + String.format( + UPDATE_CATEGORY, + getBaseURL(port), + fromString(menu.getId()), + fromString(category.getId())); + + var response = + this.testRestTemplate.exchange( + requestUrl, + HttpMethod.PUT, + new HttpEntity<>(request, getRequestHttpEntity()), + ResourceUpdatedResponse.class); + + // Then + then(response).isNotNull(); + then(response.getStatusCode()).isEqualTo(NOT_FOUND); + } + @Test void testUpdateCategoryWhenMultipleCategoriesExists() { // Given @@ -123,6 +192,9 @@ void testUpdateCategoryWhenMultipleCategoriesExists() { UpdateCategoryRequest request = new UpdateCategoryRequest("new Category", "new Description"); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + // When String requestUrl = String.format(UPDATE_CATEGORY, getBaseURL(port), menu.getId(), categories.get(0).getId()); @@ -149,6 +221,9 @@ void testUpdateOnlyCategoryDescription() { UpdateCategoryRequest request = new UpdateCategoryRequest(categoryList.get(1).getName(), "new Description"); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + // When String requestUrl = String.format( @@ -173,7 +248,12 @@ void testDeleteCategorySuccess() { // Given Menu menu = createMenu(1); Category category = createCategory(0); - menu.setCategories(List.of(category)); + List categories = new ArrayList<>(); + categories.add(category); + menu.setCategories(categories); + + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + doNothing().when(menuRepository).delete(any(Menu.class)); // When String requestUrl = @@ -194,8 +274,11 @@ void testDeleteCategoryWithAnItem() { // Given Menu menu = createMenu(1); Category category = createCategory(0); - category.addOrUpdateItem(createItem(0)); - menu.addOrUpdateCategory(category); + menuHelperService.addOrUpdateItem(category, createItem(0)); + menuHelperService.addOrUpdateCategory(menu, category); + + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + doNothing().when(menuRepository).delete(any(Menu.class)); // When String requestUrl = @@ -218,6 +301,9 @@ void testDeleteACategoryFromList() { List categories = createCategories(2); menu.setCategories(categories); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + doNothing().when(menuRepository).delete(any(Menu.class)); + // When String requestUrl = String.format(DELETE_CATEGORY, getBaseURL(port), menu.getId(), categories.get(0).getId()); diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/ItemControllerTest.java b/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/ItemControllerTest.java index 422b76c3..57685d90 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/ItemControllerTest.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/ItemControllerTest.java @@ -8,25 +8,38 @@ import static com.amido.stacks.workloads.util.TestHelper.getRequestHttpEntity; import static java.util.UUID.randomUUID; import static org.assertj.core.api.BDDAssertions.then; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.NOT_FOUND; import static org.springframework.http.HttpStatus.OK; import com.amido.stacks.core.api.dto.ErrorResponse; import com.amido.stacks.core.api.dto.response.ResourceCreatedResponse; import com.amido.stacks.core.api.dto.response.ResourceUpdatedResponse; +import com.amido.stacks.workloads.Application; import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateItemRequest; import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateItemRequest; import com.amido.stacks.workloads.menu.domain.Category; import com.amido.stacks.workloads.menu.domain.Item; import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; +import com.amido.stacks.workloads.menu.service.v1.CategoryService; +import com.amido.stacks.workloads.menu.service.v1.utility.MenuHelperService; +import com.azure.spring.autoconfigure.cosmos.CosmosAutoConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosHealthConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosRepositoriesAutoConfiguration; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpEntity; @@ -35,8 +48,15 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnableAutoConfiguration +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = {Application.class}) +@EnableAutoConfiguration( + exclude = { + CosmosRepositoriesAutoConfiguration.class, + CosmosAutoConfiguration.class, + CosmosHealthConfiguration.class + }) @Tag("Integration") @ActiveProfiles("test") public class ItemControllerTest { @@ -51,17 +71,28 @@ public class ItemControllerTest { @Autowired private TestRestTemplate testRestTemplate; + @Autowired private MenuHelperService menuHelperService; + + @Autowired private CategoryService categoryService; + + @MockBean private MenuRepository menuRepository; + + @MockBean private MenuQueryService menuQueryService; + @Test void testAddItem() { // Given Menu menu = createMenu(1); Category category = new Category(randomUUID().toString(), "cat name", "cat description", new ArrayList<>()); - menu.addOrUpdateCategory(category); + menuHelperService.addOrUpdateCategory(menu, category); CreateItemRequest request = new CreateItemRequest("Some Name", "Some Description", 13.56d, true); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + // When var response = this.testRestTemplate.postForEntity( @@ -77,7 +108,7 @@ void testAddItem() { } @Test - void testInvalidCategoryIdWilThrowBadRequest() { + void testInvalidCategoryIdWillThrowBadRequest() { // Given CreateItemRequest request = @@ -101,8 +132,8 @@ void testUpdateItemSuccess() { Menu menu = createMenu(0); Category category = createCategory(0); Item item = createItem(0); - category.addOrUpdateItem(item); - menu.addOrUpdateCategory(category); + menuHelperService.addOrUpdateItem(category, item); + menuHelperService.addOrUpdateCategory(menu, category); UpdateItemRequest request = new UpdateItemRequest("Some Name", "Some Description", 13.56d, true); @@ -111,6 +142,9 @@ void testUpdateItemSuccess() { String requestUrl = String.format(UPDATE_ITEM, getBaseURL(port), menu.getId(), category.getId(), item.getId()); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + var response = this.testRestTemplate.exchange( requestUrl, @@ -123,6 +157,37 @@ void testUpdateItemSuccess() { then(response.getStatusCode()).isEqualTo(OK); } + @Test + void testUpdateItemFailure() { + // Given + Menu menu = createMenu(0); + Category category = createCategory(0); + Item item = createItem(0); + menuHelperService.addOrUpdateItem(category, item); + menuHelperService.addOrUpdateCategory(menu, category); + + UpdateItemRequest request = + new UpdateItemRequest("Some Name", "Some Description", 13.56d, true); + + // When + String requestUrl = + String.format(UPDATE_ITEM, getBaseURL(port), menu.getId(), category.getId(), item.getId()); + + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.empty()); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + + var response = + this.testRestTemplate.exchange( + requestUrl, + HttpMethod.PUT, + new HttpEntity<>(request, getRequestHttpEntity()), + ResourceUpdatedResponse.class); + + // Then + then(response).isNotNull(); + then(response.getStatusCode()).isEqualTo(NOT_FOUND); + } + @Test void testUpdateItemDescription() { // Given @@ -130,7 +195,7 @@ void testUpdateItemDescription() { Category category = createCategory(0); List items = createItems(2); category.setItems(items); - menu.addOrUpdateCategory(category); + menuHelperService.addOrUpdateCategory(menu, category); UpdateItemRequest request = new UpdateItemRequest(items.get(0).getName(), "Some Description2", 13.56d, true); @@ -140,6 +205,9 @@ void testUpdateItemDescription() { String.format( UPDATE_ITEM, getBaseURL(port), menu.getId(), category.getId(), items.get(0).getId()); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + var response = this.testRestTemplate.exchange( requestUrl, @@ -158,13 +226,16 @@ void testDeleteItemSuccess() { Menu menu = createMenu(1); Category category = createCategory(0); Item item = new Item(UUID.randomUUID().toString(), "New Item", "Item description", 12.2d, true); - category.addOrUpdateItem(item); - menu.addOrUpdateCategory(category); + menuHelperService.addOrUpdateItem(category, item); + menuHelperService.addOrUpdateCategory(menu, category); // When String requestUrl = String.format(DELETE_ITEM, getBaseURL(port), menu.getId(), category.getId(), item.getId()); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + var response = this.testRestTemplate.exchange( requestUrl, diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/MenuControllerTest.java b/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/MenuControllerTest.java index 6e0c7ac4..fe3674dc 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/MenuControllerTest.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/api/v1/MenuControllerTest.java @@ -8,12 +8,17 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsNull.notNullValue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; +import static org.springframework.http.HttpStatus.NOT_FOUND; import static org.springframework.http.HttpStatus.OK; import com.amido.stacks.core.api.dto.response.ResourceCreatedResponse; import com.amido.stacks.core.api.dto.response.ResourceUpdatedResponse; +import com.amido.stacks.workloads.Application; import com.amido.stacks.workloads.menu.api.v1.dto.request.CreateMenuRequest; -import com.amido.stacks.workloads.menu.api.v1.dto.request.UpdateMenuRequest; import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; import com.amido.stacks.workloads.menu.api.v1.dto.response.SearchMenuResult; import com.amido.stacks.workloads.menu.api.v1.dto.response.SearchMenuResultItem; @@ -24,10 +29,18 @@ import com.amido.stacks.workloads.menu.mappers.ItemMapper; import com.amido.stacks.workloads.menu.mappers.MenuMapper; import com.amido.stacks.workloads.menu.mappers.SearchMenuResultItemMapper; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; +import com.amido.stacks.workloads.menu.service.v1.MenuService; +import com.amido.stacks.workloads.menu.service.v1.utility.MenuHelperService; +import com.azure.spring.autoconfigure.cosmos.CosmosAutoConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosHealthConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosRepositoriesAutoConfiguration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import org.junit.jupiter.api.Tag; @@ -35,16 +48,26 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnableAutoConfiguration +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = {Application.class}) +@EnableAutoConfiguration( + exclude = { + CosmosRepositoriesAutoConfiguration.class, + CosmosAutoConfiguration.class, + CosmosHealthConfiguration.class + }) @Tag("Integration") @ActiveProfiles("test") public class MenuControllerTest { @@ -62,6 +85,10 @@ public class MenuControllerTest { @Autowired private TestRestTemplate testRestTemplate; + @Autowired private MenuService menuService; + + @Autowired private MenuHelperService menuHelperService; + @Autowired private MenuMapper menuMapper; @Autowired private CategoryMapper categoryMapper; @@ -70,6 +97,10 @@ public class MenuControllerTest { @Autowired private SearchMenuResultItemMapper searchMenuResultItemMapper; + @MockBean private MenuRepository menuRepository; + + @MockBean private MenuQueryService menuQueryService; + @Test void testCreateNewMenu() { // Given @@ -78,6 +109,11 @@ void testCreateNewMenu() { new CreateMenuRequest( m.getName(), m.getDescription(), UUID.fromString(m.getRestaurantId()), m.getEnabled()); + when(menuRepository.findAllByRestaurantIdAndName( + eq(m.getRestaurantId()), eq(m.getName()), any(Pageable.class))) + .thenReturn(new PageImpl<>(Collections.emptyList())); + when(menuRepository.save(any(Menu.class))).thenReturn(m); + // When var response = this.testRestTemplate.postForEntity( @@ -87,6 +123,31 @@ void testCreateNewMenu() { then(response.getStatusCode()).isEqualTo(HttpStatus.CREATED); } + @Test + void testCreateNewMenuFails() { + // Given + Menu m = createMenu(1); + CreateMenuRequest request = + new CreateMenuRequest( + m.getName(), m.getDescription(), UUID.fromString(m.getRestaurantId()), m.getEnabled()); + + List existing = new ArrayList<>(); + existing.add(m); + + when(menuRepository.findAllByRestaurantIdAndName( + eq(m.getRestaurantId()), eq(m.getName()), any(Pageable.class))) + .thenReturn(new PageImpl<>(existing)); + when(menuRepository.save(any(Menu.class))).thenReturn(m); + + // When + var response = + this.testRestTemplate.postForEntity( + getBaseURL(port) + CREATE_MENU, request, ResourceCreatedResponse.class); + + // Then + then(response.getStatusCode()).isEqualTo(HttpStatus.CONFLICT); + } + @Test public void listMenusAndPagination() { @@ -95,6 +156,9 @@ public void listMenusAndPagination() { int pageNumber = 5; int pageSize = 6; + when(menuQueryService.findAll(any(Integer.class), any(Integer.class))) + .thenReturn(new ArrayList<>()); + // When var response = this.testRestTemplate.getForEntity( @@ -131,6 +195,10 @@ public void listMenusFilteredByRestaurantId() { SearchMenuResult expectedResponse = new SearchMenuResult(DEFAULT_PAGE_SIZE, DEFAULT_PAGE_NUMBER, expectedMenuList); + when(menuQueryService.findAllByRestaurantId( + eq(UUID.fromString(restaurantId)), any(Integer.class), any(Integer.class))) + .thenReturn(menuList); + // When var result = this.testRestTemplate.getForEntity( @@ -142,6 +210,83 @@ public void listMenusFilteredByRestaurantId() { then(result.getBody().getResults()).containsAll(expectedResponse.getResults()); } + @Test + public void listMenusFilteredByRestaurantName() { + + // Given + final String menuId = "d5785e28-306b-4e23-add0-3f9092d395f8"; + final String restaurantId = "58a1df85-6bdc-412a-a118-0f0e394c1342"; + + List menuList = createMenus(3); + Menu match = new Menu(menuId, restaurantId, "name", "description", new ArrayList<>(), true); + match.setRestaurantId(restaurantId); + menuList.add(match); + List matching = Collections.singletonList(match); + + List expectedMenuList = + matching.stream() + .map(m -> searchMenuResultItemMapper.toDto(m)) + .collect(Collectors.toList()); + + SearchMenuResult expectedResponse = + new SearchMenuResult(DEFAULT_PAGE_SIZE, DEFAULT_PAGE_NUMBER, expectedMenuList); + + when(menuQueryService.findAllByNameContaining( + eq(match.getName()), any(Integer.class), any(Integer.class))) + .thenReturn(menuList); + + // When + var result = + this.testRestTemplate.getForEntity( + String.format("%s/v1/menu?searchTerm=%s", getBaseURL(port), match.getName()), + SearchMenuResult.class); + // Then + then(result.getBody().getPageNumber()).isEqualTo(expectedResponse.getPageNumber()); + then(result.getBody().getPageSize()).isEqualTo(expectedResponse.getPageSize()); + then(result.getBody().getResults()).containsAll(expectedResponse.getResults()); + } + + @Test + public void listMenusFilteredByRestaurantNameAndId() { + + // Given + final String menuId = "d5785e28-306b-4e23-add0-3f9092d395f8"; + final String restaurantId = "58a1df85-6bdc-412a-a118-0f0e394c1342"; + + List menuList = createMenus(3); + Menu match = new Menu(menuId, restaurantId, "name", "description", new ArrayList<>(), true); + match.setRestaurantId(restaurantId); + menuList.add(match); + List matching = Collections.singletonList(match); + + List expectedMenuList = + matching.stream() + .map(m -> searchMenuResultItemMapper.toDto(m)) + .collect(Collectors.toList()); + + SearchMenuResult expectedResponse = + new SearchMenuResult(DEFAULT_PAGE_SIZE, DEFAULT_PAGE_NUMBER, expectedMenuList); + + when(menuQueryService.findAllByRestaurantIdAndNameContaining( + eq(UUID.fromString(restaurantId)), + eq(match.getName()), + any(Integer.class), + any(Integer.class))) + .thenReturn(menuList); + + // When + var result = + this.testRestTemplate.getForEntity( + String.format( + "%s/v1/menu?restaurantId=%s&searchTerm=%s", + getBaseURL(port), restaurantId, match.getName()), + SearchMenuResult.class); + // Then + then(result.getBody().getPageNumber()).isEqualTo(expectedResponse.getPageNumber()); + then(result.getBody().getPageSize()).isEqualTo(expectedResponse.getPageSize()); + then(result.getBody().getResults()).containsAll(expectedResponse.getResults()); + } + @Test public void getMenuById() { // Given @@ -154,10 +299,12 @@ public void getMenuById() { Item item = new Item(itemId, "item name", "item description", 5.99d, true); Category category = new Category(categoryId, "cat name", "cat description", Arrays.asList(item)); - menu.addOrUpdateCategory(category); + menuHelperService.addOrUpdateCategory(menu, category); MenuDTO expectedResponse = menuMapper.toDto(menu); + when(menuQueryService.findById(UUID.fromString(menuId))).thenReturn(Optional.of(menu)); + // When var response = this.testRestTemplate.getForEntity( @@ -167,6 +314,22 @@ public void getMenuById() { then(response.getBody()).isEqualTo(expectedResponse); } + @Test + public void getMenuByIdNotFound() { + // Given + final String menuId = "d5785e28-306b-4e23-add0-3f9092d395f8"; + + when(menuQueryService.findById(UUID.fromString(menuId))).thenReturn(Optional.empty()); + + // When + var response = + this.testRestTemplate.getForEntity( + String.format("%s/v1/menu/%s", getBaseURL(port), menuId), MenuDTO.class); + + // Then + then(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + } + @Test public void listMenusWithDefaultPagination() { @@ -187,7 +350,12 @@ void testUpdateSuccess() { // Given Menu menu = createMenu(0); - UpdateMenuRequest request = new UpdateMenuRequest("new name", "new description", false); + MenuDTO request = new MenuDTO(); + request.setName("new name"); + request.setDescription("new description"); + request.setEnabled(false); + + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); // When var response = @@ -202,11 +370,38 @@ void testUpdateSuccess() { then(response.getStatusCode()).isEqualTo(HttpStatus.OK); } + @Test + void testUpdateFailure() { + // Given + Menu menu = createMenu(0); + + MenuDTO request = new MenuDTO(); + request.setName("new name"); + request.setDescription("new description"); + request.setEnabled(false); + + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.empty()); + + // When + var response = + this.testRestTemplate.exchange( + String.format(UPDATE_MENU, getBaseURL(port), menu.getId()), + HttpMethod.PUT, + new HttpEntity<>(request, getRequestHttpEntity()), + ResourceUpdatedResponse.class); + + // Then + then(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + } + @Test void testDeleteMenuSuccess() { // Given Menu menu = createMenu(1); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + doNothing().when(menuRepository).delete(any(Menu.class)); + var response = this.testRestTemplate.exchange( String.format(DELETE_MENU, getBaseURL(port), menu.getId()), @@ -216,4 +411,23 @@ void testDeleteMenuSuccess() { // Then then(response.getStatusCode()).isEqualTo(OK); } + + @Test + void testDeleteMenuFailure() { + // Given + Menu menu = createMenu(1); + + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.empty()); + doNothing().when(menuRepository).delete(any(Menu.class)); + + var response = + this.testRestTemplate.exchange( + String.format(DELETE_MENU, getBaseURL(port), menu.getId()), + HttpMethod.DELETE, + new HttpEntity<>(getRequestHttpEntity()), + Void.class); + + // Then + then(response.getStatusCode()).isEqualTo(NOT_FOUND); + } } diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2Test.java b/java/src/test/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2Test.java index f78959b6..ca7df17d 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2Test.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2Test.java @@ -3,21 +3,36 @@ import static com.amido.stacks.workloads.menu.domain.MenuHelper.createMenu; import static com.amido.stacks.workloads.util.TestHelper.getBaseURL; import static org.assertj.core.api.BDDAssertions.then; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; import com.amido.stacks.workloads.menu.domain.Menu; import com.amido.stacks.workloads.menu.mappers.MenuMapper; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import com.amido.stacks.workloads.menu.service.data.MenuQueryService; +import com.azure.spring.autoconfigure.cosmos.CosmosAutoConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosHealthConfiguration; +import com.azure.spring.autoconfigure.cosmos.CosmosRepositoriesAutoConfiguration; +import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.ActiveProfiles; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnableAutoConfiguration +@EnableAutoConfiguration( + exclude = { + CosmosRepositoriesAutoConfiguration.class, + CosmosAutoConfiguration.class, + CosmosHealthConfiguration.class + }) @Tag("Integration") @ActiveProfiles("test") public class MenuControllerV2Test { @@ -30,6 +45,10 @@ public class MenuControllerV2Test { @Autowired private MenuMapper menuMapper; + @MockBean private MenuRepository menuRepository; + + @MockBean private MenuQueryService menuQueryService; + @Test void getMenuById() { // Given @@ -38,6 +57,9 @@ void getMenuById() { menu.setRestaurantId(restaurantId); MenuDTO expectedResponse = menuMapper.toDto(menu); + when(menuQueryService.findById(UUID.fromString(menu.getId()))).thenReturn(Optional.of(menu)); + when(menuRepository.save(any(Menu.class))).thenReturn(menu); + // When var response = this.testRestTemplate.getForEntity( diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java b/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java index beaf6179..421d56e5 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java @@ -4,7 +4,9 @@ import java.util.List; import java.util.UUID; -/** @author ArathyKrishna */ +/** + * @author ArathyKrishna + */ public class MenuHelper { public static List createMenus(int count) { @@ -21,7 +23,7 @@ public static Menu createMenu(int counter) { UUID.randomUUID().toString(), counter + " Menu", counter + " Menu Description", - new ArrayList(), + new ArrayList<>(), true); } } diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java b/java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java new file mode 100644 index 00000000..7c3ec71c --- /dev/null +++ b/java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java @@ -0,0 +1,144 @@ +package com.amido.stacks.workloads.menu.service.data; + +import static org.assertj.core.api.BDDAssertions.then; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +import com.amido.stacks.workloads.menu.domain.Menu; +import com.amido.stacks.workloads.menu.domain.MenuHelper; +import com.amido.stacks.workloads.menu.repository.MenuRepository; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; + +@Tag("Unit") +public class CosmosMenuQueryServiceTest { + + @Test + void findById() { + MenuRepository repository = mock(MenuRepository.class); + MenuQueryService menuQueryService = new CosmosMenuQueryService(repository); + + Menu menu = MenuHelper.createMenu(1); + + given(repository.findById(anyString())).willReturn(Optional.of(menu)); + + Optional optMenu = menuQueryService.findById(UUID.randomUUID()); + + then(optMenu).isNotEmpty(); + then(optMenu.get()).isEqualTo(menu); + } + + @Test + void findAll() { + + MenuRepository repository = mock(MenuRepository.class); + MenuQueryService menuQueryService = new CosmosMenuQueryService(repository); + + Pageable pageable = mock(Pageable.class); + + List results = MenuHelper.createMenus(2); + Page page1 = new PageImpl<>(results, pageable, 2); + Page page2 = new PageImpl<>(results, pageable, 2); + + // Given + given(repository.findAll(any(Pageable.class))).willReturn(page1); + given(repository.findAll(eq(pageable))).willReturn(page2); + + // When + List actualResults = menuQueryService.findAll(2, 5); + + // Then + then(actualResults).isEqualTo(results); + } + + @Test + void findAllByRestaurantId() { + + MenuRepository repository = mock(MenuRepository.class); + MenuQueryService menuQueryService = new CosmosMenuQueryService(repository); + + Pageable pageable = mock(Pageable.class); + + List results = MenuHelper.createMenus(2); + Page page1 = new PageImpl<>(results, pageable, 2); + Page page2 = new PageImpl<>(results, pageable, 2); + + UUID restaurantId = UUID.randomUUID(); + + // Given + given(repository.findAllByRestaurantId(eq(restaurantId.toString()), any(Pageable.class))) + .willReturn(page1); + given(repository.findAll(eq(pageable))).willReturn(page2); + + // When + List actualResults = menuQueryService.findAllByRestaurantId(restaurantId, 2, 5); + + // Then + then(actualResults).isEqualTo(results); + } + + @Test + void findAllByNameContaining() { + + MenuRepository repository = mock(MenuRepository.class); + MenuQueryService menuQueryService = new CosmosMenuQueryService(repository); + + Pageable pageable = mock(Pageable.class); + + List results = MenuHelper.createMenus(2); + Page page1 = new PageImpl<>(results, pageable, 2); + Page page2 = new PageImpl<>(results, pageable, 2); + + String searchTerm = "SICB"; + + // Given + given(repository.findAllByNameContaining(eq(searchTerm), any(Pageable.class))) + .willReturn(page1); + given(repository.findAll(eq(pageable))).willReturn(page2); + + // When + List actualResults = menuQueryService.findAllByNameContaining(searchTerm, 2, 5); + + // Then + then(actualResults).isEqualTo(results); + } + + @Test + void findAllByRestaurantIdAndNameContaining() { + + MenuRepository repository = mock(MenuRepository.class); + MenuQueryService menuQueryService = new CosmosMenuQueryService(repository); + + Pageable pageable = mock(Pageable.class); + + List results = MenuHelper.createMenus(2); + Page page1 = new PageImpl<>(results, pageable, 2); + Page page2 = new PageImpl<>(results, pageable, 2); + + String searchTerm = "SICB"; + UUID restaurantId = UUID.randomUUID(); + + // Given + given( + repository.findAllByRestaurantIdAndNameContaining( + eq(restaurantId.toString()), eq(searchTerm), any(Pageable.class))) + .willReturn(page1); + given(repository.findAll(eq(pageable))).willReturn(page2); + + // When + List actualResults = + menuQueryService.findAllByRestaurantIdAndNameContaining(restaurantId, searchTerm, 2, 5); + + // Then + then(actualResults).isEqualTo(results); + } +} From db5642e9d8452c42c8518a4667af6d430db8fb6e Mon Sep 17 00:00:00 2001 From: Steve Davis Date: Wed, 20 Jul 2022 17:23:36 +0100 Subject: [PATCH 2/7] Fixed linting --- .../workloads/menu/exception/ItemDoesNotExistsException.java | 3 --- java/src/main/resources/application.yml | 2 +- .../com/amido/stacks/workloads/menu/domain/MenuHelper.java | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java index 4dabc7d7..806bdd84 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java @@ -2,9 +2,6 @@ import java.util.UUID; -/** - * @author ArathyKrishna - */ public class ItemDoesNotExistsException extends MenuApiException { private static final int EXCEPTION_CODE = 12404; diff --git a/java/src/main/resources/application.yml b/java/src/main/resources/application.yml index befb04a1..60f769a9 100644 --- a/java/src/main/resources/application.yml +++ b/java/src/main/resources/application.yml @@ -45,4 +45,4 @@ azure: uri: https://amido-stacks-tmp.vault.azure.net/ client-id: xxxxxx client-key: xxxxxx - tenant-id: xxxxxx \ No newline at end of file + tenant-id: xxxxxx diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java b/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java index 421d56e5..4e057c73 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/domain/MenuHelper.java @@ -4,9 +4,6 @@ import java.util.List; import java.util.UUID; -/** - * @author ArathyKrishna - */ public class MenuHelper { public static List createMenus(int count) { From fca5ae5a813c68c290edad343907e4802b1e25a5 Mon Sep 17 00:00:00 2001 From: Steve Davis Date: Wed, 20 Jul 2022 18:15:38 +0100 Subject: [PATCH 3/7] Cleaned code smells --- java/pom.xml | 9 --------- .../CategoryAlreadyExistsException.java | 3 +-- .../CategoryDoesNotExistException.java | 3 +-- .../exception/ItemAlreadyExistsException.java | 3 +-- .../exception/ItemDoesNotExistsException.java | 3 +-- .../exception/MenuAlreadyExistsException.java | 3 +-- .../menu/exception/MenuApiException.java | 7 ++----- .../menu/exception/MenuNotFoundException.java | 3 +-- .../handler/MenuApiExceptionHandler.java | 18 ++++++------------ 9 files changed, 14 insertions(+), 38 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index d9bba81a..e72dfe9a 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -236,15 +236,6 @@ provided - - org.springframework.boot spring-boot-starter-test diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java index 689c583c..3fe29666 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryAlreadyExistsException.java @@ -2,7 +2,7 @@ import java.util.UUID; -public class CategoryAlreadyExistsException extends MenuApiException { +public class CategoryAlreadyExistsException extends RuntimeException { private static final int EXCEPTION_CODE = 11409; @@ -13,7 +13,6 @@ public CategoryAlreadyExistsException(UUID menuId, String name) { name, menuId)); } - @Override public int getExceptionCode() { return EXCEPTION_CODE; } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java index f7b3be0f..2e9583d3 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/CategoryDoesNotExistException.java @@ -2,7 +2,7 @@ import java.util.UUID; -public class CategoryDoesNotExistException extends MenuApiException { +public class CategoryDoesNotExistException extends RuntimeException { private static final int EXCEPTION_CODE = 11404; @@ -13,7 +13,6 @@ public CategoryDoesNotExistException(UUID menuId, UUID categoryId) { categoryId, menuId)); } - @Override public int getExceptionCode() { return EXCEPTION_CODE; } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java index 334cd827..2f94fc43 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemAlreadyExistsException.java @@ -2,7 +2,7 @@ import java.util.UUID; -public class ItemAlreadyExistsException extends MenuApiException { +public class ItemAlreadyExistsException extends RuntimeException { private static final int EXCEPTION_CODE = 12409; @@ -14,7 +14,6 @@ public ItemAlreadyExistsException(UUID menuId, UUID categoryId, String name) { name, categoryId, menuId)); } - @Override public int getExceptionCode() { return EXCEPTION_CODE; } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java index 806bdd84..a495bfce 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/ItemDoesNotExistsException.java @@ -2,7 +2,7 @@ import java.util.UUID; -public class ItemDoesNotExistsException extends MenuApiException { +public class ItemDoesNotExistsException extends RuntimeException { private static final int EXCEPTION_CODE = 12404; @@ -13,7 +13,6 @@ public ItemDoesNotExistsException(UUID menuId, UUID categoryId, UUID itemId) { itemId, categoryId, menuId)); } - @Override public int getExceptionCode() { return EXCEPTION_CODE; } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java index f8d9c682..fea0ccda 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuAlreadyExistsException.java @@ -2,7 +2,7 @@ import java.util.UUID; -public class MenuAlreadyExistsException extends MenuApiException { +public class MenuAlreadyExistsException extends RuntimeException { private static final int EXCEPTION_CODE = 10409; @@ -13,7 +13,6 @@ public MenuAlreadyExistsException(UUID restaurantId, String name) { name, restaurantId)); } - @Override public int getExceptionCode() { return EXCEPTION_CODE; } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java index 67e1c9df..2090e963 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuApiException.java @@ -1,16 +1,13 @@ package com.amido.stacks.workloads.menu.exception; -import com.amido.stacks.core.api.exception.ApiException; - -public class MenuApiException extends ApiException { +public class MenuApiException extends RuntimeException { private static final int EXCEPTION_CODE = 10000; public MenuApiException(String message) { - super(message, 0, ""); + super(message); } - @Override public int getExceptionCode() { return EXCEPTION_CODE; } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java index bfad753c..441e8479 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/MenuNotFoundException.java @@ -2,7 +2,7 @@ import java.util.UUID; -public class MenuNotFoundException extends MenuApiException { +public class MenuNotFoundException extends RuntimeException { private static final int EXCEPTION_CODE = 10404; @@ -10,7 +10,6 @@ public MenuNotFoundException(UUID menuId) { super(String.format("A menu with id '%s' does not exist.", menuId)); } - @Override public int getExceptionCode() { return EXCEPTION_CODE; } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java b/java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java index 8f46d902..c2d5d145 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/exception/handler/MenuApiExceptionHandler.java @@ -22,47 +22,41 @@ public class MenuApiExceptionHandler { @ExceptionHandler(MenuAlreadyExistsException.class) @ResponseStatus(HttpStatus.CONFLICT) ErrorResponse menuAlreadyExistsExceptionHandler(MenuAlreadyExistsException ex) { - return new ErrorResponse( - ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + return new ErrorResponse(ex.getExceptionCode(), 0, "", ex.getMessage()); } @ResponseBody @ExceptionHandler(MenuNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) ErrorResponse menuNotFoundExceptionHandler(MenuNotFoundException ex) { - return new ErrorResponse( - ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + return new ErrorResponse(ex.getExceptionCode(), 0, "", ex.getMessage()); } @ResponseBody @ExceptionHandler(CategoryAlreadyExistsException.class) @ResponseStatus(HttpStatus.CONFLICT) ErrorResponse categoryAlreadyExistsExceptionHandler(CategoryAlreadyExistsException ex) { - return new ErrorResponse( - ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + return new ErrorResponse(ex.getExceptionCode(), 0, "", ex.getMessage()); } @ResponseBody @ExceptionHandler(CategoryDoesNotExistException.class) @ResponseStatus(HttpStatus.NOT_FOUND) ErrorResponse categoryNotFoundExceptionHandler(CategoryDoesNotExistException ex) { - return new ErrorResponse( - ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + return new ErrorResponse(ex.getExceptionCode(), 0, "", ex.getMessage()); } @ResponseBody @ExceptionHandler(ItemAlreadyExistsException.class) @ResponseStatus(HttpStatus.CONFLICT) ErrorResponse itemAlreadyExistsExceptionHandler(ItemAlreadyExistsException ex) { - return new ErrorResponse( - ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + return new ErrorResponse(ex.getExceptionCode(), 0, "", ex.getMessage()); } @ResponseBody @ExceptionHandler(ItemDoesNotExistsException.class) @ResponseStatus(HttpStatus.NOT_FOUND) ErrorResponse itemDontNotExistsExceptionHandler(ItemDoesNotExistsException ex) { - return new ErrorResponse( - ex.getExceptionCode(), ex.getOperationCode(), ex.getCorrelationId(), ex.getMessage()); + return new ErrorResponse(ex.getExceptionCode(), 0, "", ex.getMessage()); } } From c7b8f1f65e4cf9fb1b3b97a13ce7473921498716 Mon Sep 17 00:00:00 2001 From: Steve Davis Date: Thu, 21 Jul 2022 06:06:40 +0100 Subject: [PATCH 4/7] Updated version for OpenUI to resolve snyk issue --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index e72dfe9a..d529374a 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -26,7 +26,7 @@ 11 1.18.0 - 1.6.1 + 1.6.4 2.6.4 3.6.0 3.6.0 From 71c7973eb6ccf3d25fa39516efdfbc9f57f909dc Mon Sep 17 00:00:00 2001 From: Steve Davis Date: Thu, 21 Jul 2022 06:42:06 +0100 Subject: [PATCH 5/7] Updated version for OpenUI to resolve snyk issue --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index d529374a..c4bd0874 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -26,7 +26,7 @@ 11 1.18.0 - 1.6.4 + 1.6.9 2.6.4 3.6.0 3.6.0 From e079a5edd3b3ff580908d75d7252143bf0083b66 Mon Sep 17 00:00:00 2001 From: Steve Davis Date: Thu, 21 Jul 2022 10:14:55 +0100 Subject: [PATCH 6/7] Added CorrelationId back in --- .../menu/api/v1/CategoryController.java | 18 +++++++---- .../workloads/menu/api/v1/ItemController.java | 17 +++++++---- .../workloads/menu/api/v1/MenuController.java | 30 ++++++++++++------- .../menu/api/v2/MenuControllerV2.java | 8 +++-- .../menu/service/v1/CategoryService.java | 7 +++-- .../menu/service/v1/ItemService.java | 10 +++++-- .../menu/service/v1/MenuService.java | 16 ++++++---- .../menu/service/v2/MenuServiceV2.java | 4 +-- 8 files changed, 71 insertions(+), 39 deletions(-) diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java index f4b2ae99..bf650902 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/CategoryController.java @@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -44,9 +45,11 @@ public class CategoryController { @CreateAPIResponses ResponseEntity createCategory( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, - @Valid @RequestBody CreateCategoryRequest body) { + @Valid @RequestBody CreateCategoryRequest body, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return new ResponseEntity<>(categoryService.create(menuId, body), HttpStatus.CREATED); + return new ResponseEntity<>( + categoryService.create(menuId, body, correlationId), HttpStatus.CREATED); } @PutMapping("/{categoryId}") @@ -60,9 +63,11 @@ ResponseEntity updateCategory( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, - @Valid @RequestBody UpdateCategoryRequest body) { + @Valid @RequestBody UpdateCategoryRequest body, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return new ResponseEntity<>(categoryService.update(menuId, categoryId, body), OK); + return new ResponseEntity<>( + categoryService.update(menuId, categoryId, body, correlationId), OK); } @DeleteMapping("/{categoryId}") @@ -75,9 +80,10 @@ ResponseEntity updateCategory( ResponseEntity deleteCategory( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") - UUID categoryId) { + UUID categoryId, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - categoryService.delete(menuId, categoryId); + categoryService.delete(menuId, categoryId, correlationId); return new ResponseEntity<>(OK); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java index 5f411dec..ae2e3163 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/ItemController.java @@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -46,9 +47,11 @@ ResponseEntity createItem( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, - @Valid @RequestBody CreateItemRequest body) { + @Valid @RequestBody CreateItemRequest body, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return new ResponseEntity<>(itemService.create(menuId, categoryId, body), HttpStatus.CREATED); + return new ResponseEntity<>( + itemService.create(menuId, categoryId, body, correlationId), HttpStatus.CREATED); } @PutMapping("/{itemId}") @@ -63,10 +66,11 @@ ResponseEntity updateItem( @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, @Parameter(description = "Item id", required = true) @PathVariable("itemId") UUID itemId, - @Valid @RequestBody UpdateItemRequest body) { + @Valid @RequestBody UpdateItemRequest body, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { return new ResponseEntity<>( - itemService.update(menuId, categoryId, itemId, body), HttpStatus.OK); + itemService.update(menuId, categoryId, itemId, body, correlationId), HttpStatus.OK); } @DeleteMapping("/{itemId}") @@ -80,9 +84,10 @@ ResponseEntity deleteItem( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, @Parameter(description = "Category id", required = true) @PathVariable("categoryId") UUID categoryId, - @Parameter(description = "Item id", required = true) @PathVariable("itemId") UUID itemId) { + @Parameter(description = "Item id", required = true) @PathVariable("itemId") UUID itemId, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - itemService.delete(menuId, categoryId, itemId); + itemService.delete(menuId, categoryId, itemId, correlationId); return new ResponseEntity<>(OK); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java index 7636f18c..bc649a3a 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v1/MenuController.java @@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -45,9 +46,11 @@ public class MenuController { description = "Adds a menu", operationId = "CreateMenu") @CreateAPIResponses - ResponseEntity createMenu(@Valid @RequestBody CreateMenuRequest dto) { + ResponseEntity createMenu( + @Valid @RequestBody CreateMenuRequest dto, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return new ResponseEntity<>(menuService.create(dto), HttpStatus.CREATED); + return new ResponseEntity<>(menuService.create(dto, correlationId), HttpStatus.CREATED); } @GetMapping @@ -68,10 +71,11 @@ ResponseEntity searchMenu( @RequestParam(value = "searchTerm", required = false) String searchTerm, @RequestParam(value = "restaurantId", required = false) UUID restaurantId, @RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize, - @RequestParam(value = "pageNumber", required = false, defaultValue = "1") - Integer pageNumber) { + @RequestParam(value = "pageNumber", required = false, defaultValue = "1") Integer pageNumber, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return ResponseEntity.ok(menuService.search(searchTerm, restaurantId, pageSize, pageNumber)); + return ResponseEntity.ok( + menuService.search(searchTerm, restaurantId, pageSize, pageNumber, correlationId)); } @GetMapping(value = "/{id}") @@ -88,9 +92,11 @@ ResponseEntity searchMenu( mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = MenuDTO.class))) @ReadAPIResponses - ResponseEntity getMenu(@PathVariable(name = "id") UUID id) { + ResponseEntity getMenu( + @PathVariable(name = "id") UUID id, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return ResponseEntity.ok(menuService.get(id)); + return ResponseEntity.ok(menuService.get(id, correlationId)); } @PutMapping(value = "/{id}") @@ -101,9 +107,10 @@ ResponseEntity getMenu(@PathVariable(name = "id") UUID id) { @UpdateAPIResponses ResponseEntity updateMenu( @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, - @Valid @RequestBody UpdateMenuRequest body) { + @Valid @RequestBody UpdateMenuRequest body, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return new ResponseEntity<>(menuService.update(menuId, body), HttpStatus.OK); + return new ResponseEntity<>(menuService.update(menuId, body, correlationId), HttpStatus.OK); } @DeleteMapping(value = "/{id}") @@ -114,9 +121,10 @@ ResponseEntity updateMenu( operationId = "DeleteMenu") @DeleteAPIResponses ResponseEntity deleteMenu( - @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId) { + @Parameter(description = "Menu id", required = true) @PathVariable("id") UUID menuId, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - menuService.delete(menuId); + menuService.delete(menuId, correlationId); return new ResponseEntity<>(HttpStatus.OK); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java b/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java index fb6772d0..a53e562a 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/api/v2/MenuControllerV2.java @@ -4,6 +4,7 @@ import com.amido.stacks.workloads.menu.api.v1.dto.response.MenuDTO; import com.amido.stacks.workloads.menu.service.v2.MenuServiceV2; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -13,6 +14,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -38,8 +40,10 @@ public class MenuControllerV2 { mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = MenuDTO.class))) @ReadAPIResponses - ResponseEntity getMenu(@PathVariable(name = "id") UUID id) { + ResponseEntity getMenu( + @PathVariable(name = "id") UUID id, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { - return ResponseEntity.ok(menuServiceV2.get(id)); + return ResponseEntity.ok(menuServiceV2.get(id, correlationId)); } } diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java index 62abcd73..e311ce8c 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java @@ -35,7 +35,8 @@ public class CategoryService { private final UpdateCategoryMapper updateCategoryMapper; - public ResourceCreatedResponse create(UUID menuId, @Valid CreateCategoryRequest body) { + public ResourceCreatedResponse create( + UUID menuId, @Valid CreateCategoryRequest body, String correlationId) { Menu menu = getMenu(menuId); @@ -53,7 +54,7 @@ public ResourceCreatedResponse create(UUID menuId, @Valid CreateCategoryRequest } public ResourceUpdatedResponse update( - UUID menuId, UUID categoryId, @Valid UpdateCategoryRequest body) { + UUID menuId, UUID categoryId, @Valid UpdateCategoryRequest body, String correlationId) { Menu menu = getMenu(menuId); @@ -73,7 +74,7 @@ public ResourceUpdatedResponse update( return new ResourceUpdatedResponse(categoryId); } - public void delete(UUID menuId, UUID categoryId) { + public void delete(UUID menuId, UUID categoryId, String correlationId) { Menu menu = getMenu(menuId); diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java index 60b799f9..c395a8ee 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java @@ -35,7 +35,7 @@ public class ItemService { private final ItemMapper itemMapper; public ResourceCreatedResponse create( - UUID menuId, UUID categoryId, @Valid CreateItemRequest body) { + UUID menuId, UUID categoryId, @Valid CreateItemRequest body, String correlationId) { Menu menu = getMenu(menuId); @@ -55,7 +55,11 @@ public ResourceCreatedResponse create( } public ResourceUpdatedResponse update( - UUID menuId, UUID categoryId, UUID itemId, @Valid UpdateItemRequest body) { + UUID menuId, + UUID categoryId, + UUID itemId, + @Valid UpdateItemRequest body, + String correlationId) { Menu menu = getMenu(menuId); @@ -74,7 +78,7 @@ public ResourceUpdatedResponse update( return new ResourceUpdatedResponse(itemId); } - public void delete(UUID menuId, UUID categoryId, UUID itemId) { + public void delete(UUID menuId, UUID categoryId, UUID itemId, String correlationId) { Menu menu = getMenu(menuId); diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java index 30ff4fec..115250a5 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/MenuService.java @@ -44,7 +44,7 @@ public class MenuService { private final SearchMenuResultItemMapper searchMenuResultItemMapper; - public MenuDTO create(@Valid CreateMenuRequest dto) { + public MenuDTO create(@Valid CreateMenuRequest dto, String correlationId) { verifyMenuNotAlreadyExisting(dto.getTenantId(), dto.getName()); @@ -55,7 +55,11 @@ public MenuDTO create(@Valid CreateMenuRequest dto) { } public SearchMenuResult search( - String searchTerm, UUID restaurantId, Integer pageSize, Integer pageNumber) { + String searchTerm, + UUID restaurantId, + Integer pageSize, + Integer pageNumber, + String correlationId) { List menuList; @@ -77,7 +81,7 @@ public SearchMenuResult search( menuList.stream().map(searchMenuResultItemMapper::toDto).collect(Collectors.toList())); } - public MenuDTO get(UUID menuId) { + public MenuDTO get(UUID menuId, String correlationId) { Optional optMenu = menuQueryService.findById(menuId); @@ -88,7 +92,7 @@ public MenuDTO get(UUID menuId) { throw new MenuNotFoundException(menuId); } - public MenuDTO update(UUID menuId, @Valid UpdateMenuRequest dto) { + public MenuDTO update(UUID menuId, @Valid UpdateMenuRequest dto, String correlationId) { Optional optMenu = menuQueryService.findById(menuId); @@ -100,7 +104,7 @@ public MenuDTO update(UUID menuId, @Valid UpdateMenuRequest dto) { menuRepository.save(menuMapper.fromDto(menuDTO)); - return get(menuId); + return get(menuId, correlationId); } throw new MenuNotFoundException(menuId); @@ -117,7 +121,7 @@ public void verifyMenuNotAlreadyExisting(UUID restaurantId, String name) { } } - public void delete(UUID menuId) { + public void delete(UUID menuId, String correlationId) { Optional optMenu = menuQueryService.findById(menuId); diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java index f24da897..3e472f47 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v2/MenuServiceV2.java @@ -31,8 +31,8 @@ public MenuServiceV2( } @Override - public MenuDTO get(UUID id) { + public MenuDTO get(UUID id, String correlationId) { - return super.get(id); + return super.get(id, correlationId); } } From dcacd59811838ec4fbf6ddb1bdb30ac1e80e571b Mon Sep 17 00:00:00 2001 From: Steve Davis Date: Thu, 21 Jul 2022 10:53:59 +0100 Subject: [PATCH 7/7] Remove repo reference in helper utility --- .../menu/service/v1/CategoryService.java | 9 ++++--- .../menu/service/v1/ItemService.java | 9 ++++--- .../service/v1/utility/MenuHelperService.java | 4 --- .../data/CosmosMenuQueryServiceTest.java | 25 +++++++++++++++++++ 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java index e311ce8c..5cf8c064 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/CategoryService.java @@ -13,6 +13,7 @@ import com.amido.stacks.workloads.menu.mappers.CategoryMapper; import com.amido.stacks.workloads.menu.mappers.wrappers.CreateCategoryMapper; import com.amido.stacks.workloads.menu.mappers.wrappers.UpdateCategoryMapper; +import com.amido.stacks.workloads.menu.repository.MenuRepository; import com.amido.stacks.workloads.menu.service.data.MenuQueryService; import com.amido.stacks.workloads.menu.service.v1.utility.MenuHelperService; import java.util.Optional; @@ -25,6 +26,8 @@ @RequiredArgsConstructor public class CategoryService { + private final MenuRepository menuRepository; + private final MenuQueryService menuQueryService; private final MenuHelperService menuHelperService; @@ -48,7 +51,7 @@ public ResourceCreatedResponse create( categoryDTO.setId(categoryId.toString()); menuHelperService.addOrUpdateCategory(menu, categoryMapper.fromDto(categoryDTO)); - menuHelperService.save(menu); + menuRepository.save(menu); return new ResourceCreatedResponse(categoryId); } @@ -69,7 +72,7 @@ public ResourceUpdatedResponse update( updatedCategory.setItems(category.getItems()); menuHelperService.addOrUpdateCategory(menu, updatedCategory); - menuHelperService.save(menu); + menuRepository.save(menu); return new ResourceUpdatedResponse(categoryId); } @@ -81,7 +84,7 @@ public void delete(UUID menuId, UUID categoryId, String correlationId) { menuHelperService.checkCategoryExistsById(menu, categoryId); menuHelperService.removeCategory(menu, categoryId); - menuHelperService.save(menu); + menuRepository.save(menu); } private Menu getMenu(UUID menuId) { diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java index c395a8ee..a11eee85 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/ItemService.java @@ -12,6 +12,7 @@ import com.amido.stacks.workloads.menu.mappers.ItemMapper; import com.amido.stacks.workloads.menu.mappers.wrappers.CreateItemMapper; import com.amido.stacks.workloads.menu.mappers.wrappers.UpdateItemMapper; +import com.amido.stacks.workloads.menu.repository.MenuRepository; import com.amido.stacks.workloads.menu.service.data.MenuQueryService; import com.amido.stacks.workloads.menu.service.v1.utility.MenuHelperService; import java.util.Optional; @@ -24,6 +25,8 @@ @RequiredArgsConstructor public class ItemService { + private final MenuRepository menuRepository; + private final MenuQueryService menuQueryService; private final MenuHelperService menuHelperService; @@ -49,7 +52,7 @@ public ResourceCreatedResponse create( itemDTO.setId(itemId.toString()); menuHelperService.addOrUpdateItem(category, itemMapper.fromDto(itemDTO)); - menuHelperService.save(menu); + menuRepository.save(menu); return new ResourceCreatedResponse(itemId); } @@ -73,7 +76,7 @@ public ResourceUpdatedResponse update( itemDTO.setId(item.getId()); menuHelperService.addOrUpdateItem(category, itemMapper.fromDto(itemDTO)); - menuHelperService.save(menu); + menuRepository.save(menu); return new ResourceUpdatedResponse(itemId); } @@ -87,7 +90,7 @@ public void delete(UUID menuId, UUID categoryId, UUID itemId, String correlation menuHelperService.checkItemExistsById(menuId, category, itemId); menuHelperService.removeItem(category, itemId); - menuHelperService.save(menu); + menuRepository.save(menu); } private Menu getMenu(UUID menuId) { diff --git a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java index c8e07b71..e3239877 100644 --- a/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java +++ b/java/src/main/java/com/amido/stacks/workloads/menu/service/v1/utility/MenuHelperService.java @@ -103,8 +103,4 @@ public void removeItem(Category category, UUID itemId) { public void removeCategory(Menu menu, UUID categoryId) { menu.getCategories().removeIf(c -> c.getId().equals(categoryId.toString())); } - - public Menu save(Menu menu) { - return menuRepository.save(menu); - } } diff --git a/java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java b/java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java index 7c3ec71c..1cca0742 100644 --- a/java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java +++ b/java/src/test/java/com/amido/stacks/workloads/menu/service/data/CosmosMenuQueryServiceTest.java @@ -60,6 +60,31 @@ void findAll() { then(actualResults).isEqualTo(results); } + @Test + void findAllNextPage() { + + MenuRepository repository = mock(MenuRepository.class); + MenuQueryService menuQueryService = new CosmosMenuQueryService(repository); + + Pageable pageable = mock(Pageable.class); + + List results = MenuHelper.createMenus(2); + Page page1 = new PageImpl<>(results, pageable, 2); + Page page2 = new PageImpl<>(results, pageable, 2); + + Page mockPage1 = (Page) mock(Page.class); + + // Given + given(repository.findAll(any(Pageable.class))).willReturn(page1); + given(repository.findAll(eq(pageable))).willReturn(page2); + + // When + List actualResults = menuQueryService.findAll(2, 5); + + // Then + then(actualResults).isEqualTo(results); + } + @Test void findAllByRestaurantId() {