use of io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent in project resilience4j by resilience4j.
the class CircularEventConsumerTest method shouldNotBufferEvents.
@Test
public void shouldNotBufferEvents() {
// Given
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName");
CircularEventConsumer<CircuitBreakerEvent> ringBuffer = new CircularEventConsumer<>(2);
assertThat(ringBuffer.getBufferedEvents()).isEmpty();
circuitBreaker.onError(0, new RuntimeException("Bla"));
circuitBreaker.onError(0, new RuntimeException("Bla"));
circuitBreaker.onError(0, new RuntimeException("Bla"));
// Subscription is too late
circuitBreaker.getEventPublisher().onEvent(ringBuffer);
// Then
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(3);
// Should store 0 events, because Subscription was too late
assertThat(ringBuffer.getBufferedEvents()).hasSize(0);
}
use of io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent in project resilience4j by resilience4j.
the class CircularEventConsumerTest method shouldBufferAllEvents.
@Test
public void shouldBufferAllEvents() {
// Given
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom().ringBufferSizeInClosedState(3).recordFailure(throwable -> API.Match(throwable).of(Case($(instanceOf(WebServiceException.class)), true), Case($(), false))).build();
CircuitBreaker circuitBreaker = CircuitBreaker.of("testName", circuitBreakerConfig);
CircularEventConsumer<CircuitBreakerEvent> ringBuffer = new CircularEventConsumer<>(10);
circuitBreaker.getEventPublisher().onEvent(ringBuffer);
assertThat(ringBuffer.getBufferedEvents()).isEmpty();
// When
circuitBreaker.onSuccess(0);
circuitBreaker.onError(0, new WebServiceException("Bla"));
circuitBreaker.onError(0, new IOException("Bla"));
circuitBreaker.onError(0, new WebServiceException("Bla"));
// Then
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(2);
circuitBreaker.reset();
CircuitBreaker.Metrics resetMetrics = circuitBreaker.getMetrics();
assertThat(resetMetrics.getNumberOfBufferedCalls()).isEqualTo(0);
assertThat(resetMetrics.getNumberOfFailedCalls()).isEqualTo(0);
// Should store 3 events, because circuit emits 2 error events and one state transition event
assertThat(ringBuffer.getBufferedEvents()).hasSize(7);
assertThat(ringBuffer.getBufferedEvents()).extracting("eventType").containsExactly(Type.SUCCESS, Type.ERROR, Type.IGNORED_ERROR, Type.ERROR, Type.STATE_TRANSITION, Type.STATE_TRANSITION, Type.RESET);
// ringBuffer.getBufferedEvents().forEach(event -> LOG.info(event.toString()));
}
use of io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent in project resilience4j by resilience4j.
the class CircularEventConsumerTest method shouldBufferErrorEvents.
@Test
public void shouldBufferErrorEvents() {
// Given
// tag::shouldBufferEvents[]
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName");
CircularEventConsumer<CircuitBreakerEvent> ringBuffer = new CircularEventConsumer<>(2);
circuitBreaker.getEventPublisher().onEvent(ringBuffer);
// end::shouldBufferEvents[]
assertThat(ringBuffer.getBufferedEvents()).isEmpty();
// When
circuitBreaker.onError(0, new RuntimeException("Bla"));
circuitBreaker.onError(0, new RuntimeException("Bla"));
circuitBreaker.onError(0, new RuntimeException("Bla"));
// Then
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(3);
// Should only store 2 events, because capacity is 2
assertThat(ringBuffer.getBufferedEvents()).hasSize(2);
// ringBuffer.getBufferedEvents().forEach(event -> LOG.info(event.toString()));
}
use of io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent in project resilience4j by resilience4j.
the class CircuitBreakerChain method execute.
@Override
public void execute(Chain chain) throws Exception {
String prefix = chain.getRegistry().get(Resilience4jConfig.class).getEndpoints().getCircuitBreakers().getPath();
chain.prefix(prefix, chain1 -> {
chain1.get("events", ctx -> Promise.<CircuitBreakerEventsEndpointResponse>async(d -> {
CircuitBreakerEventsEndpointResponse response = new CircuitBreakerEventsEndpointResponse(eventConsumerRegistry.getAllEventConsumer().flatMap(CircularEventConsumer::getBufferedEvents).sorted(Comparator.comparing(CircuitBreakerEvent::getCreationTime)).map(CircuitBreakerEventDTOFactory::createCircuitBreakerEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r))));
chain1.get("stream/events", ctx -> {
Seq<Flowable<CircuitBreakerEvent>> eventStreams = circuitBreakerRegistry.getAllCircuitBreakers().map(circuitBreaker -> RxJava2Adapter.toFlowable(circuitBreaker.getEventPublisher()));
Function<CircuitBreakerEvent, String> data = c -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(CircuitBreakerEventDTOFactory.createCircuitBreakerEventDTO(c));
ServerSentEvents events = ServerSentEvents.serverSentEvents(Flowable.merge(eventStreams), e -> e.id(CircuitBreakerEvent::getCircuitBreakerName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
chain1.get("events/:name", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
Promise.<CircuitBreakerEventsEndpointResponse>async(d -> {
CircuitBreakerEventsEndpointResponse response = new CircuitBreakerEventsEndpointResponse(eventConsumerRegistry.getEventConsumer(circuitBreakerName).getBufferedEvents().map(CircuitBreakerEventDTOFactory::createCircuitBreakerEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r)));
});
chain1.get("stream/events/:name", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
CircuitBreaker circuitBreaker = circuitBreakerRegistry.getAllCircuitBreakers().find(cb -> cb.getName().equals(circuitBreakerName)).getOrElseThrow(() -> new IllegalArgumentException(String.format("circuit breaker with name %s not found", circuitBreakerName)));
Function<CircuitBreakerEvent, String> data = c -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(CircuitBreakerEventDTOFactory.createCircuitBreakerEventDTO(c));
ServerSentEvents events = ServerSentEvents.serverSentEvents(RxJava2Adapter.toFlowable(circuitBreaker.getEventPublisher()), e -> e.id(CircuitBreakerEvent::getCircuitBreakerName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
chain1.get("events/:name/:type", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
String eventType = ctx.getPathTokens().get("type");
Promise.<CircuitBreakerEventsEndpointResponse>async(d -> {
CircuitBreakerEventsEndpointResponse response = new CircuitBreakerEventsEndpointResponse(eventConsumerRegistry.getEventConsumer(circuitBreakerName).getBufferedEvents().filter(event -> event.getEventType() == CircuitBreakerEvent.Type.valueOf(eventType.toUpperCase())).map(CircuitBreakerEventDTOFactory::createCircuitBreakerEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r)));
});
chain1.get("stream/events/:name/:type", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
String eventType = ctx.getPathTokens().get("type");
CircuitBreaker circuitBreaker = circuitBreakerRegistry.getAllCircuitBreakers().find(cb -> cb.getName().equals(circuitBreakerName)).getOrElseThrow(() -> new IllegalArgumentException(String.format("circuit breaker with name %s not found", circuitBreakerName)));
Flowable<CircuitBreakerEvent> eventStream = RxJava2Adapter.toFlowable(circuitBreaker.getEventPublisher()).filter(event -> event.getEventType() == CircuitBreakerEvent.Type.valueOf(eventType.toUpperCase()));
Function<CircuitBreakerEvent, String> data = c -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(CircuitBreakerEventDTOFactory.createCircuitBreakerEventDTO(c));
ServerSentEvents events = ServerSentEvents.serverSentEvents(eventStream, e -> e.id(CircuitBreakerEvent::getCircuitBreakerName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
});
}
use of io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent in project resilience4j by resilience4j.
the class CircuitBreakerEventsEndpoint method getEventsStreamFilteredByCircuitBreakerNameAndEventType.
@RequestMapping(value = "stream/events/{circuitBreakerName}/{eventType}", produces = MEDIA_TYPE_TEXT_EVENT_STREAM)
public SseEmitter getEventsStreamFilteredByCircuitBreakerNameAndEventType(@PathVariable("circuitBreakerName") String circuitBreakerName, @PathVariable("eventType") String eventType) {
CircuitBreaker circuitBreaker = circuitBreakerRegistry.getAllCircuitBreakers().find(cb -> cb.getName().equals(circuitBreakerName)).getOrElseThrow(() -> new IllegalArgumentException(String.format("circuit breaker with name %s not found", circuitBreakerName)));
Flux<CircuitBreakerEvent> eventStream = toFlux(circuitBreaker.getEventPublisher()).filter(event -> event.getEventType() == CircuitBreakerEvent.Type.valueOf(eventType.toUpperCase()));
return CircuitBreakerEventEmitter.createSseEmitter(eventStream);
}
Aggregations