@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.function.context.FunctionCatalog;
|
||||
import org.springframework.cloud.function.context.FunctionProperties;
|
||||
import org.springframework.cloud.function.web.constants.WebRequestConstants;
|
||||
import org.springframework.cloud.function.web.util.FunctionWebRequestProcessingHelper;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -45,16 +46,19 @@ public class FunctionHandlerMapping extends RequestMappingHandlerMapping
|
||||
|
||||
private final FunctionController controller;
|
||||
|
||||
private final FunctionProperties functionProperties;
|
||||
|
||||
@Value("${spring.cloud.function.web.path:}")
|
||||
private String prefix = "";
|
||||
|
||||
@Autowired
|
||||
public FunctionHandlerMapping(FunctionCatalog catalog,
|
||||
FunctionController controller) {
|
||||
FunctionController controller, FunctionProperties functionProperties) {
|
||||
this.functions = catalog;
|
||||
this.logger.info("FunctionCatalog: " + catalog);
|
||||
setOrder(super.getOrder() - 5);
|
||||
this.controller = controller;
|
||||
this.functionProperties = functionProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,7 +84,7 @@ public class FunctionHandlerMapping extends RequestMappingHandlerMapping
|
||||
path = path.substring(this.prefix.length());
|
||||
}
|
||||
Object function = FunctionWebRequestProcessingHelper
|
||||
.findFunction(request.getRequest().getMethod(), this.functions, request.getAttributes(), path, new String[] {});
|
||||
.findFunction(this.functionProperties, request.getRequest().getMethod(), this.functions, request.getAttributes(), path, new String[] {});
|
||||
|
||||
if (function != null) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
|
||||
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.cloud.function.context.FunctionCatalog;
|
||||
import org.springframework.cloud.function.context.FunctionProperties;
|
||||
import org.springframework.cloud.function.web.BasicStringConverter;
|
||||
import org.springframework.cloud.function.web.StringConverter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -47,8 +48,8 @@ import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandl
|
||||
public class ReactorAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public FunctionHandlerMapping functionHandlerMapping(FunctionCatalog catalog, FunctionController controller) {
|
||||
return new FunctionHandlerMapping(catalog, controller);
|
||||
public FunctionHandlerMapping functionHandlerMapping(FunctionCatalog catalog, FunctionController controller, FunctionProperties functionProperties) {
|
||||
return new FunctionHandlerMapping(catalog, controller, functionProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -31,11 +31,12 @@ import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.web.ErrorProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ResourceProperties;
|
||||
import org.springframework.boot.autoconfigure.web.WebProperties.Resources;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
|
||||
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
|
||||
import org.springframework.boot.web.reactive.error.ErrorAttributes;
|
||||
import org.springframework.cloud.function.context.FunctionCatalog;
|
||||
import org.springframework.cloud.function.context.FunctionProperties;
|
||||
import org.springframework.cloud.function.context.FunctionalSpringApplication;
|
||||
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
|
||||
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
|
||||
@@ -106,7 +107,7 @@ class FunctionEndpointInitializer implements ApplicationContextInitializer<Gener
|
||||
() -> new RequestProcessor(context.getBeanProvider(JsonMapper.class),
|
||||
context.getBeanProvider(ServerCodecConfigurer.class)));
|
||||
context.registerBean(FunctionEndpointFactory.class,
|
||||
() -> new FunctionEndpointFactory(context.getBean(FunctionCatalog.class),
|
||||
() -> new FunctionEndpointFactory(context.getBean(FunctionProperties.class), context.getBean(FunctionCatalog.class),
|
||||
context.getBean(RequestProcessor.class), context.getEnvironment()));
|
||||
RouterFunctionRegister.register(context);
|
||||
}
|
||||
@@ -120,9 +121,10 @@ class FunctionEndpointInitializer implements ApplicationContextInitializer<Gener
|
||||
private DefaultErrorWebExceptionHandler errorHandler(GenericApplicationContext context) {
|
||||
context.registerBean(ErrorAttributes.class, () -> new DefaultErrorAttributes());
|
||||
context.registerBean(ErrorProperties.class, () -> new ErrorProperties());
|
||||
context.registerBean(ResourceProperties.class, () -> new ResourceProperties());
|
||||
|
||||
context.registerBean(Resources.class, () -> new Resources());
|
||||
DefaultErrorWebExceptionHandler handler = new DefaultErrorWebExceptionHandler(
|
||||
context.getBean(ErrorAttributes.class), context.getBean(ResourceProperties.class),
|
||||
context.getBean(ErrorAttributes.class), context.getBean(Resources.class),
|
||||
context.getBean(ErrorProperties.class), context);
|
||||
ServerCodecConfigurer codecs = ServerCodecConfigurer.create();
|
||||
handler.setMessageWriters(codecs.getWriters());
|
||||
@@ -203,7 +205,9 @@ class FunctionEndpointFactory {
|
||||
|
||||
private final RequestProcessor processor;
|
||||
|
||||
FunctionEndpointFactory(FunctionCatalog functionCatalog, RequestProcessor processor, Environment environment) {
|
||||
private final FunctionProperties functionProperties;
|
||||
|
||||
FunctionEndpointFactory(FunctionProperties functionProperties, FunctionCatalog functionCatalog, RequestProcessor processor, Environment environment) {
|
||||
String handler = environment.resolvePlaceholders("${function.handler}");
|
||||
if (handler.startsWith("$")) {
|
||||
handler = null;
|
||||
@@ -211,6 +215,7 @@ class FunctionEndpointFactory {
|
||||
this.processor = processor;
|
||||
this.functionCatalog = functionCatalog;
|
||||
this.handler = handler;
|
||||
this.functionProperties = functionProperties;
|
||||
}
|
||||
|
||||
private FunctionInvocationWrapper extract(ServerRequest request) {
|
||||
@@ -223,7 +228,7 @@ class FunctionEndpointFactory {
|
||||
}
|
||||
else {
|
||||
String[] accept = FunctionWebRequestProcessingHelper.acceptContentTypes(request.headers().accept());
|
||||
function = FunctionWebRequestProcessingHelper.findFunction(request.method(), functionCatalog, request.attributes(),
|
||||
function = FunctionWebRequestProcessingHelper.findFunction(this.functionProperties, request.method(), functionCatalog, request.attributes(),
|
||||
request.path(), accept);
|
||||
}
|
||||
return function;
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.function.context.FunctionCatalog;
|
||||
import org.springframework.cloud.function.context.FunctionProperties;
|
||||
import org.springframework.cloud.function.web.constants.WebRequestConstants;
|
||||
import org.springframework.cloud.function.web.util.FunctionWebRequestProcessingHelper;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -47,16 +48,19 @@ public class FunctionHandlerMapping extends RequestMappingHandlerMapping
|
||||
|
||||
private final FunctionController controller;
|
||||
|
||||
private final FunctionProperties functionProperties;
|
||||
|
||||
@Value("${spring.cloud.function.web.path:}")
|
||||
private String prefix = "";
|
||||
|
||||
@Autowired
|
||||
public FunctionHandlerMapping(FunctionCatalog catalog,
|
||||
public FunctionHandlerMapping(FunctionProperties functionProperties, FunctionCatalog catalog,
|
||||
FunctionController controller) {
|
||||
this.functions = catalog;
|
||||
this.logger.info("FunctionCatalog: " + catalog);
|
||||
setOrder(super.getOrder() - 5);
|
||||
this.controller = controller;
|
||||
this.functionProperties = functionProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,7 +95,7 @@ public class FunctionHandlerMapping extends RequestMappingHandlerMapping
|
||||
path = path.substring(this.prefix.length());
|
||||
}
|
||||
|
||||
Object function = FunctionWebRequestProcessingHelper.findFunction(HttpMethod.resolve(request.getMethod()),
|
||||
Object function = FunctionWebRequestProcessingHelper.findFunction(this.functionProperties, HttpMethod.resolve(request.getMethod()),
|
||||
this.functions, new HttpRequestAttributeDelegate(request), path, new String[] {});
|
||||
if (function != null) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.cloud.function.context.FunctionCatalog;
|
||||
import org.springframework.cloud.function.context.FunctionProperties;
|
||||
import org.springframework.cloud.function.web.BasicStringConverter;
|
||||
import org.springframework.cloud.function.web.StringConverter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -43,8 +44,8 @@ import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandl
|
||||
public class ReactorAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public FunctionHandlerMapping functionHandlerMapping(FunctionCatalog catalog, FunctionController controller) {
|
||||
return new FunctionHandlerMapping(catalog, controller);
|
||||
public FunctionHandlerMapping functionHandlerMapping(FunctionProperties functionProperties, FunctionCatalog catalog, FunctionController controller) {
|
||||
return new FunctionHandlerMapping(functionProperties, catalog, controller);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -28,6 +28,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.function.context.FunctionCatalog;
|
||||
import org.springframework.cloud.function.context.FunctionProperties;
|
||||
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
|
||||
import org.springframework.cloud.function.web.constants.WebRequestConstants;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -54,10 +55,10 @@ public final class FunctionWebRequestProcessingHelper {
|
||||
|
||||
}
|
||||
|
||||
public static FunctionInvocationWrapper findFunction(HttpMethod method, FunctionCatalog functionCatalog,
|
||||
public static FunctionInvocationWrapper findFunction(FunctionProperties functionProperties, HttpMethod method, FunctionCatalog functionCatalog,
|
||||
Map<String, Object> attributes, String path, String[] acceptContentTypes) {
|
||||
if (method.equals(HttpMethod.GET) || method.equals(HttpMethod.POST)) {
|
||||
return doFindFunction(method, functionCatalog, attributes, path, acceptContentTypes);
|
||||
return doFindFunction(functionProperties.getDefinition(), method, functionCatalog, attributes, path, acceptContentTypes);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("HTTP method '" + method + "' is not supported;");
|
||||
@@ -145,8 +146,9 @@ public final class FunctionWebRequestProcessingHelper {
|
||||
return message.getPayload();
|
||||
}
|
||||
|
||||
private static FunctionInvocationWrapper doFindFunction(HttpMethod method, FunctionCatalog functionCatalog,
|
||||
private static FunctionInvocationWrapper doFindFunction(String functionDefinition, HttpMethod method, FunctionCatalog functionCatalog,
|
||||
Map<String, Object> attributes, String path, String[] acceptContentTypes) {
|
||||
|
||||
path = path.startsWith("/") ? path.substring(1) : path;
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
FunctionInvocationWrapper function = functionCatalog.lookup(path, acceptContentTypes);
|
||||
@@ -169,16 +171,27 @@ public final class FunctionWebRequestProcessingHelper {
|
||||
: null;
|
||||
FunctionInvocationWrapper function = functionCatalog.lookup(name, acceptContentTypes);
|
||||
if (function != null) {
|
||||
attributes.put(WebRequestConstants.FUNCTION, function);
|
||||
if (value != null) {
|
||||
attributes.put(WebRequestConstants.ARGUMENT, value);
|
||||
}
|
||||
return function;
|
||||
return postProcessFunction(function, value, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(functionDefinition)) {
|
||||
FunctionInvocationWrapper function = functionCatalog.lookup(functionDefinition, acceptContentTypes);
|
||||
if (function != null) {
|
||||
return postProcessFunction(function, value, attributes);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static FunctionInvocationWrapper postProcessFunction(FunctionInvocationWrapper function, String argument, Map<String, Object> attributes) {
|
||||
attributes.put(WebRequestConstants.FUNCTION, function);
|
||||
if (argument != null) {
|
||||
attributes.put(WebRequestConstants.ARGUMENT, argument);
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private static Object postProcessResult(Object result, boolean isMessage) {
|
||||
if (result instanceof Flux) {
|
||||
|
||||
Reference in New Issue
Block a user