mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-10-14 08:18:23 +00:00
deps: Refactor dependencies (#3224)
* remove spring dep move junit, logging, mockito under dep mgmt * upgrade anti-corruption-layer deps * async method invocation * balking, bloc * bridge to bytecode * caching * callback - cqrs * component - health check * hexagonal - metadata mapping * rest of the patterns * remove checkstyle, take spotless into use
This commit is contained in:
1 parent
371439aeaa
commit
0ca162a55c
1863 files changed
+14403
-17632
No files matched your search
@@ -34,6 +34,14 @@
|
||||
</parent>
|
||||
<artifactId>circuit-breaker</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
|
||||
@@ -27,33 +27,29 @@ package com.iluwatar.circuitbreaker;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The intention of the Circuit Builder pattern is to handle remote failures robustly, which is to
|
||||
* mean that if a service is dependent on n number of other services, and m of them fail, we should
|
||||
* be able to recover from that failure by ensuring that the user can still use the services that
|
||||
* are actually functional, and resources are not tied up by uselessly by the services which are not
|
||||
* working. However, we should also be able to detect when any of the m failing services become
|
||||
* operational again, so that we can use it
|
||||
* </p>
|
||||
* <p>
|
||||
* In this example, the circuit breaker pattern is demonstrated by using three services: {@link
|
||||
*
|
||||
* <p>In this example, the circuit breaker pattern is demonstrated by using three services: {@link
|
||||
* DelayedRemoteService}, {@link QuickRemoteService} and {@link MonitoringService}. The monitoring
|
||||
* service is responsible for calling three services: a local service, a quick remove service
|
||||
* {@link QuickRemoteService} and a delayed remote service {@link DelayedRemoteService} , and by
|
||||
* using the circuit breaker construction we ensure that if the call to remote service is going to
|
||||
* fail, we are going to save our resources and not make the function call at all, by wrapping our
|
||||
* call to the remote services in the {@link DefaultCircuitBreaker} implementation object.
|
||||
* </p>
|
||||
* <p>
|
||||
* This works as follows: The {@link DefaultCircuitBreaker} object can be in one of three states:
|
||||
* <b>Open</b>, <b>Closed</b> and <b>Half-Open</b>, which represents the real world circuits. If
|
||||
* the state is closed (initial), we assume everything is alright and perform the function call.
|
||||
* service is responsible for calling three services: a local service, a quick remove service {@link
|
||||
* QuickRemoteService} and a delayed remote service {@link DelayedRemoteService} , and by using the
|
||||
* circuit breaker construction we ensure that if the call to remote service is going to fail, we
|
||||
* are going to save our resources and not make the function call at all, by wrapping our call to
|
||||
* the remote services in the {@link DefaultCircuitBreaker} implementation object.
|
||||
*
|
||||
* <p>This works as follows: The {@link DefaultCircuitBreaker} object can be in one of three states:
|
||||
* <b>Open</b>, <b>Closed</b> and <b>Half-Open</b>, which represents the real world circuits. If the
|
||||
* state is closed (initial), we assume everything is alright and perform the function call.
|
||||
* However, every time the call fails, we note it and once it crosses a threshold, we set the state
|
||||
* to Open, preventing any further calls to the remote server. Then, after a certain retry period
|
||||
* (during which we expect thee service to recover), we make another call to the remote server and
|
||||
* this state is called the Half-Open state, where it stays till the service is down, and once it
|
||||
* recovers, it goes back to the closed state and the cycle continues.
|
||||
* </p>
|
||||
*/
|
||||
@Slf4j
|
||||
public class App {
|
||||
@@ -68,45 +64,45 @@ public class App {
|
||||
var serverStartTime = System.nanoTime();
|
||||
|
||||
var delayedService = new DelayedRemoteService(serverStartTime, 5);
|
||||
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000, 2,
|
||||
2000 * 1000 * 1000);
|
||||
var delayedServiceCircuitBreaker =
|
||||
new DefaultCircuitBreaker(delayedService, 3000, 2, 2000 * 1000 * 1000);
|
||||
|
||||
var quickService = new QuickRemoteService();
|
||||
var quickServiceCircuitBreaker = new DefaultCircuitBreaker(quickService, 3000, 2,
|
||||
2000 * 1000 * 1000);
|
||||
var quickServiceCircuitBreaker =
|
||||
new DefaultCircuitBreaker(quickService, 3000, 2, 2000 * 1000 * 1000);
|
||||
|
||||
//Create an object of monitoring service which makes both local and remote calls
|
||||
var monitoringService = new MonitoringService(delayedServiceCircuitBreaker,
|
||||
quickServiceCircuitBreaker);
|
||||
// Create an object of monitoring service which makes both local and remote calls
|
||||
var monitoringService =
|
||||
new MonitoringService(delayedServiceCircuitBreaker, quickServiceCircuitBreaker);
|
||||
|
||||
//Fetch response from local resource
|
||||
// Fetch response from local resource
|
||||
LOGGER.info(monitoringService.localResourceResponse());
|
||||
|
||||
//Fetch response from delayed service 2 times, to meet the failure threshold
|
||||
// Fetch response from delayed service 2 times, to meet the failure threshold
|
||||
LOGGER.info(monitoringService.delayedServiceResponse());
|
||||
LOGGER.info(monitoringService.delayedServiceResponse());
|
||||
|
||||
//Fetch current state of delayed service circuit breaker after crossing failure threshold limit
|
||||
//which is OPEN now
|
||||
// Fetch current state of delayed service circuit breaker after crossing failure threshold limit
|
||||
// which is OPEN now
|
||||
LOGGER.info(delayedServiceCircuitBreaker.getState());
|
||||
|
||||
//Meanwhile, the delayed service is down, fetch response from the healthy quick service
|
||||
// Meanwhile, the delayed service is down, fetch response from the healthy quick service
|
||||
LOGGER.info(monitoringService.quickServiceResponse());
|
||||
LOGGER.info(quickServiceCircuitBreaker.getState());
|
||||
|
||||
//Wait for the delayed service to become responsive
|
||||
// Wait for the delayed service to become responsive
|
||||
try {
|
||||
LOGGER.info("Waiting for delayed service to become responsive");
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
}
|
||||
//Check the state of delayed circuit breaker, should be HALF_OPEN
|
||||
// Check the state of delayed circuit breaker, should be HALF_OPEN
|
||||
LOGGER.info(delayedServiceCircuitBreaker.getState());
|
||||
|
||||
//Fetch response from delayed service, which should be healthy by now
|
||||
// Fetch response from delayed service, which should be healthy by now
|
||||
LOGGER.info(monitoringService.delayedServiceResponse());
|
||||
//As successful response is fetched, it should be CLOSED again.
|
||||
// As successful response is fetched, it should be CLOSED again.
|
||||
LOGGER.info(delayedServiceCircuitBreaker.getState());
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,7 @@
|
||||
*/
|
||||
package com.iluwatar.circuitbreaker;
|
||||
|
||||
/**
|
||||
* The Circuit breaker interface.
|
||||
*/
|
||||
/** The Circuit breaker interface. */
|
||||
public interface CircuitBreaker {
|
||||
|
||||
// Success response. Reset everything to defaults
|
||||
|
||||
+14
-14
@@ -45,14 +45,14 @@ public class DefaultCircuitBreaker implements CircuitBreaker {
|
||||
/**
|
||||
* Constructor to create an instance of Circuit Breaker.
|
||||
*
|
||||
* @param timeout Timeout for the API request. Not necessary for this simple example
|
||||
* @param timeout Timeout for the API request. Not necessary for this simple example
|
||||
* @param failureThreshold Number of failures we receive from the depended on service before
|
||||
* changing state to 'OPEN'
|
||||
* @param retryTimePeriod Time, in nanoseconds, period after which a new request is made to
|
||||
* remote service for status check.
|
||||
* changing state to 'OPEN'
|
||||
* @param retryTimePeriod Time, in nanoseconds, period after which a new request is made to remote
|
||||
* service for status check.
|
||||
*/
|
||||
DefaultCircuitBreaker(RemoteService serviceToCall, long timeout, int failureThreshold,
|
||||
long retryTimePeriod) {
|
||||
DefaultCircuitBreaker(
|
||||
RemoteService serviceToCall, long timeout, int failureThreshold, long retryTimePeriod) {
|
||||
this.service = serviceToCall;
|
||||
// We start in a closed state hoping that everything is fine
|
||||
this.state = State.CLOSED;
|
||||
@@ -61,7 +61,7 @@ public class DefaultCircuitBreaker implements CircuitBreaker {
|
||||
// Used to break the calls made to remote resource if it exceeds the limit
|
||||
this.timeout = timeout;
|
||||
this.retryTimePeriod = retryTimePeriod;
|
||||
//An absurd amount of time in future which basically indicates the last failure never happened
|
||||
// An absurd amount of time in future which basically indicates the last failure never happened
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.failureCount = 0;
|
||||
}
|
||||
@@ -84,16 +84,16 @@ public class DefaultCircuitBreaker implements CircuitBreaker {
|
||||
|
||||
// Evaluate the current state based on failureThreshold, failureCount and lastFailureTime.
|
||||
protected void evaluateState() {
|
||||
if (failureCount >= failureThreshold) { //Then something is wrong with remote service
|
||||
if (failureCount >= failureThreshold) { // Then something is wrong with remote service
|
||||
if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
|
||||
//We have waited long enough and should try checking if service is up
|
||||
// We have waited long enough and should try checking if service is up
|
||||
state = State.HALF_OPEN;
|
||||
} else {
|
||||
//Service would still probably be down
|
||||
// Service would still probably be down
|
||||
state = State.OPEN;
|
||||
}
|
||||
} else {
|
||||
//Everything is working fine
|
||||
// Everything is working fine
|
||||
state = State.CLOSED;
|
||||
}
|
||||
}
|
||||
@@ -140,9 +140,9 @@ public class DefaultCircuitBreaker implements CircuitBreaker {
|
||||
} else {
|
||||
// Make the API request if the circuit is not OPEN
|
||||
try {
|
||||
//In a real application, this would be run in a thread and the timeout
|
||||
//parameter of the circuit breaker would be utilized to know if service
|
||||
//is working. Here, we simulate that based on server response itself
|
||||
// In a real application, this would be run in a thread and the timeout
|
||||
// parameter of the circuit breaker would be utilized to know if service
|
||||
// is working. Here, we simulate that based on server response itself
|
||||
var response = service.call();
|
||||
// Yay!! the API responded fine. Let's reset everything.
|
||||
recordSuccess();
|
||||
|
||||
@@ -56,12 +56,12 @@ public class DelayedRemoteService implements RemoteService {
|
||||
@Override
|
||||
public String call() throws RemoteServiceException {
|
||||
var currentTime = System.nanoTime();
|
||||
//Since currentTime and serverStartTime are both in nanoseconds, we convert it to
|
||||
//seconds by diving by 10e9 and ensure floating point division by multiplying it
|
||||
//with 1.0 first. We then check if it is greater or less than specified delay and then
|
||||
//send the reply
|
||||
// Since currentTime and serverStartTime are both in nanoseconds, we convert it to
|
||||
// seconds by diving by 10e9 and ensure floating point division by multiplying it
|
||||
// with 1.0 first. We then check if it is greater or less than specified delay and then
|
||||
// send the reply
|
||||
if ((currentTime - serverStartTime) * 1.0 / (1000 * 1000 * 1000) < delay) {
|
||||
//Can use Thread.sleep() here to block and simulate a hung server
|
||||
// Can use Thread.sleep() here to block and simulate a hung server
|
||||
throw new RemoteServiceException("Delayed service is down");
|
||||
}
|
||||
return "Delayed service is working";
|
||||
|
||||
@@ -39,7 +39,7 @@ public class MonitoringService {
|
||||
this.quickService = quickService;
|
||||
}
|
||||
|
||||
//Assumption: Local service won't fail, no need to wrap it in a circuit breaker logic
|
||||
// Assumption: Local service won't fail, no need to wrap it in a circuit breaker logic
|
||||
public String localResourceResponse() {
|
||||
return "Local Service is working";
|
||||
}
|
||||
@@ -69,4 +69,4 @@ public class MonitoringService {
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,7 @@
|
||||
*/
|
||||
package com.iluwatar.circuitbreaker;
|
||||
|
||||
/**
|
||||
* A quick response remote service, that responds healthy without any delay or failure.
|
||||
*/
|
||||
/** A quick response remote service, that responds healthy without any delay or failure. */
|
||||
public class QuickRemoteService implements RemoteService {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,6 +30,6 @@ package com.iluwatar.circuitbreaker;
|
||||
*/
|
||||
public interface RemoteService {
|
||||
|
||||
//Fetch response from remote service.
|
||||
// Fetch response from remote service.
|
||||
String call() throws RemoteServiceException;
|
||||
}
|
||||
+1
-3
@@ -24,9 +24,7 @@
|
||||
*/
|
||||
package com.iluwatar.circuitbreaker;
|
||||
|
||||
/**
|
||||
* Exception thrown when {@link RemoteService} does not respond successfully.
|
||||
*/
|
||||
/** Exception thrown when {@link RemoteService} does not respond successfully. */
|
||||
public class RemoteServiceException extends Exception {
|
||||
|
||||
public RemoteServiceException(String message) {
|
||||
|
||||
@@ -24,11 +24,9 @@
|
||||
*/
|
||||
package com.iluwatar.circuitbreaker;
|
||||
|
||||
/**
|
||||
* Enumeration for states the circuit breaker could be in.
|
||||
*/
|
||||
/** Enumeration for states the circuit breaker could be in. */
|
||||
public enum State {
|
||||
CLOSED,
|
||||
OPEN,
|
||||
HALF_OPEN
|
||||
}
|
||||
}
|
||||
@@ -31,20 +31,18 @@ import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* App Test showing usage of circuit breaker.
|
||||
*/
|
||||
/** App Test showing usage of circuit breaker. */
|
||||
class AppTest {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AppTest.class);
|
||||
|
||||
//Startup delay for delayed service (in seconds)
|
||||
// Startup delay for delayed service (in seconds)
|
||||
private static final int STARTUP_DELAY = 4;
|
||||
|
||||
//Number of failed requests for circuit breaker to open
|
||||
// Number of failed requests for circuit breaker to open
|
||||
private static final int FAILURE_THRESHOLD = 1;
|
||||
|
||||
//Time period in seconds for circuit breaker to retry service
|
||||
// Time period in seconds for circuit breaker to retry service
|
||||
private static final int RETRY_PERIOD = 2;
|
||||
|
||||
private MonitoringService monitoringService;
|
||||
@@ -62,75 +60,75 @@ class AppTest {
|
||||
@BeforeEach
|
||||
void setupCircuitBreakers() {
|
||||
var delayedService = new DelayedRemoteService(System.nanoTime(), STARTUP_DELAY);
|
||||
//Set the circuit Breaker parameters
|
||||
delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
||||
FAILURE_THRESHOLD,
|
||||
RETRY_PERIOD * 1000 * 1000 * 1000);
|
||||
// Set the circuit Breaker parameters
|
||||
delayedServiceCircuitBreaker =
|
||||
new DefaultCircuitBreaker(
|
||||
delayedService, 3000, FAILURE_THRESHOLD, RETRY_PERIOD * 1000 * 1000 * 1000);
|
||||
|
||||
var quickService = new QuickRemoteService();
|
||||
//Set the circuit Breaker parameters
|
||||
quickServiceCircuitBreaker = new DefaultCircuitBreaker(quickService, 3000, FAILURE_THRESHOLD,
|
||||
RETRY_PERIOD * 1000 * 1000 * 1000);
|
||||
|
||||
monitoringService = new MonitoringService(delayedServiceCircuitBreaker,
|
||||
quickServiceCircuitBreaker);
|
||||
// Set the circuit Breaker parameters
|
||||
quickServiceCircuitBreaker =
|
||||
new DefaultCircuitBreaker(
|
||||
quickService, 3000, FAILURE_THRESHOLD, RETRY_PERIOD * 1000 * 1000 * 1000);
|
||||
|
||||
monitoringService =
|
||||
new MonitoringService(delayedServiceCircuitBreaker, quickServiceCircuitBreaker);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_OpenStateTransition() {
|
||||
//Calling delayed service, which will be unhealthy till 4 seconds
|
||||
// Calling delayed service, which will be unhealthy till 4 seconds
|
||||
assertEquals("Delayed service is down", monitoringService.delayedServiceResponse());
|
||||
//As failure threshold is "1", the circuit breaker is changed to OPEN
|
||||
// As failure threshold is "1", the circuit breaker is changed to OPEN
|
||||
assertEquals("OPEN", delayedServiceCircuitBreaker.getState());
|
||||
//As circuit state is OPEN, we expect a quick fallback response from circuit breaker.
|
||||
// As circuit state is OPEN, we expect a quick fallback response from circuit breaker.
|
||||
assertEquals("Delayed service is down", monitoringService.delayedServiceResponse());
|
||||
|
||||
//Meanwhile, the quick service is responding and the circuit state is CLOSED
|
||||
// Meanwhile, the quick service is responding and the circuit state is CLOSED
|
||||
assertEquals("Quick Service is working", monitoringService.quickServiceResponse());
|
||||
assertEquals("CLOSED", quickServiceCircuitBreaker.getState());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_HalfOpenStateTransition() {
|
||||
//Calling delayed service, which will be unhealthy till 4 seconds
|
||||
// Calling delayed service, which will be unhealthy till 4 seconds
|
||||
assertEquals("Delayed service is down", monitoringService.delayedServiceResponse());
|
||||
//As failure threshold is "1", the circuit breaker is changed to OPEN
|
||||
// As failure threshold is "1", the circuit breaker is changed to OPEN
|
||||
assertEquals("OPEN", delayedServiceCircuitBreaker.getState());
|
||||
|
||||
//Waiting for recovery period of 2 seconds for circuit breaker to retry service.
|
||||
// Waiting for recovery period of 2 seconds for circuit breaker to retry service.
|
||||
try {
|
||||
LOGGER.info("Waiting 2s for delayed service to become responsive");
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
}
|
||||
//After 2 seconds, the circuit breaker should move to "HALF_OPEN" state and retry fetching response from service again
|
||||
// After 2 seconds, the circuit breaker should move to "HALF_OPEN" state and retry fetching
|
||||
// response from service again
|
||||
assertEquals("HALF_OPEN", delayedServiceCircuitBreaker.getState());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRecovery_ClosedStateTransition() {
|
||||
//Calling delayed service, which will be unhealthy till 4 seconds
|
||||
// Calling delayed service, which will be unhealthy till 4 seconds
|
||||
assertEquals("Delayed service is down", monitoringService.delayedServiceResponse());
|
||||
//As failure threshold is "1", the circuit breaker is changed to OPEN
|
||||
// As failure threshold is "1", the circuit breaker is changed to OPEN
|
||||
assertEquals("OPEN", delayedServiceCircuitBreaker.getState());
|
||||
|
||||
//Waiting for 4 seconds, which is enough for DelayedService to become healthy and respond successfully.
|
||||
// Waiting for 4 seconds, which is enough for DelayedService to become healthy and respond
|
||||
// successfully.
|
||||
try {
|
||||
LOGGER.info("Waiting 4s for delayed service to become responsive");
|
||||
Thread.sleep(4000);
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
}
|
||||
//As retry period is 2 seconds (<4 seconds of wait), hence the circuit breaker should be back in HALF_OPEN state.
|
||||
// As retry period is 2 seconds (<4 seconds of wait), hence the circuit breaker should be back
|
||||
// in HALF_OPEN state.
|
||||
assertEquals("HALF_OPEN", delayedServiceCircuitBreaker.getState());
|
||||
//Check the success response from delayed service.
|
||||
// Check the success response from delayed service.
|
||||
assertEquals("Delayed service is working", monitoringService.delayedServiceResponse());
|
||||
//As the response is success, the state should be CLOSED
|
||||
// As the response is success, the state should be CLOSED
|
||||
assertEquals("CLOSED", delayedServiceCircuitBreaker.getState());
|
||||
}
|
||||
|
||||
}
|
||||
+19
-20
@@ -28,29 +28,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Circuit Breaker test
|
||||
*/
|
||||
/** Circuit Breaker test */
|
||||
class DefaultCircuitBreakerTest {
|
||||
|
||||
//long timeout, int failureThreshold, long retryTimePeriod
|
||||
// long timeout, int failureThreshold, long retryTimePeriod
|
||||
@Test
|
||||
void testEvaluateState() {
|
||||
var circuitBreaker = new DefaultCircuitBreaker(null, 1, 1, 100);
|
||||
//Right now, failureCount<failureThreshold, so state should be closed
|
||||
// Right now, failureCount<failureThreshold, so state should be closed
|
||||
assertEquals(circuitBreaker.getState(), "CLOSED");
|
||||
circuitBreaker.failureCount = 4;
|
||||
circuitBreaker.lastFailureTime = System.nanoTime();
|
||||
circuitBreaker.evaluateState();
|
||||
//Since failureCount>failureThreshold, and lastFailureTime is nearly equal to current time,
|
||||
//state should be half-open
|
||||
// Since failureCount>failureThreshold, and lastFailureTime is nearly equal to current time,
|
||||
// state should be half-open
|
||||
assertEquals(circuitBreaker.getState(), "HALF_OPEN");
|
||||
//Since failureCount>failureThreshold, and lastFailureTime is much lesser current time,
|
||||
//state should be open
|
||||
// Since failureCount>failureThreshold, and lastFailureTime is much lesser current time,
|
||||
// state should be open
|
||||
circuitBreaker.lastFailureTime = System.nanoTime() - 1000 * 1000 * 1000 * 1000;
|
||||
circuitBreaker.evaluateState();
|
||||
assertEquals(circuitBreaker.getState(), "OPEN");
|
||||
//Now set it back again to closed to test idempotency
|
||||
// Now set it back again to closed to test idempotency
|
||||
circuitBreaker.failureCount = 0;
|
||||
circuitBreaker.evaluateState();
|
||||
assertEquals(circuitBreaker.getState(), "CLOSED");
|
||||
@@ -59,23 +57,24 @@ class DefaultCircuitBreakerTest {
|
||||
@Test
|
||||
void testSetStateForBypass() {
|
||||
var circuitBreaker = new DefaultCircuitBreaker(null, 1, 1, 2000 * 1000 * 1000);
|
||||
//Right now, failureCount<failureThreshold, so state should be closed
|
||||
//Bypass it and set it to open
|
||||
// Right now, failureCount<failureThreshold, so state should be closed
|
||||
// Bypass it and set it to open
|
||||
circuitBreaker.setState(State.OPEN);
|
||||
assertEquals(circuitBreaker.getState(), "OPEN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testApiResponses() throws RemoteServiceException {
|
||||
RemoteService mockService = new RemoteService() {
|
||||
@Override
|
||||
public String call() throws RemoteServiceException {
|
||||
return "Remote Success";
|
||||
}
|
||||
};
|
||||
RemoteService mockService =
|
||||
new RemoteService() {
|
||||
@Override
|
||||
public String call() throws RemoteServiceException {
|
||||
return "Remote Success";
|
||||
}
|
||||
};
|
||||
var circuitBreaker = new DefaultCircuitBreaker(mockService, 1, 1, 100);
|
||||
//Call with the parameter start_time set to huge amount of time in past so that service
|
||||
//replies with "Ok". Also, state is CLOSED in start
|
||||
// Call with the parameter start_time set to huge amount of time in past so that service
|
||||
// replies with "Ok". Also, state is CLOSED in start
|
||||
var serviceStartTime = System.nanoTime() - 60 * 1000 * 1000 * 1000;
|
||||
var response = circuitBreaker.attemptRequest();
|
||||
assertEquals(response, "Remote Success");
|
||||
|
||||
+9
-9
@@ -29,9 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Monitoring Service test
|
||||
*/
|
||||
/** Monitoring Service test */
|
||||
class DelayedRemoteServiceTest {
|
||||
|
||||
/**
|
||||
@@ -41,10 +39,12 @@ class DelayedRemoteServiceTest {
|
||||
*/
|
||||
@Test
|
||||
void testDefaultConstructor() throws RemoteServiceException {
|
||||
Assertions.assertThrows(RemoteServiceException.class, () -> {
|
||||
var obj = new DelayedRemoteService();
|
||||
obj.call();
|
||||
});
|
||||
Assertions.assertThrows(
|
||||
RemoteServiceException.class,
|
||||
() -> {
|
||||
var obj = new DelayedRemoteService();
|
||||
obj.call();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ class DelayedRemoteServiceTest {
|
||||
*/
|
||||
@Test
|
||||
void testParameterizedConstructor() throws RemoteServiceException {
|
||||
var obj = new DelayedRemoteService(System.nanoTime()-2000*1000*1000,1);
|
||||
assertEquals("Delayed service is working",obj.call());
|
||||
var obj = new DelayedRemoteService(System.nanoTime() - 2000 * 1000 * 1000, 1);
|
||||
assertEquals("Delayed service is working", obj.call());
|
||||
}
|
||||
}
|
||||
+16
-21
@@ -28,28 +28,25 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Monitoring Service test
|
||||
*/
|
||||
/** Monitoring Service test */
|
||||
class MonitoringServiceTest {
|
||||
|
||||
//long timeout, int failureThreshold, long retryTimePeriod
|
||||
// long timeout, int failureThreshold, long retryTimePeriod
|
||||
@Test
|
||||
void testLocalResponse() {
|
||||
var monitoringService = new MonitoringService(null,null);
|
||||
var monitoringService = new MonitoringService(null, null);
|
||||
var response = monitoringService.localResourceResponse();
|
||||
assertEquals(response, "Local Service is working");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelayedRemoteResponseSuccess() {
|
||||
var delayedService = new DelayedRemoteService(System.nanoTime()-2*1000*1000*1000, 2);
|
||||
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
||||
1,
|
||||
2 * 1000 * 1000 * 1000);
|
||||
var delayedService = new DelayedRemoteService(System.nanoTime() - 2 * 1000 * 1000 * 1000, 2);
|
||||
var delayedServiceCircuitBreaker =
|
||||
new DefaultCircuitBreaker(delayedService, 3000, 1, 2 * 1000 * 1000 * 1000);
|
||||
|
||||
var monitoringService = new MonitoringService(delayedServiceCircuitBreaker,null);
|
||||
//Set time in past to make the server work
|
||||
var monitoringService = new MonitoringService(delayedServiceCircuitBreaker, null);
|
||||
// Set time in past to make the server work
|
||||
var response = monitoringService.delayedServiceResponse();
|
||||
assertEquals(response, "Delayed service is working");
|
||||
}
|
||||
@@ -57,11 +54,10 @@ class MonitoringServiceTest {
|
||||
@Test
|
||||
void testDelayedRemoteResponseFailure() {
|
||||
var delayedService = new DelayedRemoteService(System.nanoTime(), 2);
|
||||
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
||||
1,
|
||||
2 * 1000 * 1000 * 1000);
|
||||
var monitoringService = new MonitoringService(delayedServiceCircuitBreaker,null);
|
||||
//Set time as current time as initially server fails
|
||||
var delayedServiceCircuitBreaker =
|
||||
new DefaultCircuitBreaker(delayedService, 3000, 1, 2 * 1000 * 1000 * 1000);
|
||||
var monitoringService = new MonitoringService(delayedServiceCircuitBreaker, null);
|
||||
// Set time as current time as initially server fails
|
||||
var response = monitoringService.delayedServiceResponse();
|
||||
assertEquals(response, "Delayed service is down");
|
||||
}
|
||||
@@ -69,11 +65,10 @@ class MonitoringServiceTest {
|
||||
@Test
|
||||
void testQuickRemoteServiceResponse() {
|
||||
var delayedService = new QuickRemoteService();
|
||||
var delayedServiceCircuitBreaker = new DefaultCircuitBreaker(delayedService, 3000,
|
||||
1,
|
||||
2 * 1000 * 1000 * 1000);
|
||||
var monitoringService = new MonitoringService(delayedServiceCircuitBreaker,null);
|
||||
//Set time as current time as initially server fails
|
||||
var delayedServiceCircuitBreaker =
|
||||
new DefaultCircuitBreaker(delayedService, 3000, 1, 2 * 1000 * 1000 * 1000);
|
||||
var monitoringService = new MonitoringService(delayedServiceCircuitBreaker, null);
|
||||
// Set time as current time as initially server fails
|
||||
var response = monitoringService.delayedServiceResponse();
|
||||
assertEquals(response, "Quick Service is working");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user