package com.github.jaceko.circuitswitcher; import java.util.concurrent.atomic.AtomicReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Circuit { private static final Logger LOG = LoggerFactory.getLogger(Circuit.class); private final int failureThreshold; private final long resetTimeout; private final AtomicReference<CircuitState> circuitState = new AtomicReference<CircuitState>(); private final String targetAddress; public Circuit(String targetAddress, int failureThreshold, long resetTimeout) { this.targetAddress = targetAddress; this.failureThreshold = failureThreshold; this.resetTimeout = resetTimeout; circuitState.set(new CircuitClosed()); } public boolean connectionAvailable() { return circuitState.get().connectionAvailable(this); } public void handleFailedConnection() { circuitState.get().onError(this); } public void handleSuccesfullConnection() { circuitState.get().onSuccess(this); } public int getFailureThreshold() { return failureThreshold; } public long getResetTimeout() { return resetTimeout; } public void tripBreaker() { circuitState.set(new CircuitOpen()); LOG.warn("Tripping breaker, {}", this.toString()); } public void resetBreaker() { circuitState.set(new CircuitClosed()); LOG.info("Breaker reset, {}", this.toString()); } public void attemptReset() { circuitState.set(new CircuitHalfOpen()); LOG.info("Breaker reset attempt, {}", this.toString()); } public String getTargetAddress() { return targetAddress; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Circuit [targetAddress=").append(targetAddress).append(", state=") .append(circuitState.get()).append(", failureThreshold=").append(failureThreshold) .append(", resetTimeout=").append(resetTimeout).append("]"); return builder.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((targetAddress == null) ? 0 : targetAddress.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Circuit other = (Circuit) obj; if (targetAddress == null) { if (other.targetAddress != null) return false; } else if (!targetAddress.equals(other.targetAddress)) return false; return true; } }