Skip to content

Commit 95a309e

Browse files
committed
Lift requirement of setting REST Client base URL when mocks are used
Closes: quarkusio#47383
1 parent a72deaa commit 95a309e

File tree

5 files changed

+29
-10
lines changed

5 files changed

+29
-10
lines changed

extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@
2828
import java.lang.reflect.Modifier;
2929
import java.util.ArrayList;
3030
import java.util.Collection;
31+
import java.util.Collections;
3132
import java.util.HashMap;
3233
import java.util.HashSet;
3334
import java.util.List;
3435
import java.util.Map;
3536
import java.util.Optional;
3637
import java.util.Set;
3738
import java.util.function.Predicate;
39+
import java.util.stream.Collectors;
3840

3941
import jakarta.enterprise.context.SessionScoped;
4042
import jakarta.enterprise.inject.Typed;
@@ -87,6 +89,7 @@
8789
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
8890
import io.quarkus.deployment.builditem.FeatureBuildItem;
8991
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
92+
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
9093
import io.quarkus.deployment.builditem.RunTimeConfigBuilderBuildItem;
9194
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
9295
import io.quarkus.deployment.builditem.StaticInitConfigBuilderBuildItem;
@@ -119,7 +122,9 @@ class RestClientReactiveProcessor {
119122
private static final Logger log = Logger.getLogger(RestClientReactiveProcessor.class);
120123

121124
private static final DotName REGISTER_REST_CLIENT = DotName.createSimple(RegisterRestClient.class.getName());
125+
private static final DotName REST_CLIENT = DotName.createSimple(RestClient.class.getName());
122126
private static final DotName SESSION_SCOPED = DotName.createSimple(SessionScoped.class.getName());
127+
private static final DotName INJECT_MOCK = DotName.createSimple("io.quarkus.test.InjectMock");
123128
private static final DotName KOTLIN_METADATA_ANNOTATION = DotName.createSimple("kotlin.Metadata");
124129

125130
private static final String ENABLE_COMPRESSION = "quarkus.http.enable-compression";
@@ -473,11 +478,24 @@ void addRestClientBeans(Capabilities capabilities,
473478
BuildProducer<GeneratedBeanBuildItem> generatedBeans,
474479
RestClientReactiveConfig clientConfig,
475480
RestClientsBuildTimeConfig clientsBuildConfig,
481+
LaunchModeBuildItem launchMode,
476482
RestClientRecorder recorder,
477483
ShutdownContextBuildItem shutdown) {
478484

479485
CompositeIndex index = CompositeIndex.create(combinedIndexBuildItem.getIndex());
480486

487+
Set<DotName> requestedRestClientMocks = Collections.emptySet();
488+
if (launchMode.getLaunchMode() == LaunchMode.TEST) {
489+
// we need to determine which RestClient interfaces have been marked for mocking
490+
requestedRestClientMocks = combinedIndexBuildItem.getIndex().getAnnotations(INJECT_MOCK)
491+
.stream()
492+
.filter(ai -> ai.target().kind() == AnnotationTarget.Kind.FIELD)
493+
.map(ai -> ai.target().asField())
494+
.filter(f -> f.hasAnnotation(REST_CLIENT))
495+
.map(f -> f.type().name())
496+
.collect(Collectors.toSet());
497+
}
498+
481499
Map<String, String> configKeys = new HashMap<>();
482500
var annotationsStore = new AnnotationStore(index, restClientAnnotationsTransformerBuildItem.stream()
483501
.map(RestClientAnnotationsTransformerBuildItem::getAnnotationTransformation).toList());
@@ -552,14 +570,16 @@ void addRestClientBeans(Capabilities capabilities,
552570
Optional<String> baseUri = registerRestClient.getDefaultBaseUri();
553571

554572
ResultHandle baseUriHandle = constructor.load(baseUri.isPresent() ? baseUri.get() : "");
573+
boolean lazyDelegate = scope.getDotName().equals(REQUEST_SCOPED)
574+
|| requestedRestClientMocks.contains(jaxrsInterface.name());
555575
constructor.invokeSpecialMethod(
556576
MethodDescriptor.ofConstructor(RestClientReactiveCDIWrapperBase.class, Class.class, String.class,
557577
String.class, boolean.class),
558578
constructor.getThis(),
559579
constructor.loadClassFromTCCL(jaxrsInterface.toString()),
560580
baseUriHandle,
561581
configKey.isPresent() ? constructor.load(configKey.get()) : constructor.loadNull(),
562-
constructor.load(scope.getDotName().equals(REQUEST_SCOPED)));
582+
constructor.load(lazyDelegate));
563583
constructor.returnValue(null);
564584

565585
// METHODS:

extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientReactiveCDIWrapperBase.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ public abstract class RestClientReactiveCDIWrapperBase<T extends Closeable> impl
2121
private Object mock;
2222

2323
public RestClientReactiveCDIWrapperBase(Class<T> jaxrsInterface, String baseUriFromAnnotation,
24-
String configKey, boolean requestScope) {
24+
String configKey, boolean lazyDelegate) {
2525
this.jaxrsInterface = jaxrsInterface;
2626
this.baseUriFromAnnotation = baseUriFromAnnotation;
2727
this.configKey = configKey;
28-
if (!requestScope) {
29-
// when not using the Request scope, we eagerly create the delegate
30-
delegate();
28+
if (!lazyDelegate) {
29+
constructDelegate();
3130
}
3231
}
3332

@@ -55,7 +54,7 @@ public void destroy() {
5554
@SuppressWarnings("unused")
5655
@NoClassInterceptors
5756
public Object getDelegate() {
58-
return mock == null ? delegate() : mock;
57+
return mock == null ? constructDelegate() : mock;
5958
}
6059

6160
@Override
@@ -71,7 +70,7 @@ public void clearMock() {
7170
}
7271

7372
@NoClassInterceptors
74-
private T delegate() {
73+
private T constructDelegate() {
7574
if (delegate == null) {
7675
delegate = RestClientCDIDelegateBuilder.createDelegate(jaxrsInterface, baseUriFromAnnotation, configKey);
7776
}

integration-tests/rest-client-reactive/src/main/java/io/quarkus/it/rest/client/main/FaultToleranceOnInterfaceClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
1313

1414
@Path("/unprocessable")
15-
@RegisterRestClient(configKey = "w-fault-tolerance")
15+
@RegisterRestClient(configKey = "w-fault-tolerance-int")
1616
@CircuitBreaker(requestVolumeThreshold = 2, delay = 1, delayUnit = ChronoUnit.MINUTES)
1717
public interface FaultToleranceOnInterfaceClient {
1818
@GET

integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/InjectMockTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
import io.quarkus.it.rest.client.main.ClientWithExceptionMapper;
1313
import io.quarkus.it.rest.client.main.MyResponseExceptionMapper;
14+
import io.quarkus.test.InjectMock;
1415
import io.quarkus.test.junit.QuarkusTest;
15-
import io.quarkus.test.junit.mockito.InjectMock;
1616
import io.restassured.RestAssured;
1717

1818
@QuarkusTest

integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/InjectMockWithInterceptorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import org.junit.jupiter.api.Test;
1313

1414
import io.quarkus.it.rest.client.main.FaultToleranceOnInterfaceClient;
15+
import io.quarkus.test.InjectMock;
1516
import io.quarkus.test.junit.QuarkusTest;
16-
import io.quarkus.test.junit.mockito.InjectMock;
1717
import io.restassured.RestAssured;
1818
import io.smallrye.faulttolerance.api.CircuitBreakerMaintenance;
1919

0 commit comments

Comments
 (0)