Skip to content

Commit

Permalink
Make copying of Vertx context data conditional
Browse files Browse the repository at this point in the history
In order to avoid negatively affecting RESTEasy Reactive performance
just to serve very specific use cases, we introduce a way to
conditionally control when the current Vertx request context data needs
to be copied into the connection context

Follow up off: #22671
  • Loading branch information
geoand committed Jan 10, 2022
1 parent 6a36ecf commit 8735ad1
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.vertx.core.deployment.CoreVertxBuildItem;
import io.quarkus.vertx.deployment.CopyVertxContextDataBuildItem;

public class OpenTelemetryProcessor {
static class OpenTelemetryEnabled implements BooleanSupplier {
Expand Down Expand Up @@ -137,6 +138,11 @@ void storeVertxOnContextStorage(OpenTelemetryRecorder recorder, CoreVertxBuildIt
recorder.storeVertxOnContextStorage(vertx.getVertx());
}

@BuildStep
CopyVertxContextDataBuildItem copyVertxContextData() {
return new CopyVertxContextDataBuildItem(QuarkusContextStorage.ACTIVE_CONTEXT);
}

public static boolean isClassPresent(String classname) {
try {
Class.forName(classname, false, Thread.currentThread().getContextClassLoader());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
import io.quarkus.security.AuthenticationCompletionException;
import io.quarkus.security.AuthenticationRedirectException;
import io.quarkus.security.ForbiddenException;
import io.quarkus.vertx.deployment.CopyVertxContextDataBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig;
import io.quarkus.vertx.http.runtime.VertxHttpRecorder;
Expand Down Expand Up @@ -643,7 +644,8 @@ public void setupDeployment(BeanArchiveIndexBuildItem beanArchiveIndexBuildItem,
ParamConverterProvidersBuildItem paramConverterProvidersBuildItem,
ContextResolversBuildItem contextResolversBuildItem,
ResteasyReactiveServerConfig serverConfig,
LaunchModeBuildItem launchModeBuildItem)
LaunchModeBuildItem launchModeBuildItem,
List<CopyVertxContextDataBuildItem> copyVertxContextDataBuildItems)
throws NoSuchMethodException {

if (!resourceScanningResultBuildItem.isPresent()) {
Expand Down Expand Up @@ -761,7 +763,8 @@ public void setupDeployment(BeanArchiveIndexBuildItem beanArchiveIndexBuildItem,
RuntimeValue<Deployment> deployment = recorder.createDeployment(deploymentInfo,
beanContainerBuildItem.getValue(), shutdownContext, vertxConfig,
requestContextFactoryBuildItem.map(RequestContextFactoryBuildItem::getFactory).orElse(null),
initClassFactory, launchModeBuildItem.getLaunchMode(), servletPresent);
initClassFactory, launchModeBuildItem.getLaunchMode(), servletPresent,
copyVertxContextDataBuildItems.stream().map(CopyVertxContextDataBuildItem::getProperty).collect(toList()));

quarkusRestDeploymentBuildItemBuildProducer
.produce(new ResteasyReactiveDeploymentBuildItem(deployment, deploymentPath));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.resteasy.reactive.server.runtime;

import java.util.List;

import javax.enterprise.event.Event;
import javax.ws.rs.core.SecurityContext;

Expand All @@ -23,8 +25,9 @@ public class QuarkusResteasyReactiveRequestContext extends VertxResteasyReactive
public QuarkusResteasyReactiveRequestContext(Deployment deployment, ProvidersImpl providers,
RoutingContext context, ThreadSetupAction requestContext, ServerRestHandler[] handlerChain,
ServerRestHandler[] abortHandlerChain, ClassLoader devModeTccl,
CurrentIdentityAssociation currentIdentityAssociation) {
super(deployment, providers, context, requestContext, handlerChain, abortHandlerChain, devModeTccl);
CurrentIdentityAssociation currentIdentityAssociation, List<String> vertxContextPropsToCopy) {
super(deployment, providers, context, requestContext, handlerChain, abortHandlerChain, devModeTccl,
vertxContextPropsToCopy);
this.association = currentIdentityAssociation;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.io.Closeable;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
Expand Down Expand Up @@ -73,7 +74,7 @@ public RuntimeValue<Deployment> createDeployment(DeploymentInfo info,
ShutdownContext shutdownContext, HttpBuildTimeConfig vertxConfig,
RequestContextFactory contextFactory,
BeanFactory<ResteasyReactiveInitialiser> initClassFactory,
LaunchMode launchMode, boolean servletPresent) {
LaunchMode launchMode, boolean servletPresent, List<String> vertxContextPropsToCopy) {

if (servletPresent) {
info.setResumeOn404(true);
Expand Down Expand Up @@ -107,7 +108,8 @@ public ResteasyReactiveRequestContext createContext(Deployment deployment,
return new QuarkusResteasyReactiveRequestContext(deployment, providers, (RoutingContext) context,
requestContext,
handlerChain,
abortHandlerChain, launchMode == LaunchMode.DEVELOPMENT ? tccl : null, currentIdentityAssociation);
abortHandlerChain, launchMode == LaunchMode.DEVELOPMENT ? tccl : null, currentIdentityAssociation,
vertxContextPropsToCopy);
}

};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkus.vertx.deployment;

import io.quarkus.builder.item.MultiBuildItem;

/**
* Build item which indicates that the current Vertx request context data needs
* to be copied into the connection context
*/
public final class CopyVertxContextDataBuildItem extends MultiBuildItem {

private final String property;

public CopyVertxContextDataBuildItem(String property) {
this.property = property;
}

public String getProperty() {
return property;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jboss.resteasy.reactive.server.vertx;

import io.vertx.ext.web.RoutingContext;
import java.util.Collections;
import org.jboss.resteasy.reactive.server.core.Deployment;
import org.jboss.resteasy.reactive.server.core.RequestContextFactory;
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext;
Expand All @@ -14,6 +15,6 @@ public ResteasyReactiveRequestContext createContext(Deployment deployment,
ProvidersImpl providers, Object context, ThreadSetupAction requestContext,
ServerRestHandler[] handlerChain, ServerRestHandler[] abortHandlerChain) {
return new VertxResteasyReactiveRequestContext(deployment, providers, (RoutingContext) context,
requestContext, handlerChain, abortHandlerChain, null);
requestContext, handlerChain, abortHandlerChain, null, Collections.emptyList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class VertxResteasyReactiveRequestContext extends ResteasyReactiveRequest
public VertxResteasyReactiveRequestContext(Deployment deployment, ProvidersImpl providers,
RoutingContext context,
ThreadSetupAction requestContext, ServerRestHandler[] handlerChain, ServerRestHandler[] abortHandlerChain,
ClassLoader devModeTccl) {
ClassLoader devModeTccl, List<String> vertxContextPropsToCopy) {
super(deployment, providers, requestContext, handlerChain, abortHandlerChain);
this.context = context;
this.request = context.request();
Expand All @@ -61,8 +61,18 @@ public VertxResteasyReactiveRequestContext(Deployment deployment, ProvidersImpl
context.addHeadersEndHandler(this);
String expect = request.getHeader(HttpHeaderNames.EXPECT);
ContextInternal internal = ((ConnectionBase) context.request().connection()).getContext();
ContextInternal current = (ContextInternal) Vertx.currentContext();
internal.localContextData().putAll(current.localContextData());
if (!vertxContextPropsToCopy.isEmpty()) {
ContextInternal current = (ContextInternal) Vertx.currentContext();
Map<Object, Object> internalLocalContextData = internal.localContextData();
Map<Object, Object> currentLocalContextData = current.localContextData();
for (int i = 0; i < vertxContextPropsToCopy.size(); i++) {
String name = vertxContextPropsToCopy.get(i);
Object value = currentLocalContextData.get(name);
if (value != null) {
internalLocalContextData.put(name, value);
}
}
}
if (expect != null && expect.equalsIgnoreCase(CONTINUE)) {
continueState = ContinueState.REQUIRED;
}
Expand Down

0 comments on commit 8735ad1

Please sign in to comment.