Kubernetes Native Microservices with Quarkus and MicroProfile by John Clingan & Ken Finnigan

Kubernetes Native Microservices with Quarkus and MicroProfile by John Clingan & Ken Finnigan

Author:John Clingan & Ken Finnigan [Clingan, John & Finnigan, Ken]
Language: eng
Format: epub
Publisher: Manning Publications Co.
Published: 0101-01-01T00:00:00+00:00


7.8.4 Testing the circuit breaker

To test the circuit breaker, extend the WiremockAccountService with the following:

public class WiremockAccountService implements QuarkusTestResourceLifecycleManager { private WireMockServer wireMockServer; private static final String SERVER_ERROR_1 = "CB Fail 1"; ❶ private static final String SERVER_ERROR_2 = "CB Fail 2"; private static final String CB_OPEN_1 = "CB Open 1"; private static final String CB_OPEN_2 = "CB Open 2"; private static final String CB_OPEN_3 = "CB Open 3"; private static final String CB_SUCCESS_1 = "CB Success 1"; private static final String CB_SUCCESS_2 = "CB Success 2"; ... @Override public Map<String, String> start() { wireMockServer = new WireMockServer(); wireMockServer.start(); mockAccountService(); mockTimeout(); mockCircuitBreaker(); ❷ .. } void mockCircuitBreaker() { // Define wiremock scenario to support the required by a circuitbreaker state machine createCircuitBreakerStub(Scenario.STARTED, SERVER_ERROR_1, "100.00", 200); ❸ createCircuitBreakerStub(SERVER_ERROR_1, SERVER_ERROR_2, "200.00", 502); ❹ createCircuitBreakerStub(SERVER_ERROR_2, CB_OPEN_1, "300.00", 502); ❺ createCircuitBreakerStub(CB_OPEN_1, CB_OPEN_2, "400.00", 200); ❻ createCircuitBreakerStub(CB_OPEN_2, CB_OPEN_3, "400.00", 200); createCircuitBreakerStub(CB_OPEN_3, CB_SUCCESS_1, "500.00", 200); ❼ createCircuitBreakerStub(CB_SUCCESS_1, CB_SUCCESS_2, "600.00", 200); ❽ } void createCircuitBreakerStub(String currentState, String nextState, ❾ String response, int status) { stubFor(post(urlEqualTo("/accounts/444666/transaction")).inScenario("circuitbreaker") .whenScenarioStateIs(currentState).willSetStateTo(nextState).willReturn( aResponse().withStatus(status).withHeader("Content-Type", MediaType.TEXT_PLAIN).withBody(response))); } ...

❶ The states defined for the circuitbreaker WireMock “scenario.” Each field defines a circuit breaker state in order.

❷ Creates the circuit breaker mock

❸ Creates a WireMock circuit breaker stub for each scenario state transition. This first stub defines the initial request in the requestVolumeThreshold.

❹ Returns a 502, the first error the circuit breaker receives

❺ Returns a 502, the second error the circuit breaker receives. This second error will open the circuit breaker.

❻ The circuit breaker is open. Even though the request returns 200, simulating service availability, the circuit breaker is in its delay period.

❼ The first successful call after the delay period

❽ The second successful call closes the circuit.

❾ Any call to the /accounts/444666/transaction endpoint invokes a stub. Each call to the endpoint will advance the state in the circuitbreaker scenario. The body of the response is the account balance.

With the WiremockAccountService updated to support a circuit breaker, the next step is to update FaultyAccountService to test the circuit breaker, as follows.

Listing 7.17 Circuit breaker JUnit test

@Test void testCircuitBreaker() { RequestSpecification request = given() .body("142.12") .contentType(ContentType.JSON); request.post("/transactions/api/444666").then().statusCode(200); ❶ request.post("/transactions/api/444666").then().statusCode(502); ❷ request.post("/transactions/api/444666").then().statusCode(502); ❸ request.post("/transactions/api/444666").then().statusCode(503); ❹ request.post("/transactions/api/444666").then().statusCode(503); ❺ try { TimeUnit.MILLISECONDS.sleep(1000); ❻ } catch (InterruptedException e) { } request.post("/transactions/api/444666").then().statusCode(200); ❼ request.post("/transactions/api/444666").then().statusCode(200); ❽ }

❶ This successful request defines the initial request in the requestVolumeThreshold window.

❷ Expects a 502, the first error the circuit breaker receives

❸ Expects a 502, the second error the circuit breaker receives. This request will open the circuit breaker.

❹ The circuit breaker is open.

❺ The circuit breaker is still open.

❻ Sleeps long enough to get past the circuitbreaker delay

❼ The first successful call after the delay period

❽ The second successful call closes the circuit. The circuit is now closed, and further invocations will continue normally.

Note Early Quarkus releases used the Hystrix framework as the underlying implementation. Hystrix has been deprecated, so later Quarkus releases use a custom implementation. Because developers develop to the MicroProfile Fault Tolerance specification, their application source code did not change. This demonstrates the real-world value of developing to specifications instead of implementations.



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.