Skip to content

Commit

Permalink
Introduce way to customize ServerHandler with runtime config
Browse files Browse the repository at this point in the history
Essentially extensions can now use the HandlerConfigurationProviderBuildItem
to register the configuration class they work for and how the value can
be obtained
  • Loading branch information
geoand committed Nov 18, 2022
1 parent 64297c0 commit 6eecb91
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -103,6 +104,7 @@
import org.jboss.resteasy.reactive.server.processor.scanning.ResponseHeaderMethodScanner;
import org.jboss.resteasy.reactive.server.processor.scanning.ResponseStatusMethodScanner;
import org.jboss.resteasy.reactive.server.processor.util.ResteasyReactiveServerDotNames;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfiguration;
import org.jboss.resteasy.reactive.server.vertx.serializers.ServerMutinyAsyncFileMessageBodyWriter;
import org.jboss.resteasy.reactive.server.vertx.serializers.ServerMutinyBufferMessageBodyWriter;
import org.jboss.resteasy.reactive.server.vertx.serializers.ServerVertxAsyncFileMessageBodyWriter;
Expand Down Expand Up @@ -171,6 +173,7 @@
import io.quarkus.resteasy.reactive.server.runtime.security.SecurityContextOverrideHandler;
import io.quarkus.resteasy.reactive.server.spi.AnnotationsTransformerBuildItem;
import io.quarkus.resteasy.reactive.server.spi.ContextTypeBuildItem;
import io.quarkus.resteasy.reactive.server.spi.HandlerConfigurationProviderBuildItem;
import io.quarkus.resteasy.reactive.server.spi.MethodScannerBuildItem;
import io.quarkus.resteasy.reactive.server.spi.NonBlockingReturnTypeBuildItem;
import io.quarkus.resteasy.reactive.server.spi.ResumeOn404BuildItem;
Expand Down Expand Up @@ -1303,13 +1306,32 @@ private <T> T getEffectivePropertyValue(String legacyPropertyName, T newProperty

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
public void applyRuntimeConfig(ResteasyReactiveRuntimeRecorder recorder,
public void runtimeConfiguration(ResteasyReactiveRuntimeRecorder recorder,
Optional<ResteasyReactiveDeploymentBuildItem> deployment,
ResteasyReactiveServerRuntimeConfig resteasyReactiveServerRuntimeConf) {
if (!deployment.isPresent()) {
ResteasyReactiveServerRuntimeConfig resteasyReactiveServerRuntimeConf,
BuildProducer<HandlerConfigurationProviderBuildItem> producer) {
if (deployment.isEmpty()) {
return;
}
recorder.configure(deployment.get().getDeployment(), resteasyReactiveServerRuntimeConf);
producer.produce(new HandlerConfigurationProviderBuildItem(RuntimeConfiguration.class,
recorder.runtimeConfiguration(deployment.get().getDeployment(), resteasyReactiveServerRuntimeConf)));
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
public void configureHandlers(ResteasyReactiveRuntimeRecorder recorder,
Optional<ResteasyReactiveDeploymentBuildItem> deployment,
List<HandlerConfigurationProviderBuildItem> items) {
if (deployment.isEmpty()) {
return;
}

Map<Class<?>, Supplier<?>> runtimeConfigMap = new HashMap<>();
for (HandlerConfigurationProviderBuildItem item : items) {
runtimeConfigMap.put(item.getConfigClass(), item.getValueSupplier());
}

recorder.configureHandlers(deployment.get().getDeployment(), runtimeConfigMap);
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package io.quarkus.resteasy.reactive.server.runtime;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;

import org.jboss.resteasy.reactive.server.core.Deployment;
import org.jboss.resteasy.reactive.server.spi.DefaultRuntimeConfiguration;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.GenericRuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfiguration;

import io.quarkus.runtime.RuntimeValue;
Expand All @@ -21,7 +23,7 @@ public ResteasyReactiveRuntimeRecorder(HttpConfiguration httpConf) {
this.httpConf = httpConf;
}

public void configure(RuntimeValue<Deployment> deployment,
public Supplier<RuntimeConfiguration> runtimeConfiguration(RuntimeValue<Deployment> deployment,
ResteasyReactiveServerRuntimeConfig runtimeConf) {
Optional<Long> maxBodySize;

Expand All @@ -30,16 +32,34 @@ public void configure(RuntimeValue<Deployment> deployment,
} else {
maxBodySize = Optional.empty();
}

RuntimeConfiguration runtimeConfiguration = new DefaultRuntimeConfiguration(httpConf.readTimeout,
httpConf.body.deleteUploadedFilesOnEnd, httpConf.body.uploadsDirectory,
runtimeConf.multipart.inputPart.defaultCharset, maxBodySize,
httpConf.limits.maxFormAttributeSize.asLongValue());

List<RuntimeConfigurableServerRestHandler> runtimeConfigurableServerRestHandlers = deployment.getValue()
.getRuntimeConfigurableServerRestHandlers();
deployment.getValue().setRuntimeConfiguration(runtimeConfiguration);

return new Supplier<>() {
@Override
public RuntimeConfiguration get() {
return runtimeConfiguration;
}
};
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public void configureHandlers(RuntimeValue<Deployment> deployment, Map<Class<?>, Supplier<?>> runtimeConfigMap) {
List<GenericRuntimeConfigurableServerRestHandler<?>> runtimeConfigurableServerRestHandlers = deployment.getValue()
.getRuntimeConfigurableServerRestHandlers();
for (int i = 0; i < runtimeConfigurableServerRestHandlers.size(); i++) {
runtimeConfigurableServerRestHandlers.get(i).configure(runtimeConfiguration);
GenericRuntimeConfigurableServerRestHandler handler = runtimeConfigurableServerRestHandlers.get(i);
Supplier<?> supplier = runtimeConfigMap.get(handler.getConfigurationClass());
if (supplier == null) {
throw new IllegalStateException(
"Handler '" + handler.getClass().getName() + "' has not been properly configured.");
}
handler.configure(supplier.get());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.quarkus.resteasy.reactive.server.spi;

import java.util.function.Supplier;

import io.quarkus.builder.item.MultiBuildItem;

/**
* Build time that allows extensions to register a way to provide a value
* for configuration that is provided at runtime and that is needed by
* implementations of {@link org.jboss.resteasy.reactive.server.spi.GenericRuntimeConfigurableServerRestHandler}.
*
* Extensions are meant to create these build items by passing the configuration class as the first constructor
* argument, and using a recorder to return a {@link Supplier} that will provide a value of that class as the
* second argument constructor.
*
* Ideally we would have used generic to make things more type safe, but generics cannot be used in build items.
*/
@SuppressWarnings("rawtypes")
public final class HandlerConfigurationProviderBuildItem extends MultiBuildItem {

/**
* The runtime configuration class
*/
private final Class configClass;

/**
* A supplier of the runtime value of the configuration class.
* This supplier is meant to be provided by a recorder
*/
private final Supplier valueSupplier;

public HandlerConfigurationProviderBuildItem(Class configClass, Supplier valueSupplier) {
this.configClass = configClass;
this.valueSupplier = valueSupplier;
}

public Class getConfigClass() {
return configClass;
}

public Supplier getValueSupplier() {
return valueSupplier;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
import org.jboss.resteasy.reactive.server.processor.scanning.ResteasyReactiveParamConverterScanner;
import org.jboss.resteasy.reactive.server.processor.util.GeneratedClass;
import org.jboss.resteasy.reactive.server.processor.util.ResteasyReactiveServerDotNames;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.GenericRuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfiguration;
import org.jboss.resteasy.reactive.spi.BeanFactory;
import org.jboss.resteasy.reactive.spi.ThreadSetupAction;
Expand Down Expand Up @@ -362,6 +362,7 @@ public void addBuiltinSerializers() {
}
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public RunnableApplication createApplication(RuntimeConfiguration runtimeConfiguration,
RequestContextFactory requestContextFactory, Executor executor) {
sa.getResourceInterceptors().initializeDefaultFactories(factoryCreator);
Expand Down Expand Up @@ -436,10 +437,12 @@ public Executor get() {
Deployment deployment = runtimeDeploymentManager.deploy();
deployment.setRuntimeConfiguration(runtimeConfiguration);
RestInitialHandler initialHandler = new RestInitialHandler(deployment);
List<RuntimeConfigurableServerRestHandler> runtimeConfigurableServerRestHandlers = deployment
List<GenericRuntimeConfigurableServerRestHandler<?>> runtimeConfigurableServerRestHandlers = deployment
.getRuntimeConfigurableServerRestHandlers();
for (RuntimeConfigurableServerRestHandler handler : runtimeConfigurableServerRestHandlers) {
handler.configure(runtimeConfiguration);
for (GenericRuntimeConfigurableServerRestHandler handler : runtimeConfigurableServerRestHandlers) {
if (handler.getConfigurationClass().equals(RuntimeConfiguration.class)) {
handler.configure(runtimeConfiguration);
}
}
return new RunnableApplication(closeTasks, initialHandler, deployment, path);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import org.jboss.resteasy.reactive.server.mapping.RequestMapper;
import org.jboss.resteasy.reactive.server.model.ContextResolvers;
import org.jboss.resteasy.reactive.server.model.ParamConverterProviders;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.GenericRuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfiguration;
import org.jboss.resteasy.reactive.server.spi.ServerRestHandler;
import org.jboss.resteasy.reactive.spi.BeanFactory.BeanInstance;
Expand All @@ -44,7 +44,7 @@ public class Deployment {
private final RequestContextFactory requestContextFactory;
private final List<ServerRestHandler> preMatchHandlers;
private final ArrayList<RequestMapper.RequestPath<RestInitialHandler.InitialMatch>> classMappers;
private final List<RuntimeConfigurableServerRestHandler> runtimeConfigurableServerRestHandlers;
private final List<GenericRuntimeConfigurableServerRestHandler<?>> runtimeConfigurableServerRestHandlers;
private final RuntimeExceptionMapper exceptionMapper;
private final boolean resumeOn404;
private final ResteasyReactiveConfig resteasyReactiveConfig;
Expand All @@ -59,7 +59,7 @@ public Deployment(ExceptionMapping exceptionMapping, ContextResolvers contextRes
ThreadSetupAction threadSetupAction, RequestContextFactory requestContextFactory,
List<ServerRestHandler> preMatchHandlers,
ArrayList<RequestMapper.RequestPath<RestInitialHandler.InitialMatch>> classMappers,
List<RuntimeConfigurableServerRestHandler> runtimeConfigurableServerRestHandlers,
List<GenericRuntimeConfigurableServerRestHandler<?>> runtimeConfigurableServerRestHandlers,
RuntimeExceptionMapper exceptionMapper,
boolean resumeOn404,
ResteasyReactiveConfig resteasyReactiveConfig) {
Expand Down Expand Up @@ -191,7 +191,7 @@ public RequestContextFactory getRequestContextFactory() {
return requestContextFactory;
}

public List<RuntimeConfigurableServerRestHandler> getRuntimeConfigurableServerRestHandlers() {
public List<GenericRuntimeConfigurableServerRestHandler<?>> getRuntimeConfigurableServerRestHandlers() {
return runtimeConfigurableServerRestHandlers;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
import org.jboss.resteasy.reactive.server.model.HandlerChainCustomizer;
import org.jboss.resteasy.reactive.server.model.ParamConverterProviders;
import org.jboss.resteasy.reactive.server.model.ServerResourceMethod;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.GenericRuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.ServerRestHandler;
import org.jboss.resteasy.reactive.spi.BeanFactory;
import org.jboss.resteasy.reactive.spi.ThreadSetupAction;
Expand Down Expand Up @@ -103,7 +103,7 @@ public BeanFactory.BeanInstance<?> apply(Class<?> aClass) {
return info.getFactoryCreator().apply(aClass).createInstance();
}
});
List<RuntimeConfigurableServerRestHandler> runtimeConfigurableServerRestHandlers = new ArrayList<>();
List<GenericRuntimeConfigurableServerRestHandler<?>> runtimeConfigurableServerRestHandlers = new ArrayList<>();
RuntimeResourceDeployment runtimeResourceDeployment = new RuntimeResourceDeployment(info, executorSupplier,
virtualExecutorSupplier,
interceptorDeployment, dynamicEntityWriter, resourceLocatorHandler, requestContextFactory.isDefaultBlocking());
Expand Down Expand Up @@ -215,10 +215,10 @@ private void forEachMapperEntry(URITemplate path,
}

private void addRuntimeConfigurableHandlers(RuntimeResource runtimeResource,
List<RuntimeConfigurableServerRestHandler> runtimeConfigurableServerRestHandlers) {
List<GenericRuntimeConfigurableServerRestHandler<?>> runtimeConfigurableServerRestHandlers) {
for (ServerRestHandler serverRestHandler : runtimeResource.getHandlerChain()) {
if (serverRestHandler instanceof RuntimeConfigurableServerRestHandler) {
runtimeConfigurableServerRestHandlers.add((RuntimeConfigurableServerRestHandler) serverRestHandler);
if (serverRestHandler instanceof GenericRuntimeConfigurableServerRestHandler) {
runtimeConfigurableServerRestHandlers.add((GenericRuntimeConfigurableServerRestHandler<?>) serverRestHandler);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@
import org.jboss.resteasy.reactive.server.core.multipart.FormEncodedDataDefinition;
import org.jboss.resteasy.reactive.server.core.multipart.FormParserFactory;
import org.jboss.resteasy.reactive.server.core.multipart.MultiPartParserDefinition;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.GenericRuntimeConfigurableServerRestHandler;
import org.jboss.resteasy.reactive.server.spi.RuntimeConfiguration;
import org.jboss.resteasy.reactive.server.spi.ServerHttpRequest;
import org.jboss.resteasy.reactive.server.spi.ServerRestHandler;

public class FormBodyHandler implements ServerRestHandler, RuntimeConfigurableServerRestHandler {
public class FormBodyHandler implements GenericRuntimeConfigurableServerRestHandler<RuntimeConfiguration> {

private final boolean alsoSetInputStream;
private final Supplier<Executor> executorSupplier;
Expand All @@ -34,6 +33,11 @@ public FormBodyHandler(boolean alsoSetInputStream, Supplier<Executor> executorSu
this.executorSupplier = executorSupplier;
}

@Override
public Class<RuntimeConfiguration> getConfigurationClass() {
return RuntimeConfiguration.class;
}

@Override
public void configure(RuntimeConfiguration configuration) {
formParserFactory = FormParserFactory.builder(false, executorSupplier)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.jboss.resteasy.reactive.server.spi;

public interface GenericRuntimeConfigurableServerRestHandler<T> extends ServerRestHandler {

Class<T> getConfigurationClass();

void configure(T configuration);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package org.jboss.resteasy.reactive.server.spi;

public interface RuntimeConfigurableServerRestHandler extends ServerRestHandler {
@Deprecated
public interface RuntimeConfigurableServerRestHandler
extends GenericRuntimeConfigurableServerRestHandler<RuntimeConfiguration> {

@Override
default Class<RuntimeConfiguration> getConfigurationClass() {
return RuntimeConfiguration.class;
}

void configure(RuntimeConfiguration configuration);
}

0 comments on commit 6eecb91

Please sign in to comment.