Skip to content

Commit

Permalink
Merge pull request #18361 from Ladicek/fault-tolerance-config
Browse files Browse the repository at this point in the history
Update to SmallRye Fault Tolerance 5.2.0
  • Loading branch information
Ladicek authored Jul 16, 2021
2 parents 01f0ef9 + 47476df commit 0bf3600
Show file tree
Hide file tree
Showing 25 changed files with 847 additions and 112 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<smallrye-open-api.version>2.1.7</smallrye-open-api.version>
<smallrye-graphql.version>1.2.8</smallrye-graphql.version>
<smallrye-opentracing.version>2.0.0</smallrye-opentracing.version>
<smallrye-fault-tolerance.version>5.1.0</smallrye-fault-tolerance.version>
<smallrye-fault-tolerance.version>5.2.0</smallrye-fault-tolerance.version>
<smallrye-jwt.version>3.2.0</smallrye-jwt.version>
<smallrye-context-propagation.version>1.2.0</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
@@ -1,5 +1,6 @@
package io.quarkus.deployment.util;

import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -375,4 +376,56 @@ public ClassNotIndexedException(DotName dotName) {
this.dotName = dotName;
}
}

public static Class<?> loadRawType(Type type) {
switch (type.kind()) {
case VOID:
return void.class;
case PRIMITIVE:
switch (type.asPrimitiveType().primitive()) {
case BOOLEAN:
return boolean.class;
case CHAR:
return char.class;
case BYTE:
return byte.class;
case SHORT:
return short.class;
case INT:
return int.class;
case LONG:
return long.class;
case FLOAT:
return float.class;
case DOUBLE:
return double.class;
default:
throw new IllegalArgumentException("Unknown primitive type: " + type);
}
case CLASS:
return load(type.asClassType().name());
case PARAMETERIZED_TYPE:
return load(type.asParameterizedType().name());
case ARRAY:
Class<?> component = loadRawType(type.asArrayType().component());
int dimensions = type.asArrayType().dimensions();
return Array.newInstance(component, new int[dimensions]).getClass();
case WILDCARD_TYPE:
return loadRawType(type.asWildcardType().extendsBound());
case TYPE_VARIABLE:
return load(type.asTypeVariable().name());
case UNRESOLVED_TYPE_VARIABLE:
return Object.class; // can't do better here
default:
throw new IllegalArgumentException("Unknown type: " + type);
}
}

private static Class<?> load(DotName name) {
try {
return Thread.currentThread().getContextClassLoader().loadClass(name.toString());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

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

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
Expand Down Expand Up @@ -302,6 +305,72 @@ public static class MultiBoundedRepo<X extends A & B> implements Repo<X> {
public static class ErasedRepo2 extends MultiBoundedRepo {
}

@Test
public void testLoadRawType() {
Index index = index(TestMethods.class);
ClassInfo clazz = index.getClassByName(DotName.createSimple(TestMethods.class.getName()));

assertEquals(void.class, JandexUtil.loadRawType(clazz.method("aaa").returnType()));
assertEquals(int.class, JandexUtil.loadRawType(clazz.method("bbb").returnType()));
assertEquals(String.class, JandexUtil.loadRawType(clazz.method("ccc").returnType()));
assertEquals(List.class, JandexUtil.loadRawType(clazz.method("ddd").returnType()));
assertEquals(String[][].class, JandexUtil.loadRawType(clazz.method("eee").returnType()));
assertEquals(Object.class, JandexUtil.loadRawType(clazz.method("fff").returnType()));
assertEquals(Number.class, JandexUtil.loadRawType(clazz.method("ggg").returnType()));
assertEquals(Number.class, JandexUtil.loadRawType(clazz.method("hhh").returnType()));
assertEquals(Comparable.class, JandexUtil.loadRawType(clazz.method("iii").returnType()));
assertEquals(Comparable.class, JandexUtil.loadRawType(clazz.method("jjj").returnType()));
assertEquals(Serializable.class, JandexUtil.loadRawType(clazz.method("kkk").returnType()));
assertEquals(Object.class, JandexUtil.loadRawType(clazz.method("lll").returnType()
.asParameterizedType().arguments().get(0)));
assertEquals(Number.class, JandexUtil.loadRawType(clazz.method("mmm").returnType()
.asParameterizedType().arguments().get(0)));
assertEquals(Object.class, JandexUtil.loadRawType(clazz.method("nnn").returnType()
.asParameterizedType().arguments().get(0)));
assertEquals(Object.class, JandexUtil.loadRawType(clazz.method("ooo").returnType()
.asParameterizedType().arguments().get(0)));
assertEquals(Number.class, JandexUtil.loadRawType(clazz.method("ppp").returnType()
.asParameterizedType().arguments().get(0)));
assertEquals(Object.class, JandexUtil.loadRawType(clazz.method("qqq").returnType()
.asParameterizedType().arguments().get(0)));
}

public interface TestMethods<X> {
void aaa();

int bbb();

String ccc();

List<String> ddd();

String[][] eee();

X fff();

<Y extends Number> Y ggg();

<Y extends Number & Comparable<Y>> Y hhh();

<Y extends Comparable<Y>> Y iii();

<Y extends Comparable<Y> & Serializable> Y jjj();

<Y extends Serializable & Comparable<Y>> Y kkk();

List<?> lll();

List<? extends Number> mmm();

List<? super String> nnn();

List<? extends X> ooo();

<Y extends Number> List<? extends Y> ppp();

<Y extends Number> List<? super Y> qqq();
}

private static Index index(Class<?>... classes) {
Indexer indexer = new Indexer();
for (Class<?> clazz : classes) {
Expand Down
19 changes: 16 additions & 3 deletions docs/src/main/asciidoc/smallrye-fault-tolerance.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -504,13 +504,13 @@ All that is needed to enable the fault tolerance features in Quarkus is:
== Additional resources

SmallRye Fault Tolerance has more features than shown here.
Please check the link:https://smallrye.io/docs/smallrye-fault-tolerance/5.1.0/index.html[SmallRye Fault Tolerance documentation] to learn about them.
Please check the link:https://smallrye.io/docs/smallrye-fault-tolerance/5.2.0/index.html[SmallRye Fault Tolerance documentation] to learn about them.

In Quarkus, you can use the SmallRye Fault Tolerance optional features out of the box.

Support for Mutiny is present, so your `@Asynchronous` methods can return `Uni`.
Support for Mutiny is present, so your asynchronous methods can return `Uni` in addition to `CompletionStage`.

MicroProfile Context Propagation is integrated with Fault Tolerance, so existing contexts are automatically propagated to your `@Asynchronous` methods.
MicroProfile Context Propagation is integrated with Fault Tolerance, so existing contexts are automatically propagated to your asynchronous methods.

[NOTE]
====
Expand All @@ -520,3 +520,16 @@ This is contrary to MicroProfile Fault Tolerance specification, which states tha
We believe that in presence of MicroProfile Context Propagation, this requirement should not apply.
The entire point of context propagation is to make sure the new thread has the same contexts as the original thread.
====

Non-compatible mode is enabled by default, so methods that return `CompletionStage` (or `Uni`) have asynchronous fault tolerance applied without any `@Asynchronous`, `@Blocking` or `@NonBlocking` annotation.

[NOTE]
====
This mode is not compatible with the MicroProfile Fault Tolerance specification, albeit the incompatibility is very small.
To restore full compatibility, add this configuration property:
[source,properties]
----
smallrye.faulttolerance.mp-compatibility=true
----
====
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.quarkus.smallrye.faulttolerance.deployment;

import java.util.Set;

import org.eclipse.microprofile.faulttolerance.Asynchronous;
import org.eclipse.microprofile.faulttolerance.Bulkhead;
import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.faulttolerance.Retry;
import org.eclipse.microprofile.faulttolerance.Timeout;
import org.jboss.jandex.DotName;

import io.smallrye.common.annotation.Blocking;
import io.smallrye.common.annotation.NonBlocking;
import io.smallrye.faulttolerance.api.CircuitBreakerName;
import io.smallrye.faulttolerance.api.CustomBackoff;
import io.smallrye.faulttolerance.api.CustomBackoffStrategy;
import io.smallrye.faulttolerance.api.ExponentialBackoff;
import io.smallrye.faulttolerance.api.FibonacciBackoff;

public final class DotNames {
public static final DotName OBJECT = DotName.createSimple(Object.class.getName());

public static final DotName ASYNCHRONOUS = DotName.createSimple(Asynchronous.class.getName());
public static final DotName BULKHEAD = DotName.createSimple(Bulkhead.class.getName());
public static final DotName CIRCUIT_BREAKER = DotName.createSimple(CircuitBreaker.class.getName());
public static final DotName FALLBACK = DotName.createSimple(Fallback.class.getName());
public static final DotName RETRY = DotName.createSimple(Retry.class.getName());
public static final DotName TIMEOUT = DotName.createSimple(Timeout.class.getName());

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

public static final DotName BLOCKING = DotName.createSimple(Blocking.class.getName());
public static final DotName NON_BLOCKING = DotName.createSimple(NonBlocking.class.getName());

public static final DotName CIRCUIT_BREAKER_NAME = DotName.createSimple(CircuitBreakerName.class.getName());

public static final DotName EXPONENTIAL_BACKOFF = DotName.createSimple(ExponentialBackoff.class.getName());
public static final DotName FIBONACCI_BACKOFF = DotName.createSimple(FibonacciBackoff.class.getName());
public static final DotName CUSTOM_BACKOFF = DotName.createSimple(CustomBackoff.class.getName());
public static final DotName CUSTOM_BACKOFF_STRATEGY = DotName.createSimple(CustomBackoffStrategy.class.getName());

public static final Set<DotName> BACKOFF_ANNOTATIONS = Set.of(EXPONENTIAL_BACKOFF, FIBONACCI_BACKOFF, CUSTOM_BACKOFF);
}
Loading

0 comments on commit 0bf3600

Please sign in to comment.