mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-08-21 08:26:16 +00:00
feat: Distributed tracing (#3006)
* added microservices distributed tracing pattern * feat: Implement Microservice pattern: Distributed tracing #2693
This commit is contained in:
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.order.microservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* With the Microservices pattern, a request often travels through multiple different microservices.
|
||||
* Tracking the entire request flow across these services can be challenging, especially when trying
|
||||
* to diagnose performance issues or failures. Distributed tracing addresses this challenge by
|
||||
* providing end-to-end visibility into the lifecycle of a request as it passes through various
|
||||
* microservices.
|
||||
*
|
||||
* <p>The intent of the Distributed Tracing pattern is to trace a request across different
|
||||
* microservices, collecting detailed timing data and logs that help in understanding the flow,
|
||||
* performance bottlenecks, and failure points in a distributed system. Each microservice involved
|
||||
* in the request contributes to the tracing data, creating a comprehensive view of the request's
|
||||
* journey.
|
||||
*
|
||||
* <p>This implementation demonstrates distributed tracing in a microservices architecture for an
|
||||
* e-commerce platform. When a customer places an order, the {@link OrderService} interacts with
|
||||
* both the payment-microservice to process the payment and the product-microservice to check the
|
||||
* product inventory. Tracing logs are generated for each interaction, and these logs can be
|
||||
* visualized using Zipkin.
|
||||
*
|
||||
* <p>To run Zipkin and view the tracing logs, you can use the following Docker command:
|
||||
*
|
||||
* <pre>
|
||||
* {@code docker run -d -p 9411:9411 --name zipkin openzipkin/zipkin }
|
||||
* </pre>
|
||||
*
|
||||
* <p>Start Zipkin with the command above. Once Zipkin is running, you can
|
||||
* access the Zipkin UI at `<a href="http://localhost:9411">...</a>`
|
||||
* to view the tracing logs and analyze the request flows across your microservices.
|
||||
*
|
||||
*
|
||||
* <p>To place an order and generate tracing data, you can use the following curl command:
|
||||
*
|
||||
* <pre>
|
||||
* {@code curl -X POST http://localhost:30300/order -H "Content-Type: application/json" -d '{"orderId": "123"}' }
|
||||
* </pre>
|
||||
*
|
||||
* <p>This command sends a POST request to create an order, which will trigger interactions with the
|
||||
* payment and product microservices, generating tracing logs that can be viewed in Zipkin.
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class Main {
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Main.class, args);
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.order.microservice;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* This controller handles order processing by calling necessary microservices.
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class OrderController {
|
||||
|
||||
private final OrderService orderService;
|
||||
|
||||
/**
|
||||
* Constructor to inject OrderService.
|
||||
*
|
||||
* @param orderService the service to process orders
|
||||
*/
|
||||
public OrderController(final OrderService orderService) {
|
||||
this.orderService = orderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint to process an order.
|
||||
*
|
||||
* @param request the order request body (can be null)
|
||||
* @return ResponseEntity with a status message
|
||||
*/
|
||||
@PostMapping("/order")
|
||||
public ResponseEntity<String> processOrder(@RequestBody(required = false) String request) {
|
||||
LOGGER.info("Received order request: {}", request);
|
||||
var result = orderService.processOrder();
|
||||
LOGGER.info("Order processed result: {}", result);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.order.microservice;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.ResourceAccessException;
|
||||
|
||||
/**
|
||||
* Service to handle order processing logic.
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class OrderService {
|
||||
|
||||
private final RestTemplateBuilder restTemplateBuilder;
|
||||
|
||||
/**
|
||||
* Constructor to inject RestTemplateBuilder.
|
||||
*
|
||||
* @param restTemplateBuilder the RestTemplateBuilder to build RestTemplate instances
|
||||
*/
|
||||
public OrderService(final RestTemplateBuilder restTemplateBuilder) {
|
||||
this.restTemplateBuilder = restTemplateBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an order by calling
|
||||
* {@link OrderService#validateProduct()} and
|
||||
* {@link OrderService#processPayment()}.
|
||||
*
|
||||
* @return A string indicating whether the order was processed successfully or failed.
|
||||
*/
|
||||
public String processOrder() {
|
||||
if (validateProduct() && processPayment()) {
|
||||
return "Order processed successfully";
|
||||
}
|
||||
return "Order processing failed";
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the product by calling the respective microservice.
|
||||
*
|
||||
* @return true if the product is valid, false otherwise.
|
||||
*/
|
||||
Boolean validateProduct() {
|
||||
try {
|
||||
ResponseEntity<Boolean> productValidationResult = restTemplateBuilder
|
||||
.build()
|
||||
.postForEntity("http://localhost:30302/product/validate", "validating product",
|
||||
Boolean.class);
|
||||
LOGGER.info("Product validation result: {}", productValidationResult.getBody());
|
||||
return productValidationResult.getBody();
|
||||
} catch (ResourceAccessException | HttpClientErrorException e) {
|
||||
LOGGER.error("Error communicating with product service: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the product by calling the respective microservice.
|
||||
*
|
||||
* @return true if the product is valid, false otherwise.
|
||||
*/
|
||||
Boolean processPayment() {
|
||||
try {
|
||||
ResponseEntity<Boolean> paymentProcessResult = restTemplateBuilder
|
||||
.build()
|
||||
.postForEntity("http://localhost:30301/payment/process", "processing payment",
|
||||
Boolean.class);
|
||||
LOGGER.info("Payment processing result: {}", paymentProcessResult.getBody());
|
||||
return paymentProcessResult.getBody();
|
||||
} catch (ResourceAccessException | HttpClientErrorException e) {
|
||||
LOGGER.error("Error communicating with payment service: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# The MIT License
|
||||
# Copyright © 2014-2021 Ilkka Seppälä
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
spring.application.name=order-microservice
|
||||
server.port=30300
|
||||
|
||||
management.tracing.sampling.probability=1
|
||||
logging.pattern.level=%5p [${spring.zipkin.service.name:${spring.application.name:}},%X{traceId:-},%X{spanId:-}]
|
||||
management.tracing.propagation.type=w3c
|
||||
management.tracing.baggage.enabled=true
|
||||
management.tracing.enabled=true
|
||||
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.order.microservice;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Application test
|
||||
*/
|
||||
class MainTest {
|
||||
@Test
|
||||
void shouldExecuteApplicationWithoutException() {
|
||||
assertDoesNotThrow(() -> Main.main(new String[]{}));
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.iluwatar.order.microservice;/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* OrderControllerTest class to test the OrderController.
|
||||
*/
|
||||
class OrderControllerTest {
|
||||
|
||||
@InjectMocks
|
||||
private OrderController orderController;
|
||||
|
||||
@Mock
|
||||
private OrderService orderService;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the order successfully.
|
||||
*/
|
||||
@Test
|
||||
void processOrderShouldReturnSuccessStatus() {
|
||||
// Arrange
|
||||
when(orderService.processOrder()).thenReturn("Order processed successfully");
|
||||
// Act
|
||||
ResponseEntity<String> response = orderController.processOrder("test order");
|
||||
// Assert
|
||||
assertEquals("Order processed successfully", response.getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the order with failure.
|
||||
*/
|
||||
@Test
|
||||
void ProcessOrderShouldReturnFailureStatusWhen() {
|
||||
// Arrange
|
||||
when(orderService.processOrder()).thenReturn("Order processing failed");
|
||||
// Act
|
||||
ResponseEntity<String> response = orderController.processOrder("test order");
|
||||
// Assert
|
||||
assertEquals("Order processing failed", response.getBody());
|
||||
}
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.order.microservice;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.ResourceAccessException;
|
||||
|
||||
/**
|
||||
* OrderServiceTest class to test the OrderService.
|
||||
*/
|
||||
class OrderServiceTest {
|
||||
|
||||
@InjectMocks
|
||||
private OrderService orderService;
|
||||
|
||||
@Mock
|
||||
private RestTemplateBuilder restTemplateBuilder;
|
||||
|
||||
@Mock
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
when(restTemplateBuilder.build()).thenReturn(restTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the order successfully.
|
||||
*/
|
||||
@Test
|
||||
void testProcessOrder_Success() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30302/product/validate"), anyString(), eq(Boolean.class)))
|
||||
.thenReturn(ResponseEntity.ok(true));
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30301/payment/process"), anyString(), eq(Boolean.class)))
|
||||
.thenReturn(ResponseEntity.ok(true));
|
||||
// Act
|
||||
String result = orderService.processOrder();
|
||||
// Assert
|
||||
assertEquals("Order processed successfully", result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the order with failure caused by product validation failure.
|
||||
*/
|
||||
@Test
|
||||
void testProcessOrder_FailureWithProductValidationFailure() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30302/product/validate"), anyString(), eq(Boolean.class)))
|
||||
.thenReturn(ResponseEntity.ok(false));
|
||||
// Act
|
||||
String result = orderService.processOrder();
|
||||
// Assert
|
||||
assertEquals("Order processing failed", result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the order with failure caused by payment processing failure.
|
||||
*/
|
||||
@Test
|
||||
void testProcessOrder_FailureWithPaymentProcessingFailure() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30302/product/validate"), anyString(), eq(Boolean.class)))
|
||||
.thenReturn(ResponseEntity.ok(true));
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30301/payment/process"), anyString(), eq(Boolean.class)))
|
||||
.thenReturn(ResponseEntity.ok(false));
|
||||
// Act
|
||||
String result = orderService.processOrder();
|
||||
// Assert
|
||||
assertEquals("Order processing failed", result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to validate the product.
|
||||
*/
|
||||
@Test
|
||||
void testValidateProduct() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30302/product/validate"), anyString(), eq(Boolean.class)))
|
||||
.thenReturn(ResponseEntity.ok(true));
|
||||
// Act
|
||||
Boolean result = orderService.validateProduct();
|
||||
// Assert
|
||||
assertEquals(true, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the payment.
|
||||
*/
|
||||
@Test
|
||||
void testProcessPayment() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30301/payment/process"), anyString(), eq(Boolean.class)))
|
||||
.thenReturn(ResponseEntity.ok(true));
|
||||
// Act
|
||||
Boolean result = orderService.processPayment();
|
||||
// Assert
|
||||
assertEquals(true, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to validate the product with ResourceAccessException.
|
||||
*/
|
||||
@Test
|
||||
void testValidateProduct_ResourceAccessException() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30302/product/validate"), anyString(), eq(Boolean.class)))
|
||||
.thenThrow(new ResourceAccessException("Service unavailable"));
|
||||
// Act
|
||||
Boolean result = orderService.validateProduct();
|
||||
// Assert
|
||||
assertEquals(false, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to validate the product with HttpClientErrorException.
|
||||
*/
|
||||
@Test
|
||||
void testValidateProduct_HttpClientErrorException() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30302/product/validate"), anyString(), eq(Boolean.class)))
|
||||
.thenThrow(new HttpClientErrorException(org.springframework.http.HttpStatus.BAD_REQUEST, "Bad request"));
|
||||
// Act
|
||||
Boolean result = orderService.validateProduct();
|
||||
// Assert
|
||||
assertEquals(false, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the payment with ResourceAccessException.
|
||||
*/
|
||||
@Test
|
||||
void testProcessPayment_ResourceAccessException() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30301/payment/process"), anyString(), eq(Boolean.class)))
|
||||
.thenThrow(new ResourceAccessException("Service unavailable"));
|
||||
// Act
|
||||
Boolean result = orderService.processPayment();
|
||||
// Assert
|
||||
assertEquals(false, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to process the payment with HttpClientErrorException.
|
||||
*/
|
||||
@Test
|
||||
void testProcessPayment_HttpClientErrorException() {
|
||||
// Arrange
|
||||
when(restTemplate.postForEntity(eq("http://localhost:30301/payment/process"), anyString(), eq(Boolean.class)))
|
||||
.thenThrow(new HttpClientErrorException(org.springframework.http.HttpStatus.BAD_REQUEST, "Bad request"));
|
||||
// Act
|
||||
Boolean result = orderService.processPayment();
|
||||
// Assert
|
||||
assertEquals(false, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user