package eu.eudat.logic.utilities.circuitbreaker; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Created by ikalyvas on 2/25/2019. */ public final class Circuit { private final String url; private final String method; private Integer numberOfFails; private CircuitState state; private final Integer MAX_NUMBER_OF_FAILS = 5; public String getUrl() { return url; } public String getMethod() { return method; } public Integer getNumberOfFails() { return numberOfFails; } public Circuit(String url, String method, Integer numberOfFails) { this.url = url; this.method = method; this.numberOfFails = numberOfFails; ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); executor.scheduleAtFixedRate(this::halfOpenCircuit, 0, 20, TimeUnit.SECONDS); } public enum CircuitState { CLOSED, HALF_OPENED, OPENED } public static class CircuitBuilder { private String url; private String method; public CircuitBuilder url(String url) { this.url = url; return this; } public CircuitBuilder method(String method) { this.method = method; return this; } public Circuit build() { return new Circuit(url, method, 0); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Circuit circuit = (Circuit) o; if (!url.equals(circuit.url)) return false; return method.equals(circuit.method); } @Override public int hashCode() { int result = url.hashCode(); result = 31 * result + method.hashCode(); return result; } private void halfOpenCircuit() { if (this.state == CircuitState.CLOSED) { this.state = CircuitState.HALF_OPENED; } } public void addFailure() { this.numberOfFails++; if(this.state == CircuitState.OPENED && this.numberOfFails > MAX_NUMBER_OF_FAILS){ this.state = CircuitState.CLOSED; } else if(this.state == CircuitState.HALF_OPENED){ this.state = CircuitState.CLOSED; } } public boolean isOpen(){ return this.state == CircuitState.OPENED; } }