Skip to content

Commit 4865eae

Browse files
authored
Merge pull request #44212 from geoand/#44180
Add a cleanup SPI for the REST Client
2 parents 4900b2a + 46112ec commit 4865eae

File tree

6 files changed

+68
-1
lines changed

6 files changed

+68
-1
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import jakarta.ws.rs.core.MediaType;
1111

1212
import org.jboss.jandex.DotName;
13+
import org.jboss.resteasy.reactive.client.impl.RestClientClosingTask;
1314

1415
import com.fasterxml.jackson.databind.ObjectMapper;
1516

@@ -18,10 +19,12 @@
1819
import io.quarkus.deployment.annotations.BuildProducer;
1920
import io.quarkus.deployment.annotations.BuildStep;
2021
import io.quarkus.deployment.builditem.FeatureBuildItem;
22+
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
2123
import io.quarkus.rest.client.reactive.deployment.AnnotationToRegisterIntoClientContextBuildItem;
2224
import io.quarkus.rest.client.reactive.jackson.ClientObjectMapper;
2325
import io.quarkus.rest.client.reactive.jackson.runtime.serialisers.ClientJacksonMessageBodyReader;
2426
import io.quarkus.rest.client.reactive.jackson.runtime.serialisers.ClientJacksonMessageBodyWriter;
27+
import io.quarkus.rest.client.reactive.jackson.runtime.serialisers.JacksonCleanupRestClientClosingTask;
2528
import io.quarkus.resteasy.reactive.jackson.deployment.processor.ResteasyReactiveJacksonProviderDefinedBuildItem;
2629
import io.quarkus.resteasy.reactive.jackson.runtime.serialisers.vertx.VertxJsonArrayBasicMessageBodyReader;
2730
import io.quarkus.resteasy.reactive.jackson.runtime.serialisers.vertx.VertxJsonArrayBasicMessageBodyWriter;
@@ -116,4 +119,10 @@ void additionalProviders(
116119
.setRuntimeType(RuntimeType.CLIENT)
117120
.build());
118121
}
122+
123+
@BuildStep
124+
void nativeSupport(BuildProducer<ServiceProviderBuildItem> serviceProviderProducer) {
125+
serviceProviderProducer.produce(new ServiceProviderBuildItem(RestClientClosingTask.class.getName(),
126+
JacksonCleanupRestClientClosingTask.class.getName()));
127+
}
119128
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.quarkus.rest.client.reactive.jackson.runtime.serialisers;
2+
3+
import org.jboss.resteasy.reactive.client.impl.RestClientClosingTask;
4+
5+
import io.quarkus.rest.client.reactive.jackson.ClientObjectMapper;
6+
7+
/**
8+
* Cleans up the mappings that is needed to support {@link ClientObjectMapper}
9+
*/
10+
public class JacksonCleanupRestClientClosingTask implements RestClientClosingTask {
11+
12+
@Override
13+
public void close(Context context) {
14+
JacksonUtil.contextResolverMap
15+
.remove(new ResolverMapKey(context.baseTarget().getConfiguration(), context.restApiClass()));
16+
}
17+
}

extensions/resteasy-reactive/rest-client-jackson/runtime/src/main/java/io/quarkus/rest/client/reactive/jackson/runtime/serialisers/JacksonUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
final class JacksonUtil {
1616

17-
private static final ConcurrentMap<ResolverMapKey, ObjectMapper> contextResolverMap = new ConcurrentHashMap<>();
17+
static final ConcurrentMap<ResolverMapKey, ObjectMapper> contextResolverMap = new ConcurrentHashMap<>();
1818

1919
private JacksonUtil() {
2020
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.quarkus.rest.client.reactive.jackson.runtime.serialisers.JacksonCleanupRestClientClosingTask

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import org.jboss.resteasy.reactive.client.impl.ClientBuilderImpl;
9090
import org.jboss.resteasy.reactive.client.impl.ClientImpl;
9191
import org.jboss.resteasy.reactive.client.impl.MultiInvoker;
92+
import org.jboss.resteasy.reactive.client.impl.RestClientClosingTask;
9293
import org.jboss.resteasy.reactive.client.impl.SseEventSourceBuilderImpl;
9394
import org.jboss.resteasy.reactive.client.impl.StorkClientRequestFilter;
9495
import org.jboss.resteasy.reactive.client.impl.UniInvoker;
@@ -1214,6 +1215,15 @@ A more full example of generated client (with sub-resource) can is at the bottom
12141215
.getMethodCreator(MethodDescriptor.ofMethod(Closeable.class, "close", void.class));
12151216
ResultHandle webTarget = closeCreator.readInstanceField(baseTargetField, closeCreator.getThis());
12161217
ResultHandle webTargetImpl = closeCreator.checkCast(webTarget, WebTargetImpl.class);
1218+
ResultHandle restApiClass = closeCreator.loadClassFromTCCL(restClientInterface.getClassName());
1219+
ResultHandle context = closeCreator.newInstance(
1220+
MethodDescriptor.ofConstructor(RestClientClosingTask.Context.class, Class.class, WebTargetImpl.class),
1221+
restApiClass,
1222+
webTargetImpl);
1223+
closeCreator.invokeStaticInterfaceMethod(
1224+
MethodDescriptor.ofMethod(RestClientClosingTask.class, "invokeAll", void.class,
1225+
RestClientClosingTask.Context.class),
1226+
context);
12171227
ResultHandle restClient = closeCreator.invokeVirtualMethod(
12181228
MethodDescriptor.ofMethod(WebTargetImpl.class, "getRestClient", ClientImpl.class), webTargetImpl);
12191229
closeCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(ClientImpl.class, "close", void.class), restClient);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.jboss.resteasy.reactive.client.impl;
2+
3+
import java.util.ServiceLoader;
4+
5+
import org.jboss.logging.Logger;
6+
7+
/**
8+
* This represents a task that will be called by the implementation class of the REST Client when the {@code close}
9+
* method is called.
10+
*/
11+
public interface RestClientClosingTask {
12+
13+
Logger log = Logger.getLogger(RestClientClosingTask.class);
14+
15+
void close(Context context);
16+
17+
record Context(Class<?> restApiClass, WebTargetImpl baseTarget) {
18+
}
19+
20+
@SuppressWarnings("unused") // this is called by the implementation class of the REST Client when the {@code close} method is called
21+
static void invokeAll(Context context) {
22+
for (RestClientClosingTask restClientClosingTask : ServiceLoader.load(RestClientClosingTask.class)) {
23+
try {
24+
restClientClosingTask.close(context);
25+
} catch (Exception e) {
26+
log.warn("Error running RestClientClosingTask", e);
27+
}
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)