Skip to content

Commit

Permalink
Upgrade to SmallRye Fault Tolerance 6.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Ladicek authored and holly-cummins committed Jul 31, 2024
1 parent 0c47660 commit c5ab66e
Show file tree
Hide file tree
Showing 20 changed files with 415 additions and 12 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
<smallrye-open-api.version>3.10.0</smallrye-open-api.version>
<smallrye-graphql.version>2.9.0</smallrye-graphql.version>
<smallrye-fault-tolerance.version>6.3.0</smallrye-fault-tolerance.version>
<smallrye-fault-tolerance.version>6.4.0</smallrye-fault-tolerance.version>
<smallrye-jwt.version>4.5.3</smallrye-jwt.version>
<smallrye-context-propagation.version>2.1.2</smallrye-context-propagation.version>
<smallrye-reactive-streams-operators.version>1.0.13</smallrye-reactive-streams-operators.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import io.smallrye.faulttolerance.FaultToleranceInterceptor;
import io.smallrye.faulttolerance.api.ApplyFaultTolerance;
import io.smallrye.faulttolerance.api.AsynchronousNonBlocking;
import io.smallrye.faulttolerance.api.BeforeRetry;
import io.smallrye.faulttolerance.api.BeforeRetryHandler;
import io.smallrye.faulttolerance.api.CircuitBreakerName;
import io.smallrye.faulttolerance.api.CustomBackoff;
import io.smallrye.faulttolerance.api.CustomBackoffStrategy;
Expand All @@ -28,6 +30,7 @@ public final class DotNames {
public static final DotName OBJECT = DotName.createSimple(Object.class);

public static final DotName FALLBACK_HANDLER = DotName.createSimple(FallbackHandler.class);
public static final DotName BEFORE_RETRY_HANDLER = DotName.createSimple(BeforeRetryHandler.class);

public static final DotName FAULT_TOLERANCE_INTERCEPTOR = DotName.createSimple(FaultToleranceInterceptor.class);

Expand All @@ -54,9 +57,11 @@ public final class DotNames {
public static final DotName CUSTOM_BACKOFF = DotName.createSimple(CustomBackoff.class);
public static final DotName CUSTOM_BACKOFF_STRATEGY = DotName.createSimple(CustomBackoffStrategy.class);
public static final DotName RETRY_WHEN = DotName.createSimple(RetryWhen.class);
public static final DotName BEFORE_RETRY = DotName.createSimple(BeforeRetry.class);

// certain SmallRye annotations (@CircuitBreakerName, @[Non]Blocking, @*Backoff, @RetryWhen) alone do _not_ trigger
// the fault tolerance interceptor, only in combination with other fault tolerance annotations
// certain SmallRye annotations (@CircuitBreakerName, @[Non]Blocking, @*Backoff, @RetryWhen, @BeforeRetry)
// do _not_ trigger the fault tolerance interceptor alone, only in combination
// with other fault tolerance annotations
public static final Set<DotName> FT_ANNOTATIONS = Set.of(APPLY_FAULT_TOLERANCE, ASYNCHRONOUS,
ASYNCHRONOUS_NON_BLOCKING, BULKHEAD, CIRCUIT_BREAKER, FALLBACK, RATE_LIMIT, RETRY, TIMEOUT);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.smallrye.common.annotation.NonBlocking;
import io.smallrye.faulttolerance.api.ApplyFaultTolerance;
import io.smallrye.faulttolerance.api.AsynchronousNonBlocking;
import io.smallrye.faulttolerance.api.BeforeRetry;
import io.smallrye.faulttolerance.api.CircuitBreakerName;
import io.smallrye.faulttolerance.api.CustomBackoff;
import io.smallrye.faulttolerance.api.ExponentialBackoff;
Expand Down Expand Up @@ -136,6 +137,7 @@ FaultToleranceMethod createFaultToleranceMethod(ClassInfo beanClass, MethodInfo
result.exponentialBackoff = getAnnotation(ExponentialBackoff.class, method, beanClass, annotationsPresentDirectly);
result.fibonacciBackoff = getAnnotation(FibonacciBackoff.class, method, beanClass, annotationsPresentDirectly);
result.retryWhen = getAnnotation(RetryWhen.class, method, beanClass, annotationsPresentDirectly);
result.beforeRetry = getAnnotation(BeforeRetry.class, method, beanClass, annotationsPresentDirectly);

result.annotationsPresentDirectly = annotationsPresentDirectly;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import io.quarkus.runtime.metrics.MetricsFactory;
import io.quarkus.smallrye.faulttolerance.deployment.devui.FaultToleranceInfoBuildItem;
import io.quarkus.smallrye.faulttolerance.runtime.QuarkusAsyncExecutorProvider;
import io.quarkus.smallrye.faulttolerance.runtime.QuarkusBeforeRetryHandlerProvider;
import io.quarkus.smallrye.faulttolerance.runtime.QuarkusExistingCircuitBreakerNames;
import io.quarkus.smallrye.faulttolerance.runtime.QuarkusFallbackHandlerProvider;
import io.quarkus.smallrye.faulttolerance.runtime.QuarkusFaultToleranceOperationProvider;
Expand Down Expand Up @@ -102,19 +103,22 @@ public void build(BuildProducer<AnnotationsTransformerBuildItem> annotationsTran

IndexView index = combinedIndexBuildItem.getIndex();

// Add reflective access to fallback handlers
Set<String> fallbackHandlers = new HashSet<>();
// Add reflective access to fallback handlers and before retry handlers
Set<String> handlers = new HashSet<>();
for (ClassInfo implementor : index.getAllKnownImplementors(DotNames.FALLBACK_HANDLER)) {
fallbackHandlers.add(implementor.name().toString());
handlers.add(implementor.name().toString());
}
if (!fallbackHandlers.isEmpty()) {
AdditionalBeanBuildItem.Builder fallbackHandlersBeans = AdditionalBeanBuildItem.builder()
for (ClassInfo implementor : index.getAllKnownImplementors(DotNames.BEFORE_RETRY_HANDLER)) {
handlers.add(implementor.name().toString());
}
if (!handlers.isEmpty()) {
AdditionalBeanBuildItem.Builder handlerBeans = AdditionalBeanBuildItem.builder()
.setDefaultScope(BuiltinScope.DEPENDENT.getName());
for (String fallbackHandler : fallbackHandlers) {
reflectiveClass.produce(ReflectiveClassBuildItem.builder(fallbackHandler).methods().build());
fallbackHandlersBeans.addBeanClass(fallbackHandler);
for (String handler : handlers) {
reflectiveClass.produce(ReflectiveClassBuildItem.builder(handler).methods().build());
handlerBeans.addBeanClass(handler);
}
beans.produce(fallbackHandlersBeans.build());
beans.produce(handlerBeans.build());
}
// Add reflective access to fallback methods
for (AnnotationInstance annotation : index.getAnnotations(DotNames.FALLBACK)) {
Expand Down Expand Up @@ -200,6 +204,7 @@ public void transform(TransformationContext context) {
ExecutorHolder.class,
StrategyCache.class,
QuarkusFallbackHandlerProvider.class,
QuarkusBeforeRetryHandlerProvider.class,
QuarkusAsyncExecutorProvider.class,
CircuitBreakerMaintenanceImpl.class,
RequestContextIntegration.class,
Expand Down Expand Up @@ -376,6 +381,11 @@ void processFaultToleranceAnnotations(SmallRyeFaultToleranceRecorder recorder,
exceptions.add(new DefinitionException("@RetryWhen present on '" + it.target() + "', but @Retry is missing"));
}
}
for (AnnotationInstance it : index.getAnnotations(DotNames.BEFORE_RETRY)) {
if (!annotationStore.hasAnnotation(it.target(), DotNames.RETRY)) {
exceptions.add(new DefinitionException("@BeforeRetry present on '" + it.target() + "', but @Retry is missing"));
}
}

if (!exceptions.isEmpty()) {
errors.produce(new ValidationPhaseBuildItem.ValidationErrorBuildItem(exceptions));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class QwcFaultToleranceMethods extends LitElement {
${guardedMethod.FibonacciBackoff ? this._renderFibonacciBackoff(guardedMethod.FibonacciBackoff) : html``}
${guardedMethod.CustomBackoff ? this._renderCustomBackoff(guardedMethod.CustomBackoff) : html``}
${guardedMethod.RetryWhen ? this._renderRetryWhen(guardedMethod.RetryWhen) : html``}
${guardedMethod.BeforeRetry ? this._renderBeforeRetry(guardedMethod.BeforeRetry) : html``}
${guardedMethod.Timeout ? this._renderTimeout(guardedMethod.Timeout) : html``}
</vaadin-vertical-layout>
`;
Expand Down Expand Up @@ -189,6 +190,15 @@ export class QwcFaultToleranceMethods extends LitElement {
`;
}

_renderBeforeRetry(beforeRetry) {
return html`
<span>
&rarrhk;
@BeforeRetry(value = ${beforeRetry.value}, methodName = ${beforeRetry.methodName})
</span>
`;
}

_renderTimeout(timeout) {
return html`
<span>@Timeout(${timeout.value} ${timeout.valueUnit})</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;

import org.eclipse.microprofile.faulttolerance.ExecutionContext;
import org.eclipse.microprofile.faulttolerance.Retry;

import io.smallrye.faulttolerance.api.BeforeRetry;
import io.smallrye.faulttolerance.api.BeforeRetryHandler;

@Dependent
public class BeforeRetryHandlerService {
static final Set<Integer> ids = ConcurrentHashMap.newKeySet();

@Retry
@BeforeRetry(MyBeforeRetryHandler.class)
public void hello() {
throw new IllegalArgumentException();
}

static class MyBeforeRetryHandler implements BeforeRetryHandler {
@Inject
MyDependency dep;

@Override
public void handle(ExecutionContext context) {
ids.add(dep.id);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class BeforeRetryHandlerTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(BeforeRetryHandlerService.class, MyDependency.class));

@Inject
BeforeRetryHandlerService service;

@Test
public void test() {
assertThrows(IllegalArgumentException.class, service::hello);
assertThat(BeforeRetryHandlerService.ids)
.hasSize(3)
.containsExactly(1, 2, 3);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import jakarta.enterprise.context.Dependent;

import org.eclipse.microprofile.faulttolerance.Retry;

import io.smallrye.faulttolerance.api.BeforeRetry;

@Dependent
public class BeforeRetryMethodService {
static final Set<Integer> ids = ConcurrentHashMap.newKeySet();
private static final AtomicInteger counter = new AtomicInteger();

@Retry
@BeforeRetry(methodName = "beforeRetry")
public void hello() {
throw new IllegalArgumentException();
}

void beforeRetry() {
ids.add(counter.incrementAndGet());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class BeforeRetryMethodTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(BeforeRetryMethodService.class));

@Inject
BeforeRetryMethodService service;

@Test
public void test() {
assertThrows(IllegalArgumentException.class, service::hello);
assertThat(BeforeRetryMethodService.ids)
.hasSize(3)
.containsExactly(1, 2, 3);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import jakarta.enterprise.context.Dependent;

import org.eclipse.microprofile.faulttolerance.ExecutionContext;
import org.eclipse.microprofile.faulttolerance.Retry;

import io.smallrye.faulttolerance.api.BeforeRetry;
import io.smallrye.faulttolerance.api.BeforeRetryHandler;

@Dependent
public class BothValueAndMethodNameSetService {
@Retry
@BeforeRetry(value = MyHandler.class, methodName = "beforeRetry")
public void hello() {
throw new IllegalArgumentException();
}

void beforeRetry() {
}

static class MyHandler implements BeforeRetryHandler {
@Override
public void handle(ExecutionContext context) {
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import jakarta.enterprise.inject.spi.DeploymentException;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class BothValueAndMethodNameSetTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(BothValueAndMethodNameSetService.class))
.assertException(e -> {
assertEquals(DeploymentException.class, e.getClass());
assertTrue(e.getMessage().contains("Invalid @BeforeRetry"));
assertTrue(e.getMessage().contains(
"before retry handler class and before retry method can't be specified both at the same time"));
});

@Test
public void test() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import java.util.concurrent.atomic.AtomicInteger;

import jakarta.enterprise.context.Dependent;

@Dependent
public class MyDependency {
private static final AtomicInteger counter = new AtomicInteger();

public final int id = counter.incrementAndGet();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import jakarta.enterprise.context.Dependent;

import org.eclipse.microprofile.faulttolerance.Retry;

import io.smallrye.faulttolerance.api.BeforeRetry;

@Dependent
public class NoBeforeRetryMethodFoundService {
@Retry
@BeforeRetry(methodName = "beforeRetry")
public void hello() {
throw new IllegalArgumentException();
}

public int beforeRetry(int param) {
return 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.quarkus.smallrye.faulttolerance.test.retry.beforeretry;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import jakarta.enterprise.inject.spi.DeploymentException;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class NoBeforeRetryMethodFoundTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(NoBeforeRetryMethodFoundService.class))
.assertException(e -> {
assertEquals(DeploymentException.class, e.getClass());
assertTrue(e.getMessage().contains("Invalid @BeforeRetry"));
assertTrue(e.getMessage().contains("can't find before retry method"));
});

@Test
public void test() {
}
}
Loading

0 comments on commit c5ab66e

Please sign in to comment.