diff --git a/.vscode/launch.json b/.vscode/launch.json index 5d677fce..d879f47c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -80,6 +80,16 @@ "projectName": "payment-service", "args": "", "envFile": "${workspaceFolder}/.env" + }, + { + "type": "java", + "name": "Spring Boot-TestCatalogServiceApplication", + "request": "launch", + "cwd": "${workspaceFolder}", + "mainClass": "com.example.catalogservice.TestCatalogServiceApplication", + "projectName": "catalog-service", + "args": "", + "envFile": "${workspaceFolder}/.env" } ] } \ No newline at end of file diff --git a/catalog-service/src/main/java/com/example/catalogservice/services/ProductService.java b/catalog-service/src/main/java/com/example/catalogservice/services/ProductService.java index d6cf5d0e..9d6c4a1e 100644 --- a/catalog-service/src/main/java/com/example/catalogservice/services/ProductService.java +++ b/catalog-service/src/main/java/com/example/catalogservice/services/ProductService.java @@ -146,11 +146,27 @@ private Mono getInventoryByProductCode(String code) { } @Observed(name = "product.findByCode", contextualName = "findByProductCode") - public Mono findProductByProductCode(String productCode) { - return productRepository - .findByCodeAllIgnoreCase(productCode) - .map(productMapper::toProductResponse) - .switchIfEmpty(Mono.error(new ProductNotFoundException(productCode))); + public Mono findProductByProductCode( + String productCode, boolean fetchInStock) { + Mono productResponseMono = + productRepository + .findByCodeAllIgnoreCase(productCode) + .map(productMapper::toProductResponse) + .switchIfEmpty(Mono.error(new ProductNotFoundException(productCode))); + + if (fetchInStock) { + return productResponseMono.flatMap(this::fetchInventoryAndUpdateProductResponse); + } + return productResponseMono; + } + + private Mono fetchInventoryAndUpdateProductResponse( + ProductResponse productResponse) { + return getInventoryByProductCode(productResponse.code()) + .map( + inventoryResponse -> + productResponse.withInStock( + inventoryResponse.availableQuantity() > 0)); } // saves product to db and sends message that new product is available for inventory diff --git a/catalog-service/src/main/java/com/example/catalogservice/web/controllers/ProductController.java b/catalog-service/src/main/java/com/example/catalogservice/web/controllers/ProductController.java index 456543ba..7b82ff3b 100644 --- a/catalog-service/src/main/java/com/example/catalogservice/web/controllers/ProductController.java +++ b/catalog-service/src/main/java/com/example/catalogservice/web/controllers/ProductController.java @@ -63,8 +63,11 @@ public Mono> getProductById(@PathVariable Long i @GetMapping("/productCode/{productCode}") public Mono> getProductByProductCode( - @PathVariable String productCode) { - return productService.findProductByProductCode(productCode).map(ResponseEntity::ok); + @PathVariable String productCode, + @RequestParam(required = false) boolean fetchInStock) { + return productService + .findProductByProductCode(productCode, fetchInStock) + .map(ResponseEntity::ok); } @GetMapping("/exists") diff --git a/catalog-service/src/test/java/com/example/catalogservice/web/controllers/ProductControllerIT.java b/catalog-service/src/test/java/com/example/catalogservice/web/controllers/ProductControllerIT.java index ecd1992d..35ebe0f2 100644 --- a/catalog-service/src/test/java/com/example/catalogservice/web/controllers/ProductControllerIT.java +++ b/catalog-service/src/test/java/com/example/catalogservice/web/controllers/ProductControllerIT.java @@ -427,7 +427,43 @@ void shouldFindProductByProductCode() { .jsonPath("$.description") .isEqualTo(product.getDescription()) .jsonPath("$.price") - .isEqualTo(product.getPrice()); + .isEqualTo(product.getPrice()) + .jsonPath("$.inStock") + .isEqualTo(false); + } + + @Test + void shouldFindProductByProductCodeWithStock() throws JsonProcessingException { + Product product = savedProductList.getFirst(); + + mockBackendEndpoint( + 200, objectMapper.writeValueAsString(new InventoryResponse(product.getCode(), 10))); + webTestClient + .get() + .uri( + uriBuilder -> + uriBuilder + .path("/api/catalog/productCode/{productCode}") + .queryParam("fetchInStock", true) + .build(product.getCode())) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON) + .expectBody() + .jsonPath("$.id") + .isEqualTo(product.getId()) + .jsonPath("$.code") + .isEqualTo(product.getCode()) + .jsonPath("$.productName") + .isEqualTo(product.getProductName()) + .jsonPath("$.description") + .isEqualTo(product.getDescription()) + .jsonPath("$.price") + .isEqualTo(product.getPrice()) + .jsonPath("$.inStock") + .isEqualTo(true); } @Test diff --git a/test-em-all.sh b/test-em-all.sh index ca04e613..46cef785 100755 --- a/test-em-all.sh +++ b/test-em-all.sh @@ -140,6 +140,11 @@ function setupTestData() { # Update the product_1 available Quantity recreateComposite $(echo "$RESPONSE" | jq -r .id) "$body" "inventory-service/api/inventory/$(echo "$RESPONSE" | jq -r .id)" "PUT" + # Verify that communication between catalog-service and inventory service is established + assertCurl 200 "curl -k http://$HOST:$PORT/catalog-service/api/catalog/productCode/$PROD_CODE_1?fetchInStock=true" + assertEqual $PROD_CODE_1 $(echo ${RESPONSE} | jq .code) + assertEqual \"true\" $(echo ${RESPONSE} | jq .inStock) + body="{\"name\": \"$CUSTOMER_NAME" body+=\ '","email": "docker@email.com","address": "docker Address","amountAvailable":1000}'