argos/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/circuitbreaker/CircuitBreaker.java

48 lines
1.7 KiB
Java

package eu.eudat.logic.utilities.circuitbreaker;
import eu.eudat.logic.utilities.interfaces.CheckedSupplier;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientResponseException;
import java.util.*;
import java.util.function.Consumer;
/**
* Created by ikalyvas on 2/25/2019.
*/
@Component
public class CircuitBreaker {
private Set<Circuit> circuits = new HashSet<>();
private Map<Circuit, Consumer<HttpRequest>> resolvers = new HashMap<>();
public <R> R handle(HttpRequest request, CheckedSupplier<R> function) throws RestClientResponseException {
Optional<Circuit> circuitOptional = this.circuits.stream()
.filter(circuit ->
circuit.getMethod().equals(request.getMethod().name()) && circuit.getUrl().equals(request.getURI().toString()))
.findFirst();
if (circuitOptional.isPresent() && circuitOptional.get().isOpen()) {
Consumer<HttpRequest> resolver = resolvers.get(circuitOptional.get());
if (resolver != null) {
resolver.accept(request);
return null;
} else throw new RuntimeException("Resolver not found for " + request);
} else {
try {
return function.get();
} catch (Exception ex) {
if (circuitOptional.isPresent()) circuitOptional.get().addFailure();
else
circuits.add(new Circuit.CircuitBuilder().method(request.getMethod().name()).url(request.getURI().toString()).build());
throw new RestClientResponseException(StringUtils.EMPTY, 400, StringUtils.EMPTY, null, null, null);
}
}
}
public CircuitBreaker addCircuitResolver(Circuit circuit, Consumer<HttpRequest> requestConsumer) {
this.resolvers.put(circuit, requestConsumer);
return this;
}
}