use of io.github.resilience4j.core.ContextAwareScheduledThreadPoolExecutor in project resilience4j by resilience4j.
the class DecoratorsTest method shouldThrowTimeoutExceptionAndPropagateMDCContext.
@Test
public void shouldThrowTimeoutExceptionAndPropagateMDCContext() {
TimeLimiter timeLimiter = TimeLimiter.of("helloBackend", TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(100)).build());
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("helloBackend");
ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.ofDefaults("helloBackend");
MDC.put("key", "ValueShouldPropagateThreadBoundary");
MDC.put("key2", "value2");
final Map<String, String> contextMap = MDC.getCopyOfContextMap();
ContextAwareScheduledThreadPoolExecutor scheduledThreadPool = ContextAwareScheduledThreadPoolExecutor.newScheduledThreadPool().corePoolSize(1).build();
CompletionStage<String> completionStage = Decorators.ofCallable(() -> {
assertThat(Thread.currentThread().getName()).isEqualTo("bulkhead-helloBackend-1");
Thread.sleep(1000);
return "Bla";
}).withThreadPoolBulkhead(bulkhead).withTimeLimiter(timeLimiter, scheduledThreadPool).withCircuitBreaker(circuitBreaker).get();
final CompletableFuture<String> completableFuture = completionStage.toCompletableFuture().exceptionally(throwable -> {
if (throwable != null) {
assertThat(Thread.currentThread().getName()).isEqualTo("ContextAwareScheduledThreadPool-1");
assertThat(MDC.getCopyOfContextMap()).hasSize(2).containsExactlyEntriesOf(contextMap);
return MDC.getCopyOfContextMap().get("key");
}
return null;
});
waitAtMost(2, TimeUnit.SECONDS).until(matches(() -> assertThat(completableFuture).isCompletedWithValue("ValueShouldPropagateThreadBoundary")));
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(1);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(1);
}
use of io.github.resilience4j.core.ContextAwareScheduledThreadPoolExecutor in project resilience4j by resilience4j.
the class DecoratorsTest method testDecorateCompletionStagePropagatesContextWithRetryAsync.
@Test
public void testDecorateCompletionStagePropagatesContextWithRetryAsync() {
given(helloWorldService.returnHelloWorld()).willReturn("Hello world");
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("helloBackend");
TestThreadLocalContextPropagatorWithHolder propagator = new TestThreadLocalContextPropagatorWithHolder();
TestThreadLocalContextHolder.put("ValueShouldCrossThreadBoundary");
ContextAwareScheduledThreadPoolExecutor scheduledThreadPool = ContextAwareScheduledThreadPoolExecutor.newScheduledThreadPool().corePoolSize(1).contextPropagators(propagator).build();
CompletableFuture<String> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(new HelloWorldException());
given(asyncHelloWorldService.returnHelloWorld()).willReturn(failedFuture);
CompletionStage<String> completionStage = Decorators.ofCompletionStage(() -> asyncHelloWorldService.returnHelloWorld()).withCircuitBreaker(circuitBreaker).withRetry(Retry.ofDefaults("id"), scheduledThreadPool).withBulkhead(Bulkhead.ofDefaults("testName")).get();
final CompletableFuture<String> completableFuture = completionStage.toCompletableFuture().exceptionally(throwable -> {
if (throwable != null) {
assertThat(Thread.currentThread().getName()).contains("ContextAwareScheduledThreadPool");
assertThat(TestThreadLocalContextHolder.get().get()).isEqualTo("ValueShouldCrossThreadBoundary");
return (String) TestThreadLocalContextHolder.get().orElse(null);
}
return null;
});
waitAtMost(2, TimeUnit.SECONDS).until(matches(() -> assertThat(completableFuture).isCompletedWithValue("ValueShouldCrossThreadBoundary")));
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(3);
then(asyncHelloWorldService).should(times(3)).returnHelloWorld();
}
use of io.github.resilience4j.core.ContextAwareScheduledThreadPoolExecutor in project resilience4j by resilience4j.
the class DecoratorsTest method testDecorateCompletionStagePropagatesMDCContextWithRetryAsync.
@Test
public void testDecorateCompletionStagePropagatesMDCContextWithRetryAsync() {
given(helloWorldService.returnHelloWorld()).willReturn("Hello world");
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("helloBackend");
MDC.put("key", "ValueShouldCrossThreadBoundary");
MDC.put("key2", "value2");
final Map<String, String> contextMap = MDC.getCopyOfContextMap();
ContextAwareScheduledThreadPoolExecutor scheduledThreadPool = ContextAwareScheduledThreadPoolExecutor.newScheduledThreadPool().corePoolSize(1).build();
CompletableFuture<String> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(new HelloWorldException());
given(asyncHelloWorldService.returnHelloWorld()).willReturn(failedFuture);
CompletionStage<String> completionStage = Decorators.ofCompletionStage(() -> asyncHelloWorldService.returnHelloWorld()).withCircuitBreaker(circuitBreaker).withRetry(Retry.ofDefaults("id"), scheduledThreadPool).withBulkhead(Bulkhead.ofDefaults("testName")).get();
final CompletableFuture<String> completableFuture = completionStage.toCompletableFuture().exceptionally(throwable -> {
if (throwable != null) {
assertThat(Thread.currentThread().getName()).contains("ContextAwareScheduledThreadPool");
assertThat(MDC.getCopyOfContextMap()).hasSize(2).containsExactlyEntriesOf(contextMap);
return MDC.getCopyOfContextMap().get("key");
}
return null;
});
waitAtMost(2, TimeUnit.SECONDS).until(matches(() -> assertThat(completableFuture).isCompletedWithValue("ValueShouldCrossThreadBoundary")));
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(3);
then(asyncHelloWorldService).should(times(3)).returnHelloWorld();
}
use of io.github.resilience4j.core.ContextAwareScheduledThreadPoolExecutor in project resilience4j by resilience4j.
the class ContextAwareScheduledThreadPoolConfigurationPropertiesTest method buildPropertiesWithNoContextPropagator.
@Test
public void buildPropertiesWithNoContextPropagator() {
ContextAwareScheduledThreadPoolConfigurationProperties poolConfigurationProperties = new ContextAwareScheduledThreadPoolConfigurationProperties();
poolConfigurationProperties.setCorePoolSize(10);
final ContextAwareScheduledThreadPoolExecutor contextAwareScheduledThreadPoolExecutor = poolConfigurationProperties.build();
assertThat(contextAwareScheduledThreadPoolExecutor.getCorePoolSize()).isEqualTo(10);
assertThat(contextAwareScheduledThreadPoolExecutor.getContextPropagators()).isEmpty();
}
use of io.github.resilience4j.core.ContextAwareScheduledThreadPoolExecutor in project resilience4j by resilience4j.
the class ContextAwareScheduledThreadPoolConfigurationPropertiesTest method buildPropertiesWithValidArguments.
@Test
public void buildPropertiesWithValidArguments() {
ContextAwareScheduledThreadPoolConfigurationProperties poolConfigurationProperties = new ContextAwareScheduledThreadPoolConfigurationProperties();
poolConfigurationProperties.setContextPropagators(TestThreadLocalContextPropagatorWithHolder.class);
poolConfigurationProperties.setCorePoolSize(10);
final ContextAwareScheduledThreadPoolExecutor contextAwareScheduledThreadPoolExecutor = poolConfigurationProperties.build();
assertThat(contextAwareScheduledThreadPoolExecutor.getCorePoolSize()).isEqualTo(10);
assertThat(contextAwareScheduledThreadPoolExecutor.getContextPropagators()).hasSize(1).hasOnlyElementsOfTypes(TestThreadLocalContextPropagatorWithHolder.class);
}
Aggregations