Skip to content

Commit

Permalink
Merge pull request quarkusio#44212 from geoand/quarkusio#44180
Browse files Browse the repository at this point in the history
Add a cleanup SPI for the REST Client
  • Loading branch information
geoand authored Nov 6, 2024
2 parents 4900b2a + 46112ec commit 4865eae
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import jakarta.ws.rs.core.MediaType;

import org.jboss.jandex.DotName;
import org.jboss.resteasy.reactive.client.impl.RestClientClosingTask;

import com.fasterxml.jackson.databind.ObjectMapper;

Expand All @@ -18,10 +19,12 @@
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
import io.quarkus.rest.client.reactive.deployment.AnnotationToRegisterIntoClientContextBuildItem;
import io.quarkus.rest.client.reactive.jackson.ClientObjectMapper;
import io.quarkus.rest.client.reactive.jackson.runtime.serialisers.ClientJacksonMessageBodyReader;
import io.quarkus.rest.client.reactive.jackson.runtime.serialisers.ClientJacksonMessageBodyWriter;
import io.quarkus.rest.client.reactive.jackson.runtime.serialisers.JacksonCleanupRestClientClosingTask;
import io.quarkus.resteasy.reactive.jackson.deployment.processor.ResteasyReactiveJacksonProviderDefinedBuildItem;
import io.quarkus.resteasy.reactive.jackson.runtime.serialisers.vertx.VertxJsonArrayBasicMessageBodyReader;
import io.quarkus.resteasy.reactive.jackson.runtime.serialisers.vertx.VertxJsonArrayBasicMessageBodyWriter;
Expand Down Expand Up @@ -116,4 +119,10 @@ void additionalProviders(
.setRuntimeType(RuntimeType.CLIENT)
.build());
}

@BuildStep
void nativeSupport(BuildProducer<ServiceProviderBuildItem> serviceProviderProducer) {
serviceProviderProducer.produce(new ServiceProviderBuildItem(RestClientClosingTask.class.getName(),
JacksonCleanupRestClientClosingTask.class.getName()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.rest.client.reactive.jackson.runtime.serialisers;

import org.jboss.resteasy.reactive.client.impl.RestClientClosingTask;

import io.quarkus.rest.client.reactive.jackson.ClientObjectMapper;

/**
* Cleans up the mappings that is needed to support {@link ClientObjectMapper}
*/
public class JacksonCleanupRestClientClosingTask implements RestClientClosingTask {

@Override
public void close(Context context) {
JacksonUtil.contextResolverMap
.remove(new ResolverMapKey(context.baseTarget().getConfiguration(), context.restApiClass()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

final class JacksonUtil {

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

private JacksonUtil() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.quarkus.rest.client.reactive.jackson.runtime.serialisers.JacksonCleanupRestClientClosingTask
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import org.jboss.resteasy.reactive.client.impl.ClientBuilderImpl;
import org.jboss.resteasy.reactive.client.impl.ClientImpl;
import org.jboss.resteasy.reactive.client.impl.MultiInvoker;
import org.jboss.resteasy.reactive.client.impl.RestClientClosingTask;
import org.jboss.resteasy.reactive.client.impl.SseEventSourceBuilderImpl;
import org.jboss.resteasy.reactive.client.impl.StorkClientRequestFilter;
import org.jboss.resteasy.reactive.client.impl.UniInvoker;
Expand Down Expand Up @@ -1214,6 +1215,15 @@ A more full example of generated client (with sub-resource) can is at the bottom
.getMethodCreator(MethodDescriptor.ofMethod(Closeable.class, "close", void.class));
ResultHandle webTarget = closeCreator.readInstanceField(baseTargetField, closeCreator.getThis());
ResultHandle webTargetImpl = closeCreator.checkCast(webTarget, WebTargetImpl.class);
ResultHandle restApiClass = closeCreator.loadClassFromTCCL(restClientInterface.getClassName());
ResultHandle context = closeCreator.newInstance(
MethodDescriptor.ofConstructor(RestClientClosingTask.Context.class, Class.class, WebTargetImpl.class),
restApiClass,
webTargetImpl);
closeCreator.invokeStaticInterfaceMethod(
MethodDescriptor.ofMethod(RestClientClosingTask.class, "invokeAll", void.class,
RestClientClosingTask.Context.class),
context);
ResultHandle restClient = closeCreator.invokeVirtualMethod(
MethodDescriptor.ofMethod(WebTargetImpl.class, "getRestClient", ClientImpl.class), webTargetImpl);
closeCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(ClientImpl.class, "close", void.class), restClient);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.jboss.resteasy.reactive.client.impl;

import java.util.ServiceLoader;

import org.jboss.logging.Logger;

/**
* This represents a task that will be called by the implementation class of the REST Client when the {@code close}
* method is called.
*/
public interface RestClientClosingTask {

Logger log = Logger.getLogger(RestClientClosingTask.class);

void close(Context context);

record Context(Class<?> restApiClass, WebTargetImpl baseTarget) {
}

@SuppressWarnings("unused") // this is called by the implementation class of the REST Client when the {@code close} method is called
static void invokeAll(Context context) {
for (RestClientClosingTask restClientClosingTask : ServiceLoader.load(RestClientClosingTask.class)) {
try {
restClientClosingTask.close(context);
} catch (Exception e) {
log.warn("Error running RestClientClosingTask", e);
}
}
}
}

0 comments on commit 4865eae

Please sign in to comment.