Skip to content

Commit

Permalink
Fault Tolerance: fix duplicate circuit breaker name detection
Browse files Browse the repository at this point in the history
Previously, duplicate circuit breaker names were detected in a crude way:
find all occurences of `@CircuitBreakerName` in the Jandex index, collect
the values, and fail of some value is present more than once.

With this commit, circuit breaker names are collected in a more precise
way: only from beans, and only from methods that are actually detected
as methods with fault tolerance annotations. This even correctly includes
transformed annotations.
  • Loading branch information
Ladicek committed Sep 22, 2023
1 parent d98090e commit ee53dd9
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ boolean hasFTAnnotations(ClassInfo clazz) {
void forEachMethod(ClassInfo clazz, Consumer<MethodInfo> action) {
for (MethodInfo method : clazz.methods()) {
if (method.name().startsWith("<")) {
// constructors (or static init blocks) can't be intercepted
// constructors and static inititalizers can't be intercepted
continue;
}
if (method.isSynthetic()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem;
Expand Down Expand Up @@ -279,6 +278,7 @@ void processFaultToleranceAnnotations(SmallRyeFaultToleranceRecorder recorder,

List<FaultToleranceMethod> ftMethods = new ArrayList<>();
List<Throwable> exceptions = new ArrayList<>();
Map<String, Set<String>> existingCircuitBreakerNames = new HashMap<>();

for (BeanInfo info : validationPhase.getContext().beans()) {
ClassInfo beanClass = info.getImplClazz();
Expand Down Expand Up @@ -319,6 +319,12 @@ void processFaultToleranceAnnotations(SmallRyeFaultToleranceRecorder recorder,
reflectiveClass.produce(ReflectiveClassBuildItem.builder(exceptionNames.get()).build());
}
}

if (annotationStore.hasAnnotation(method, DotNames.CIRCUIT_BREAKER_NAME)) {
AnnotationInstance ann = annotationStore.getAnnotation(method, DotNames.CIRCUIT_BREAKER_NAME);
existingCircuitBreakerNames.computeIfAbsent(ann.value().asString(), ignored -> new HashSet<>())
.add(method + " @ " + method.declaringClass());
}
}
});

Expand All @@ -337,16 +343,6 @@ void processFaultToleranceAnnotations(SmallRyeFaultToleranceRecorder recorder,

recorder.createFaultToleranceOperation(ftMethods);

// since annotation transformations are applied lazily, we can't know
// all transformed `@CircuitBreakerName`s and have to rely on Jandex here
Map<String, Set<String>> existingCircuitBreakerNames = new HashMap<>();
for (AnnotationInstance it : index.getAnnotations(DotNames.CIRCUIT_BREAKER_NAME)) {
if (it.target().kind() == Kind.METHOD) {
MethodInfo method = it.target().asMethod();
existingCircuitBreakerNames.computeIfAbsent(it.value().asString(), ignored -> new HashSet<>())
.add(method + " @ " + method.declaringClass());
}
}
for (Map.Entry<String, Set<String>> entry : existingCircuitBreakerNames.entrySet()) {
if (entry.getValue().size() > 1) {
exceptions.add(new DefinitionException("Multiple circuit breakers have the same name '"
Expand Down

0 comments on commit ee53dd9

Please sign in to comment.