io.automatiko.addons.fault.tolerance.internal.NotifyingCircuitBreaker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of automatiko-fault-tolerance-addon Show documentation
Show all versions of automatiko-fault-tolerance-addon Show documentation
Fault Tolerance AddOn for Automatiko Engine
package io.automatiko.addons.fault.tolerance.internal;
import java.util.Collections;
import java.util.function.Consumer;
import org.eclipse.microprofile.faulttolerance.exceptions.CircuitBreakerOpenException;
import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
import io.automatiko.addons.fault.tolerance.CircuitClosedEvent;
import io.automatiko.engine.api.workflow.ServiceExecutionError;
import io.automatiko.engine.api.workflow.workitem.WorkItemExecutionError;
import io.smallrye.faulttolerance.core.FaultToleranceStrategy;
import io.smallrye.faulttolerance.core.InvocationContext;
import io.smallrye.faulttolerance.core.circuit.breaker.CircuitBreakerEvents;
public class NotifyingCircuitBreaker implements FaultToleranceStrategy {
private final String name;
private final Consumer consumer;
private final FaultToleranceStrategy delegate;
public NotifyingCircuitBreaker(String name, FaultToleranceStrategy delegate, Consumer consumer) {
this.name = name;
this.delegate = delegate;
this.consumer = consumer;
}
@Override
public V apply(InvocationContext ctx) throws Exception {
ctx.registerEventHandler(CircuitBreakerEvents.StateTransition.class, e -> {
if (e.targetState.equals(CircuitBreakerEvents.StateTransition.TO_CLOSED.targetState)) {
consumer.accept(new CircuitClosedEvent(name));
}
});
try {
return delegate.apply(ctx);
} catch (WorkItemExecutionError e) {
throw new ServiceExecutionError(e.getMessage(), e.getErrorCode(), name, e.getErrorData());
} catch (CircuitBreakerOpenException e) {
throw new ServiceExecutionError("Service not available", "503", name,
Collections.singletonMap("cause", "service call has been prevented due to too many failures"));
} catch (TimeoutException e) {
throw new ServiceExecutionError(e.getMessage(), "408", "timeout occured",
Collections.singletonMap("cause", "timeout reached when invoking service"));
} catch (Throwable e) {
throw new ServiceExecutionError(e.getMessage(), "500", name, e);
}
}
}