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 circuits = new HashSet<>(); private Map> resolvers = new HashMap<>(); public R handle(HttpRequest request, CheckedSupplier function) throws RestClientResponseException { Optional 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 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 requestConsumer) { this.resolvers.put(circuit, requestConsumer); return this; } }