Turned on checkstyle
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,9 +22,7 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
*
|
||||
* @since 2.0.1
|
||||
*
|
||||
*/
|
||||
@@ -33,12 +31,14 @@ public abstract class AbstractFunctionRegistry implements FunctionRegistry {
|
||||
@Autowired
|
||||
private Environment environment = new StandardEnvironment();
|
||||
|
||||
|
||||
public <T> T lookup(Class<?> type, String name) {
|
||||
String functionDefinitionName = !StringUtils.hasText(name) && environment.containsProperty("spring.cloud.function.definition")
|
||||
? environment.getProperty("spring.cloud.function.definition") : name;
|
||||
String functionDefinitionName = !StringUtils.hasText(name)
|
||||
&& this.environment.containsProperty("spring.cloud.function.definition")
|
||||
? this.environment.getProperty("spring.cloud.function.definition")
|
||||
: name;
|
||||
return this.doLookup(type, functionDefinitionName);
|
||||
}
|
||||
|
||||
protected abstract <T> T doLookup(Class<?> type, String name);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -25,20 +25,20 @@ import java.util.Set;
|
||||
public interface FunctionCatalog {
|
||||
|
||||
/**
|
||||
* Will look up the instance of the functional interface by name only
|
||||
*
|
||||
* Will look up the instance of the functional interface by name only.
|
||||
* @param <T> instance type
|
||||
* @param name the name of the functional interface. Must not be null;
|
||||
* @return instance of the functional interface registered with this catalog
|
||||
*/
|
||||
default public <T> T lookup(String name) {
|
||||
default <T> T lookup(String name) {
|
||||
return this.lookup(null, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will look up the instance of the functional interface by name and type
|
||||
* which can only be Supplier, Consumer or Function. If type is not provided, the lookup
|
||||
* will be made based on name only
|
||||
*
|
||||
* Will look up the instance of the functional interface by name and type which can
|
||||
* only be Supplier, Consumer or Function. If type is not provided, the lookup will be
|
||||
* made based on name only.
|
||||
* @param <T> instance type
|
||||
* @param type the type of functional interface. Can be null
|
||||
* @param name the name of the functional interface. Must not be null;
|
||||
* @return instance of the functional interface registered with this catalog
|
||||
@@ -48,11 +48,12 @@ public interface FunctionCatalog {
|
||||
Set<String> getNames(Class<?> type);
|
||||
|
||||
/**
|
||||
* Return the count of functions registered in this catalog
|
||||
* Return the count of functions registered in this catalog.
|
||||
* @return the count of functions registered in this catalog
|
||||
*/
|
||||
default int size() {
|
||||
throw new UnsupportedOperationException("This instance of FunctionCatalog does not support this operation");
|
||||
throw new UnsupportedOperationException(
|
||||
"This instance of FunctionCatalog does not support this operation");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,9 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.cloud.function.core.FluxConsumer;
|
||||
import org.springframework.cloud.function.core.FluxFunction;
|
||||
@@ -34,26 +37,23 @@ import org.springframework.cloud.function.core.FluxSupplier;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* @param <T> target type
|
||||
* @author Dave Syer
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class FunctionRegistration<T> implements BeanNameAware {
|
||||
|
||||
private T target;
|
||||
|
||||
private final Set<String> names = new LinkedHashSet<>();
|
||||
|
||||
private final Map<String, String> properties = new LinkedHashMap<>();
|
||||
|
||||
private T target;
|
||||
|
||||
private FunctionType type;
|
||||
|
||||
/**
|
||||
* Creates instance of FunctionRegistration.
|
||||
*
|
||||
* @param target instance of {@link Supplier}, {@link Function} or {@link Consumer}
|
||||
* @param names additional set of names for this registration. Additional names can be
|
||||
* provided {@link #name(String)} or {@link #names(String...)} operations.
|
||||
@@ -65,15 +65,11 @@ public class FunctionRegistration<T> implements BeanNameAware {
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return properties;
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public Set<String> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
public FunctionType getType() {
|
||||
return type;
|
||||
return this.names;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,15 +77,19 @@ public class FunctionRegistration<T> implements BeanNameAware {
|
||||
* want to add a name or set or names to the existing set of names use
|
||||
* {@link #names(Collection)} or {@link #name(String)} or {@link #names(String...)}
|
||||
* operations.
|
||||
* @param names
|
||||
* @param names - bean names
|
||||
*/
|
||||
public void setNames(Set<String> names) {
|
||||
this.names.clear();
|
||||
this.names.addAll(names);
|
||||
}
|
||||
|
||||
public FunctionType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public T getTarget() {
|
||||
return target;
|
||||
return this.target;
|
||||
}
|
||||
|
||||
public FunctionRegistration<T> properties(Map<String, String> properties) {
|
||||
@@ -133,7 +133,7 @@ public class FunctionRegistration<T> implements BeanNameAware {
|
||||
}
|
||||
|
||||
public <S> FunctionRegistration<S> wrap() {
|
||||
if (type == null || type.isWrapper()) {
|
||||
if (this.type == null || this.type.isWrapper()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
FunctionRegistration<S> value = (FunctionRegistration<S>) this;
|
||||
return value;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.context;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
@@ -23,18 +24,21 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class FunctionType {
|
||||
|
||||
/**
|
||||
* Unclassified function types.
|
||||
*/
|
||||
public static FunctionType UNCLASSIFIED = new FunctionType(ResolvableType
|
||||
.forClassWithGenerics(Function.class, Object.class, Object.class).getType());
|
||||
|
||||
@@ -61,34 +65,6 @@ public class FunctionType {
|
||||
this.message = messageType();
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Class<?> getInputWrapper() {
|
||||
return inputWrapper;
|
||||
}
|
||||
|
||||
public Class<?> getOutputWrapper() {
|
||||
return outputWrapper;
|
||||
}
|
||||
|
||||
public Class<?> getInputType() {
|
||||
return inputType;
|
||||
}
|
||||
|
||||
public Class<?> getOutputType() {
|
||||
return outputType;
|
||||
}
|
||||
|
||||
public boolean isMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public boolean isWrapper() {
|
||||
return isWrapper(getInputWrapper()) || isWrapper(getOutputWrapper());
|
||||
}
|
||||
|
||||
public static boolean isWrapper(Type type) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
type = ((ParameterizedType) type).getRawType();
|
||||
@@ -125,6 +101,91 @@ public class FunctionType {
|
||||
ResolvableType.forClassWithGenerics(Consumer.class, input).getType());
|
||||
}
|
||||
|
||||
public static FunctionType compose(FunctionType input, FunctionType output) {
|
||||
ResolvableType inputGeneric = input(input);
|
||||
ResolvableType outputGeneric = output(output);
|
||||
if (!isWrapper(outputGeneric.getType())) {
|
||||
ResolvableType inputOutput = output(input);
|
||||
if (isWrapper(inputOutput.getType())) {
|
||||
outputGeneric = wrap(input,
|
||||
extractClass(inputOutput.getType(), ParamType.OUTPUT_WRAPPER),
|
||||
extractClass(outputGeneric.getType(), ParamType.OUTPUT));
|
||||
}
|
||||
}
|
||||
return new FunctionType(ResolvableType
|
||||
.forClassWithGenerics(Function.class, inputGeneric, outputGeneric)
|
||||
.getType());
|
||||
}
|
||||
|
||||
private static ResolvableType wrap(FunctionType input, Class<?> wrapper,
|
||||
Class<?> type) {
|
||||
return input.isMessage() ? wrap(wrapper, message(type))
|
||||
: ResolvableType.forClassWithGenerics(wrapper, type);
|
||||
}
|
||||
|
||||
private static ResolvableType wrap(Class<?> wrapper, ResolvableType type) {
|
||||
return ResolvableType.forClassWithGenerics(wrapper, type);
|
||||
}
|
||||
|
||||
private static ResolvableType message(Class<?> type) {
|
||||
return ResolvableType.forClassWithGenerics(Message.class, type);
|
||||
}
|
||||
|
||||
private static ResolvableType input(FunctionType type) {
|
||||
return type.input(type.getInputType());
|
||||
}
|
||||
|
||||
private static ResolvableType output(FunctionType type) {
|
||||
return type.output(type.getOutputType());
|
||||
}
|
||||
|
||||
private static Class<?> extractClass(Type param, ParamType paramType) {
|
||||
if (param instanceof ParameterizedType) {
|
||||
ParameterizedType concrete = (ParameterizedType) param;
|
||||
param = concrete.getRawType();
|
||||
}
|
||||
if (param == null) {
|
||||
// Last ditch attempt to guess: Flux<String>
|
||||
if (paramType.isWrapper()) {
|
||||
param = Flux.class;
|
||||
}
|
||||
else {
|
||||
param = String.class;
|
||||
}
|
||||
}
|
||||
Class<?> result = param instanceof Class ? (Class<?>) param : null;
|
||||
// TODO: cache result
|
||||
return result;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Class<?> getInputWrapper() {
|
||||
return this.inputWrapper;
|
||||
}
|
||||
|
||||
public Class<?> getOutputWrapper() {
|
||||
return this.outputWrapper;
|
||||
}
|
||||
|
||||
public Class<?> getInputType() {
|
||||
return this.inputType;
|
||||
}
|
||||
|
||||
public Class<?> getOutputType() {
|
||||
return this.outputType;
|
||||
}
|
||||
|
||||
public boolean isMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public boolean isWrapper() {
|
||||
return isWrapper(getInputWrapper()) || isWrapper(getOutputWrapper());
|
||||
}
|
||||
|
||||
public FunctionType to(Class<?> output) {
|
||||
ResolvableType inputGeneric = input(this);
|
||||
ResolvableType outputGeneric = output(output);
|
||||
@@ -173,73 +234,69 @@ public class FunctionType {
|
||||
return wrap(wrapper, wrapper);
|
||||
}
|
||||
|
||||
public static FunctionType compose(FunctionType input, FunctionType output) {
|
||||
ResolvableType inputGeneric = input(input);
|
||||
ResolvableType outputGeneric = output(output);
|
||||
if (!isWrapper(outputGeneric.getType())) {
|
||||
ResolvableType inputOutput = output(input);
|
||||
if (isWrapper(inputOutput.getType())) {
|
||||
outputGeneric = wrap(input,
|
||||
extractClass(inputOutput.getType(), ParamType.OUTPUT_WRAPPER),
|
||||
extractClass(outputGeneric.getType(), ParamType.OUTPUT));
|
||||
}
|
||||
}
|
||||
return new FunctionType(ResolvableType
|
||||
.forClassWithGenerics(Function.class, inputGeneric, outputGeneric)
|
||||
.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ((inputType == null) ? 0 : inputType.toString().hashCode());
|
||||
+ ((this.inputType == null) ? 0 : this.inputType.toString().hashCode());
|
||||
result = prime * result + ((this.inputWrapper == null) ? 0
|
||||
: this.inputWrapper.toString().hashCode());
|
||||
result = prime * result + (this.message ? 1231 : 1237);
|
||||
result = prime * result
|
||||
+ ((inputWrapper == null) ? 0 : inputWrapper.toString().hashCode());
|
||||
result = prime * result + (message ? 1231 : 1237);
|
||||
result = prime * result
|
||||
+ ((outputType == null) ? 0 : outputType.toString().hashCode());
|
||||
result = prime * result
|
||||
+ ((outputWrapper == null) ? 0 : outputWrapper.toString().hashCode());
|
||||
+ ((this.outputType == null) ? 0 : this.outputType.toString().hashCode());
|
||||
result = prime * result + ((this.outputWrapper == null) ? 0
|
||||
: this.outputWrapper.toString().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (obj == null)
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
FunctionType other = (FunctionType) obj;
|
||||
if (inputType == null) {
|
||||
if (other.inputType != null)
|
||||
if (this.inputType == null) {
|
||||
if (other.inputType != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!inputType.toString().equals(other.inputType.toString()))
|
||||
else if (!this.inputType.toString().equals(other.inputType.toString())) {
|
||||
return false;
|
||||
if (inputWrapper == null) {
|
||||
if (other.inputWrapper != null)
|
||||
}
|
||||
if (this.inputWrapper == null) {
|
||||
if (other.inputWrapper != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!inputWrapper.toString().equals(other.inputWrapper.toString()))
|
||||
else if (!this.inputWrapper.toString().equals(other.inputWrapper.toString())) {
|
||||
return false;
|
||||
if (message != other.message)
|
||||
}
|
||||
if (this.message != other.message) {
|
||||
return false;
|
||||
if (outputType == null) {
|
||||
if (other.outputType != null)
|
||||
}
|
||||
if (this.outputType == null) {
|
||||
if (other.outputType != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!outputType.toString().equals(other.outputType.toString()))
|
||||
else if (!this.outputType.toString().equals(other.outputType.toString())) {
|
||||
return false;
|
||||
if (outputWrapper == null) {
|
||||
if (other.outputWrapper != null)
|
||||
}
|
||||
if (this.outputWrapper == null) {
|
||||
if (other.outputWrapper != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!outputWrapper.toString().equals(other.outputWrapper.toString()))
|
||||
else if (!this.outputWrapper.toString().equals(other.outputWrapper.toString())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -247,28 +304,6 @@ public class FunctionType {
|
||||
return wrap(this, wrapper, type);
|
||||
}
|
||||
|
||||
private static ResolvableType wrap(FunctionType input, Class<?> wrapper,
|
||||
Class<?> type) {
|
||||
return input.isMessage() ? wrap(wrapper, message(type))
|
||||
: ResolvableType.forClassWithGenerics(wrapper, type);
|
||||
}
|
||||
|
||||
private static ResolvableType wrap(Class<?> wrapper, ResolvableType type) {
|
||||
return ResolvableType.forClassWithGenerics(wrapper, type);
|
||||
}
|
||||
|
||||
private static ResolvableType message(Class<?> type) {
|
||||
return ResolvableType.forClassWithGenerics(Message.class, type);
|
||||
}
|
||||
|
||||
private static ResolvableType input(FunctionType type) {
|
||||
return type.input(type.getInputType());
|
||||
}
|
||||
|
||||
private static ResolvableType output(FunctionType type) {
|
||||
return type.output(type.getOutputType());
|
||||
}
|
||||
|
||||
private ResolvableType output(Class<?> type) {
|
||||
ResolvableType generic;
|
||||
ResolvableType raw = ResolvableType.forClass(type);
|
||||
@@ -331,25 +366,6 @@ public class FunctionType {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
private static Class<?> extractClass(Type param, ParamType paramType) {
|
||||
if (param instanceof ParameterizedType) {
|
||||
ParameterizedType concrete = (ParameterizedType) param;
|
||||
param = concrete.getRawType();
|
||||
}
|
||||
if (param == null) {
|
||||
// Last ditch attempt to guess: Flux<String>
|
||||
if (paramType.isWrapper()) {
|
||||
param = Flux.class;
|
||||
}
|
||||
else {
|
||||
param = String.class;
|
||||
}
|
||||
}
|
||||
Class<?> result = param instanceof Class ? (Class<?>) param : null;
|
||||
// TODO: cache result
|
||||
return result;
|
||||
}
|
||||
|
||||
private Type extractType(Type type, ParamType paramType, int index) {
|
||||
Type param;
|
||||
if (type instanceof ParameterizedType) {
|
||||
@@ -442,6 +458,7 @@ public class FunctionType {
|
||||
}
|
||||
|
||||
enum ParamType {
|
||||
|
||||
INPUT, OUTPUT, INPUT_WRAPPER, OUTPUT_WRAPPER, INPUT_INNER_WRAPPER, OUTPUT_INNER_WRAPPER;
|
||||
|
||||
public boolean isOutput() {
|
||||
@@ -460,6 +477,7 @@ public class FunctionType {
|
||||
public boolean isInnerWrapper() {
|
||||
return this == OUTPUT_INNER_WRAPPER || this == INPUT_INNER_WRAPPER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.context;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -39,11 +40,6 @@ import org.springframework.util.ClassUtils;
|
||||
public class FunctionalSpringApplication
|
||||
extends org.springframework.boot.SpringApplication {
|
||||
|
||||
/**
|
||||
* Name of default property source.
|
||||
*/
|
||||
private static final String DEFAULT_PROPERTIES = "defaultProperties";
|
||||
|
||||
/**
|
||||
* Flag to say that context is functional beans.
|
||||
*/
|
||||
@@ -54,6 +50,23 @@ public class FunctionalSpringApplication
|
||||
*/
|
||||
public static final String SPRING_WEB_APPLICATION_TYPE = "spring.main.web-application-type";
|
||||
|
||||
/**
|
||||
* Name of default property source.
|
||||
*/
|
||||
private static final String DEFAULT_PROPERTIES = "defaultProperties";
|
||||
|
||||
public FunctionalSpringApplication(Class<?>... primarySources) {
|
||||
super(primarySources);
|
||||
setApplicationContextClass(GenericApplicationContext.class);
|
||||
if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler",
|
||||
null)) {
|
||||
setWebApplicationType(WebApplicationType.REACTIVE);
|
||||
}
|
||||
else {
|
||||
setWebApplicationType(WebApplicationType.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
FunctionalSpringApplication.run(new Class<?>[0], args);
|
||||
}
|
||||
@@ -68,18 +81,6 @@ public class FunctionalSpringApplication
|
||||
return new FunctionalSpringApplication(primarySources).run(args);
|
||||
}
|
||||
|
||||
public FunctionalSpringApplication(Class<?>... primarySources) {
|
||||
super(primarySources);
|
||||
setApplicationContextClass(GenericApplicationContext.class);
|
||||
if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler",
|
||||
null)) {
|
||||
setWebApplicationType(WebApplicationType.REACTIVE);
|
||||
}
|
||||
else {
|
||||
setWebApplicationType(WebApplicationType.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
|
||||
super.postProcessApplicationContext(context);
|
||||
@@ -108,7 +109,7 @@ public class FunctionalSpringApplication
|
||||
handler = BeanUtils.instantiateClass(type);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
ApplicationContextInitializer<GenericApplicationContext> initializer = (ApplicationContextInitializer<GenericApplicationContext>) handler;
|
||||
ApplicationContextInitializer initializer = (ApplicationContextInitializer) handler;
|
||||
initializer.initialize(generic);
|
||||
functional = true;
|
||||
}
|
||||
@@ -118,8 +119,9 @@ public class FunctionalSpringApplication
|
||||
Class<?> functionType = type;
|
||||
Object function = handler;
|
||||
generic.registerBean("function", FunctionRegistration.class,
|
||||
() -> new FunctionRegistration<>(handler(generic, function, functionType))
|
||||
.type(FunctionType.of(functionType)));
|
||||
() -> new FunctionRegistration<>(
|
||||
handler(generic, function, functionType))
|
||||
.type(FunctionType.of(functionType)));
|
||||
functional = true;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +132,8 @@ public class FunctionalSpringApplication
|
||||
}
|
||||
}
|
||||
|
||||
private Object handler(GenericApplicationContext generic, Object handler, Class<?> type) {
|
||||
private Object handler(GenericApplicationContext generic, Object handler,
|
||||
Class<?> type) {
|
||||
if (handler == null) {
|
||||
handler = generic.getAutowireCapableBeanFactory().createBean(type);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.context.catalog;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.context.catalog;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -26,6 +27,7 @@ import java.util.Set;
|
||||
public class FunctionRegistrationEvent extends FunctionCatalogEvent {
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final Set<String> names;
|
||||
|
||||
public FunctionRegistrationEvent(Object source, Class<?> type, Set<String> names) {
|
||||
@@ -35,11 +37,11 @@ public class FunctionRegistrationEvent extends FunctionCatalogEvent {
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Set<String> getNames() {
|
||||
return names;
|
||||
return this.names;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.context.catalog;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -26,6 +27,7 @@ import java.util.Set;
|
||||
public class FunctionUnregistrationEvent extends FunctionCatalogEvent {
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final Set<String> names;
|
||||
|
||||
public FunctionUnregistrationEvent(Object source, Class<?> type, Set<String> names) {
|
||||
@@ -35,11 +37,11 @@ public class FunctionUnregistrationEvent extends FunctionCatalogEvent {
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Set<String> getNames() {
|
||||
return names;
|
||||
return this.names;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016-2019 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -81,16 +81,17 @@ public class InMemoryFunctionCatalog extends AbstractFunctionRegistry
|
||||
FunctionRegistrationEvent event = new FunctionRegistrationEvent(this, type,
|
||||
registration.getNames());
|
||||
|
||||
registrations.put(registration.getTarget(), registration);
|
||||
this.registrations.put(registration.getTarget(), registration);
|
||||
FunctionRegistration<T> wrapped = registration.wrap();
|
||||
if (wrapped != registration) {
|
||||
registration = wrapped;
|
||||
registrations.put(wrapped.getTarget(), wrapped);
|
||||
this.registrations.put(wrapped.getTarget(), wrapped);
|
||||
if (type == Consumer.class) {
|
||||
type = Function.class;
|
||||
}
|
||||
}
|
||||
Map<String, Object> map = functions.computeIfAbsent(type, key -> new HashMap<>());
|
||||
Map<String, Object> map = this.functions.computeIfAbsent(type,
|
||||
key -> new HashMap<>());
|
||||
for (String name : registration.getNames()) {
|
||||
map.put(name, registration.getTarget());
|
||||
}
|
||||
@@ -104,19 +105,19 @@ public class InMemoryFunctionCatalog extends AbstractFunctionRegistry
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (publisher != null && !functions.isEmpty()) {
|
||||
functions.keySet()
|
||||
if (this.publisher != null && !this.functions.isEmpty()) {
|
||||
this.functions.keySet()
|
||||
.forEach(type -> this.publishEvent(new FunctionRegistrationEvent(this,
|
||||
type, functions.get(type).keySet())));
|
||||
type, this.functions.get(type).keySet())));
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
if (publisher != null && !functions.isEmpty()) {
|
||||
functions.keySet().forEach(
|
||||
if (this.publisher != null && !this.functions.isEmpty()) {
|
||||
this.functions.keySet().forEach(
|
||||
type -> this.publishEvent(new FunctionUnregistrationEvent(this, type,
|
||||
functions.get(type).keySet())));
|
||||
this.functions.get(type).keySet())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +126,7 @@ public class InMemoryFunctionCatalog extends AbstractFunctionRegistry
|
||||
public <T> T doLookup(Class<?> type, String name) {
|
||||
T function = null;
|
||||
if (type == null) {
|
||||
function = (T) functions.values().stream()
|
||||
function = (T) this.functions.values().stream()
|
||||
.filter(map -> map.get(name) != null).map(map -> map.get(name))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
@@ -138,7 +139,7 @@ public class InMemoryFunctionCatalog extends AbstractFunctionRegistry
|
||||
@Override
|
||||
public Set<String> getNames(Class<?> type) {
|
||||
if (type == null) {
|
||||
return functions.values().stream().flatMap(map -> map.keySet().stream())
|
||||
return this.functions.values().stream().flatMap(map -> map.keySet().stream())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
Map<String, Object> map = this.extractTypeMap(type);
|
||||
@@ -146,10 +147,10 @@ public class InMemoryFunctionCatalog extends AbstractFunctionRegistry
|
||||
}
|
||||
|
||||
private Map<String, Object> extractTypeMap(Class<?> type) {
|
||||
return functions.keySet().stream()
|
||||
return this.functions.keySet().stream()
|
||||
.filter(key -> key != Object.class && key.isAssignableFrom(type))
|
||||
.map(key -> functions.get(key)).findFirst()
|
||||
.orElse(functions.get(Object.class));
|
||||
.map(key -> this.functions.get(key)).findFirst()
|
||||
.orElse(this.functions.get(Object.class));
|
||||
}
|
||||
|
||||
private void publishEvent(Object event) {
|
||||
@@ -157,4 +158,5 @@ public class InMemoryFunctionCatalog extends AbstractFunctionRegistry
|
||||
this.publisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016-2019 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -32,6 +32,11 @@ import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -62,22 +67,16 @@ import org.springframework.cloud.function.json.JacksonMapper;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.type.StandardMethodMetadata;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Mark Fisher
|
||||
@@ -86,8 +85,10 @@ import reactor.core.publisher.Mono;
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(FunctionCatalog.class)
|
||||
@ComponentScan(basePackages = "${spring.cloud.function.scan.packages:functions}",
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {Supplier.class, Function.class, Consumer.class}))
|
||||
// @checkstyle:off
|
||||
@ComponentScan(basePackages = "${spring.cloud.function.scan.packages:functions}", includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
|
||||
Supplier.class, Function.class, Consumer.class }))
|
||||
// @checkstyle:on
|
||||
public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
static final String PREFERRED_MAPPER_PROPERTY = "spring.http.converters.preferred-json-mapper";
|
||||
@@ -104,11 +105,10 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
@Autowired(required = false)
|
||||
private Map<String, FunctionRegistration<?>> registrations = Collections.emptyMap();
|
||||
|
||||
|
||||
|
||||
@Bean
|
||||
public FunctionRegistry functionCatalog(ContextFunctionRegistry processor) {
|
||||
processor.merge(registrations, consumers, suppliers, functions);
|
||||
processor.merge(this.registrations, this.consumers, this.suppliers,
|
||||
this.functions);
|
||||
return new BeanFactoryFunctionCatalog(processor);
|
||||
}
|
||||
|
||||
@@ -121,11 +121,15 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
private final ContextFunctionRegistry processor;
|
||||
|
||||
public BeanFactoryFunctionCatalog(ContextFunctionRegistry processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void register(FunctionRegistration<T> registration) {
|
||||
Assert.notEmpty(registration.getNames(),
|
||||
"'registration' must contain at least one name before it is registered in catalog.");
|
||||
processor.register(registration);
|
||||
this.processor.register(registration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,22 +137,22 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
protected <T> T doLookup(Class<?> type, String name) {
|
||||
T function = null;
|
||||
if (type == null) {
|
||||
function = (T) processor.lookupFunction(name);
|
||||
function = (T) this.processor.lookupFunction(name);
|
||||
if (function == null) {
|
||||
function = (T) processor.lookupConsumer(name);
|
||||
function = (T) this.processor.lookupConsumer(name);
|
||||
}
|
||||
if (function == null) {
|
||||
function = (T) processor.lookupSupplier(name);
|
||||
function = (T) this.processor.lookupSupplier(name);
|
||||
}
|
||||
}
|
||||
else if (Supplier.class.isAssignableFrom(type)) {
|
||||
function = (T) processor.lookupSupplier(name);
|
||||
function = (T) this.processor.lookupSupplier(name);
|
||||
}
|
||||
else if (Consumer.class.isAssignableFrom(type)) {
|
||||
function = (T) processor.lookupConsumer(name);
|
||||
function = (T) this.processor.lookupConsumer(name);
|
||||
}
|
||||
else if (Function.class.isAssignableFrom(type)) {
|
||||
function = (T) processor.lookupFunction(name);
|
||||
function = (T) this.processor.lookupFunction(name);
|
||||
}
|
||||
return function;
|
||||
}
|
||||
@@ -174,26 +178,6 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
+ this.processor.getConsumers().size();
|
||||
}
|
||||
|
||||
public BeanFactoryFunctionCatalog(ContextFunctionRegistry processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected class BeanFactoryFunctionInspector implements FunctionInspector {
|
||||
|
||||
private ContextFunctionRegistry processor;
|
||||
|
||||
public BeanFactoryFunctionInspector(ContextFunctionRegistry processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionRegistration<?> getRegistration(Object function) {
|
||||
FunctionRegistration<?> registration = processor.getRegistration(function);
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -201,21 +185,27 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
@ConditionalOnBean(Gson.class)
|
||||
@Conditional(PreferGsonOrMissingJacksonCondition.class)
|
||||
protected static class GsonConfiguration {
|
||||
|
||||
@Bean
|
||||
public GsonMapper jsonMapper(Gson gson) {
|
||||
return new GsonMapper(gson);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(ObjectMapper.class)
|
||||
@ConditionalOnBean(ObjectMapper.class)
|
||||
// @checkstyle:off
|
||||
@ConditionalOnProperty(name = ContextFunctionCatalogAutoConfiguration.PREFERRED_MAPPER_PROPERTY, havingValue = "jackson", matchIfMissing = true)
|
||||
// @checkstyle:on
|
||||
protected static class JacksonConfiguration {
|
||||
|
||||
@Bean
|
||||
public JacksonMapper jsonMapper(ObjectMapper mapper) {
|
||||
return new JacksonMapper(mapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
@@ -242,10 +232,10 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
|
||||
public FunctionRegistration<?> getRegistration(Object function) {
|
||||
if (function == null || !names.containsKey(function)) {
|
||||
if (function == null || !this.names.containsKey(function)) {
|
||||
return null;
|
||||
}
|
||||
return new FunctionRegistration<>(function, names.get(function))
|
||||
return new FunctionRegistration<>(function, this.names.get(function))
|
||||
.type(findType(function).getType());
|
||||
}
|
||||
|
||||
@@ -315,15 +305,15 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
final Object value = function;
|
||||
lookup.computeIfAbsent(name, key -> value);
|
||||
if (!types.containsKey(name)) {
|
||||
if (types.containsKey(stages[0])
|
||||
&& types.containsKey(stages[stages.length - 1])) {
|
||||
FunctionType input = types.get(stages[0]);
|
||||
FunctionType output = types.get(stages[stages.length - 1]);
|
||||
types.put(name, FunctionType.compose(input, output));
|
||||
if (!this.types.containsKey(name)) {
|
||||
if (this.types.containsKey(stages[0])
|
||||
&& this.types.containsKey(stages[stages.length - 1])) {
|
||||
FunctionType input = this.types.get(stages[0]);
|
||||
FunctionType output = this.types.get(stages[stages.length - 1]);
|
||||
this.types.put(name, FunctionType.compose(input, output));
|
||||
}
|
||||
}
|
||||
names.put(function, name);
|
||||
this.names.put(function, name);
|
||||
return function;
|
||||
}
|
||||
|
||||
@@ -341,12 +331,14 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
Supplier<Flux<Object>> supplier = (Supplier<Flux<Object>>) a;
|
||||
if (b instanceof FluxConsumer) {
|
||||
if (supplier instanceof FluxSupplier) {
|
||||
FluxConsumer<Object> fConsumer = ((FluxConsumer<Object>)b);
|
||||
return (Supplier<Mono<Void>>) () -> Mono.from(supplier.get().compose(v -> fConsumer.apply(supplier.get())));
|
||||
FluxConsumer<Object> fConsumer = ((FluxConsumer<Object>) b);
|
||||
return (Supplier<Mono<Void>>) () -> Mono.from(supplier.get()
|
||||
.compose(v -> fConsumer.apply(supplier.get())));
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("The provided supplier is finite (i.e., already composed with Consumer) "
|
||||
+ "therefore it can not be composed with another consumer");
|
||||
throw new IllegalStateException(
|
||||
"The provided supplier is finite (i.e., already composed with Consumer) "
|
||||
+ "therefore it can not be composed with another consumer");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -362,13 +354,16 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
return function1.andThen(function2);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("The provided function is finite (i.e., returns Mono<?>) "
|
||||
+ "therefore it can *only* be composed with compatible function (i.e., Function<Mono, Flux>");
|
||||
throw new IllegalStateException(
|
||||
"The provided function is finite (i.e., returns Mono<?>) "
|
||||
+ "therefore it can *only* be composed with compatible function (i.e., Function<Mono, Flux>");
|
||||
}
|
||||
}
|
||||
else if (function2 instanceof FluxToMonoFunction) {
|
||||
return new FluxToMonoFunction<Object, Object>(((Function<Flux<Object>, Flux<Object>>)a)
|
||||
.andThen(((FluxToMonoFunction<Object,Object>) b).getTarget()));
|
||||
return new FluxToMonoFunction<Object, Object>(
|
||||
((Function<Flux<Object>, Flux<Object>>) a)
|
||||
.andThen(((FluxToMonoFunction<Object, Object>) b)
|
||||
.getTarget()));
|
||||
}
|
||||
else {
|
||||
return function1.andThen(function2);
|
||||
@@ -391,18 +386,18 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
if (publisher != null) {
|
||||
if (!functions.isEmpty()) {
|
||||
publisher.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Function.class, functions.keySet()));
|
||||
if (this.publisher != null) {
|
||||
if (!this.functions.isEmpty()) {
|
||||
this.publisher.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Function.class, this.functions.keySet()));
|
||||
}
|
||||
if (!consumers.isEmpty()) {
|
||||
publisher.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Consumer.class, consumers.keySet()));
|
||||
if (!this.consumers.isEmpty()) {
|
||||
this.publisher.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Consumer.class, this.consumers.keySet()));
|
||||
}
|
||||
if (!suppliers.isEmpty()) {
|
||||
publisher.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Supplier.class, suppliers.keySet()));
|
||||
if (!this.suppliers.isEmpty()) {
|
||||
this.publisher.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Supplier.class, this.suppliers.keySet()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -443,8 +438,8 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
private Collection<String> getAliases(String key) {
|
||||
Collection<String> names = new LinkedHashSet<>();
|
||||
String value = getQualifier(key);
|
||||
if (value.equals(key) && registry != null) {
|
||||
names.addAll(Arrays.asList(registry.getAliases(key)));
|
||||
if (value.equals(key) && this.registry != null) {
|
||||
names.addAll(Arrays.asList(this.registry.getAliases(key)));
|
||||
}
|
||||
names.add(value);
|
||||
return names;
|
||||
@@ -485,8 +480,8 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
// this.names.remove(target);
|
||||
this.names.put(registration.getTarget(), key);
|
||||
if (publisher != null) {
|
||||
publisher.publishEvent(new FunctionRegistrationEvent(
|
||||
if (this.publisher != null) {
|
||||
this.publisher.publishEvent(new FunctionRegistrationEvent(
|
||||
registration.getTarget(), type, registration.getNames()));
|
||||
}
|
||||
}
|
||||
@@ -552,8 +547,8 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
|
||||
private String getQualifier(String key) {
|
||||
if (registry != null && registry.containsBeanDefinition(key)) {
|
||||
BeanDefinition beanDefinition = registry.getBeanDefinition(key);
|
||||
if (this.registry != null && this.registry.containsBeanDefinition(key)) {
|
||||
BeanDefinition beanDefinition = this.registry.getBeanDefinition(key);
|
||||
Object source = beanDefinition.getSource();
|
||||
if (source instanceof StandardMethodMetadata) {
|
||||
StandardMethodMetadata metadata = (StandardMethodMetadata) source;
|
||||
@@ -568,13 +563,13 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
|
||||
private FunctionType findType(Object function) {
|
||||
String name = names.get(function);
|
||||
if (types.containsKey(name)) {
|
||||
return types.get(name);
|
||||
String name = this.names.get(function);
|
||||
if (this.types.containsKey(name)) {
|
||||
return this.types.get(name);
|
||||
}
|
||||
FunctionType param;
|
||||
if (name == null || registry == null
|
||||
|| !registry.containsBeanDefinition(name)) {
|
||||
if (name == null || this.registry == null
|
||||
|| !this.registry.containsBeanDefinition(name)) {
|
||||
if (function != null) {
|
||||
param = new FunctionType(function.getClass());
|
||||
}
|
||||
@@ -583,9 +578,10 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
}
|
||||
else {
|
||||
param = new FunctionType(FunctionContextUtils.findType(name, registry));
|
||||
param = new FunctionType(
|
||||
FunctionContextUtils.findType(name, this.registry));
|
||||
}
|
||||
types.computeIfAbsent(name, str -> param);
|
||||
this.types.computeIfAbsent(name, str -> param);
|
||||
return param;
|
||||
}
|
||||
|
||||
@@ -597,7 +593,7 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(name = ContextFunctionCatalogAutoConfiguration.PREFERRED_MAPPER_PROPERTY, havingValue = "gson", matchIfMissing = false)
|
||||
@ConditionalOnProperty(name = PREFERRED_MAPPER_PROPERTY, havingValue = "gson", matchIfMissing = false)
|
||||
static class GsonPreferred {
|
||||
|
||||
}
|
||||
@@ -609,4 +605,21 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
protected class BeanFactoryFunctionInspector implements FunctionInspector {
|
||||
|
||||
private ContextFunctionRegistry processor;
|
||||
|
||||
public BeanFactoryFunctionInspector(ContextFunctionRegistry processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionRegistration<?> getRegistration(Object function) {
|
||||
FunctionRegistration<?> registration = this.processor
|
||||
.getRegistration(function);
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,8 +50,14 @@ import org.springframework.util.ClassUtils;
|
||||
public class ContextFunctionCatalogInitializer
|
||||
implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
/**
|
||||
* Property name for ignoring pre initilizer.
|
||||
*/
|
||||
public static final String IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME = "spring.backgroundpreinitializer.ignore";
|
||||
|
||||
/**
|
||||
* Flag for enabling the context function catalog initializer.
|
||||
*/
|
||||
public static boolean enabled = true;
|
||||
|
||||
@Override
|
||||
@@ -69,7 +75,7 @@ public class ContextFunctionCatalogInitializer
|
||||
|
||||
private GenericApplicationContext context;
|
||||
|
||||
public ContextFunctionCatalogBeanRegistrar(
|
||||
ContextFunctionCatalogBeanRegistrar(
|
||||
GenericApplicationContext applicationContext) {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
@@ -101,65 +107,67 @@ public class ContextFunctionCatalogInitializer
|
||||
|
||||
performPreinitialization();
|
||||
|
||||
if (context.getBeanFactory().getBeanNamesForType(
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(
|
||||
PropertySourcesPlaceholderConfigurer.class, false,
|
||||
false).length == 0) {
|
||||
context.registerBean(PropertySourcesPlaceholderConfigurer.class,
|
||||
this.context.registerBean(PropertySourcesPlaceholderConfigurer.class,
|
||||
() -> PropertyPlaceholderAutoConfiguration
|
||||
.propertySourcesPlaceholderConfigurer());
|
||||
}
|
||||
|
||||
if (!context.getBeanFactory().containsBean(
|
||||
if (!this.context.getBeanFactory().containsBean(
|
||||
AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||
// Switch off the ConfigurationClassPostProcessor
|
||||
context.registerBean(
|
||||
this.context.registerBean(
|
||||
AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,
|
||||
DummyProcessor.class, () -> new DummyProcessor());
|
||||
// But switch on other annotation processing
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.context);
|
||||
}
|
||||
if (!context.getBeanFactory()
|
||||
if (!this.context.getBeanFactory()
|
||||
.containsBean(ConfigurationBeanFactoryMetadata.BEAN_NAME)) {
|
||||
context.registerBean(ConfigurationBeanFactoryMetadata.BEAN_NAME,
|
||||
this.context.registerBean(ConfigurationBeanFactoryMetadata.BEAN_NAME,
|
||||
ConfigurationBeanFactoryMetadata.class,
|
||||
() -> new ConfigurationBeanFactoryMetadata());
|
||||
context.registerBean(
|
||||
this.context.registerBean(
|
||||
ConfigurationPropertiesBindingPostProcessor.BEAN_NAME,
|
||||
ConfigurationPropertiesBindingPostProcessor.class,
|
||||
() -> new ConfigurationPropertiesBindingPostProcessor());
|
||||
}
|
||||
|
||||
if (ClassUtils.isPresent("com.google.gson.Gson", null)
|
||||
&& "gson".equals(context.getEnvironment().getProperty(
|
||||
&& "gson".equals(this.context.getEnvironment().getProperty(
|
||||
ContextFunctionCatalogAutoConfiguration.PREFERRED_MAPPER_PROPERTY,
|
||||
"gson"))) {
|
||||
if (context.getBeanFactory().getBeanNamesForType(Gson.class, false,
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(Gson.class, false,
|
||||
false).length == 0) {
|
||||
context.registerBean(Gson.class, () -> new Gson());
|
||||
this.context.registerBean(Gson.class, () -> new Gson());
|
||||
}
|
||||
context.registerBean(JsonMapper.class,
|
||||
this.context.registerBean(JsonMapper.class,
|
||||
() -> new ContextFunctionCatalogAutoConfiguration.GsonConfiguration()
|
||||
.jsonMapper(context.getBean(Gson.class)));
|
||||
.jsonMapper(this.context.getBean(Gson.class)));
|
||||
}
|
||||
else if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
||||
null)) {
|
||||
if (context.getBeanFactory().getBeanNamesForType(ObjectMapper.class,
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(ObjectMapper.class,
|
||||
false, false).length == 0) {
|
||||
context.registerBean(ObjectMapper.class, () -> new ObjectMapper());
|
||||
this.context.registerBean(ObjectMapper.class,
|
||||
() -> new ObjectMapper());
|
||||
}
|
||||
context.registerBean(JsonMapper.class,
|
||||
this.context.registerBean(JsonMapper.class,
|
||||
() -> new ContextFunctionCatalogAutoConfiguration.JacksonConfiguration()
|
||||
.jsonMapper(context.getBean(ObjectMapper.class)));
|
||||
.jsonMapper(this.context.getBean(ObjectMapper.class)));
|
||||
|
||||
}
|
||||
|
||||
if (context.getBeanFactory().getBeanNamesForType(FunctionCatalog.class, false,
|
||||
false).length == 0) {
|
||||
context.registerBean(InMemoryFunctionCatalog.class,
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(FunctionCatalog.class,
|
||||
false, false).length == 0) {
|
||||
this.context.registerBean(InMemoryFunctionCatalog.class,
|
||||
() -> new InMemoryFunctionCatalog());
|
||||
context.registerBean(FunctionRegistrationPostProcessor.class,
|
||||
() -> new FunctionRegistrationPostProcessor(
|
||||
context.getAutowireCapableBeanFactory()
|
||||
this.context
|
||||
.registerBean(FunctionRegistrationPostProcessor.class,
|
||||
() -> new FunctionRegistrationPostProcessor(this.context
|
||||
.getAutowireCapableBeanFactory()
|
||||
.getBeanProvider(FunctionRegistration.class)));
|
||||
}
|
||||
}
|
||||
@@ -193,10 +201,11 @@ public class ContextFunctionCatalogInitializer
|
||||
}
|
||||
|
||||
private class FunctionRegistrationPostProcessor implements BeanPostProcessor {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final ObjectProvider<FunctionRegistration> functions;
|
||||
|
||||
public FunctionRegistrationPostProcessor(
|
||||
FunctionRegistrationPostProcessor(
|
||||
@SuppressWarnings("rawtypes") ObjectProvider<FunctionRegistration> functions) {
|
||||
this.functions = functions;
|
||||
}
|
||||
@@ -206,7 +215,7 @@ public class ContextFunctionCatalogInitializer
|
||||
throws BeansException {
|
||||
if (bean instanceof FunctionRegistry) {
|
||||
FunctionRegistry catalog = (FunctionRegistry) bean;
|
||||
for (FunctionRegistration<?> registration : functions) {
|
||||
for (FunctionRegistration<?> registration : this.functions) {
|
||||
Assert.notEmpty(registration.getNames(),
|
||||
"FunctionRegistration must define at least one name. Was empty");
|
||||
if (registration.getType() == null) {
|
||||
@@ -222,13 +231,19 @@ public class ContextFunctionCatalogInitializer
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy implementation of a processor.
|
||||
*/
|
||||
public static class DummyProcessor {
|
||||
|
||||
public void setMetadataReaderFactory(MetadataReaderFactory obj) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,103 +38,106 @@ import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class FunctionContextUtils {
|
||||
|
||||
public static Type findType(String name, ConfigurableListableBeanFactory registry) {
|
||||
AbstractBeanDefinition definition = (AbstractBeanDefinition) registry.getBeanDefinition(name);
|
||||
Object source = definition.getSource();
|
||||
Type param = null;
|
||||
// Start by assuming output -> Function
|
||||
if (source instanceof StandardMethodMetadata) {
|
||||
// Standard @Bean metadata
|
||||
param = ((StandardMethodMetadata) source).getIntrospectedMethod()
|
||||
.getGenericReturnType();
|
||||
}
|
||||
else if (source instanceof MethodMetadataReadingVisitor) {
|
||||
// A component scan with @Beans
|
||||
MethodMetadataReadingVisitor visitor = (MethodMetadataReadingVisitor) source;
|
||||
param = findBeanType(definition, visitor);
|
||||
}
|
||||
else if (source instanceof Resource) {
|
||||
param = registry.getType(name);
|
||||
}
|
||||
else {
|
||||
ResolvableType type = (ResolvableType) getField(definition, "targetType");
|
||||
if (type != null) {
|
||||
param = type.getType();
|
||||
}
|
||||
else {
|
||||
Class<?> beanClass = definition.getBeanClass();
|
||||
if (beanClass != null && !FunctionFactoryMetadata.class.isAssignableFrom(beanClass)) {
|
||||
param = beanClass;
|
||||
}
|
||||
else {
|
||||
//assume FunctionFactoryMetadata
|
||||
FunctionFactoryMetadata<?> factory = (FunctionFactoryMetadata<?>) registry.getBean(name);
|
||||
param = factory.getFactoryMethod().getGenericReturnType();
|
||||
}
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}
|
||||
public static Type findType(String name, ConfigurableListableBeanFactory registry) {
|
||||
AbstractBeanDefinition definition = (AbstractBeanDefinition) registry
|
||||
.getBeanDefinition(name);
|
||||
Object source = definition.getSource();
|
||||
Type param = null;
|
||||
// Start by assuming output -> Function
|
||||
if (source instanceof StandardMethodMetadata) {
|
||||
// Standard @Bean metadata
|
||||
param = ((StandardMethodMetadata) source).getIntrospectedMethod()
|
||||
.getGenericReturnType();
|
||||
}
|
||||
else if (source instanceof MethodMetadataReadingVisitor) {
|
||||
// A component scan with @Beans
|
||||
MethodMetadataReadingVisitor visitor = (MethodMetadataReadingVisitor) source;
|
||||
param = findBeanType(definition, visitor);
|
||||
}
|
||||
else if (source instanceof Resource) {
|
||||
param = registry.getType(name);
|
||||
}
|
||||
else {
|
||||
ResolvableType type = (ResolvableType) getField(definition, "targetType");
|
||||
if (type != null) {
|
||||
param = type.getType();
|
||||
}
|
||||
else {
|
||||
Class<?> beanClass = definition.getBeanClass();
|
||||
if (beanClass != null
|
||||
&& !FunctionFactoryMetadata.class.isAssignableFrom(beanClass)) {
|
||||
param = beanClass;
|
||||
}
|
||||
else {
|
||||
// assume FunctionFactoryMetadata
|
||||
FunctionFactoryMetadata<?> factory = (FunctionFactoryMetadata<?>) registry
|
||||
.getBean(name);
|
||||
param = factory.getFactoryMethod().getGenericReturnType();
|
||||
}
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
private static Type findBeanType(AbstractBeanDefinition definition,
|
||||
MethodMetadataReadingVisitor visitor) {
|
||||
Class<?> factory = ClassUtils
|
||||
.resolveClassName(visitor.getDeclaringClassName(), null);
|
||||
Class<?>[] params = getParamTypes(factory, definition);
|
||||
Method method = ReflectionUtils.findMethod(factory, visitor.getMethodName(),
|
||||
params);
|
||||
Type type = method.getGenericReturnType();
|
||||
return type;
|
||||
}
|
||||
private static Type findBeanType(AbstractBeanDefinition definition,
|
||||
MethodMetadataReadingVisitor visitor) {
|
||||
Class<?> factory = ClassUtils.resolveClassName(visitor.getDeclaringClassName(),
|
||||
null);
|
||||
Class<?>[] params = getParamTypes(factory, definition);
|
||||
Method method = ReflectionUtils.findMethod(factory, visitor.getMethodName(),
|
||||
params);
|
||||
Type type = method.getGenericReturnType();
|
||||
return type;
|
||||
}
|
||||
|
||||
private static Class<?>[] getParamTypes(Class<?> factory,
|
||||
AbstractBeanDefinition definition) {
|
||||
if (definition instanceof RootBeanDefinition) {
|
||||
RootBeanDefinition root = (RootBeanDefinition) definition;
|
||||
for (Method method : getCandidateMethods(factory, root)) {
|
||||
if (root.isFactoryMethod(method)) {
|
||||
return method.getParameterTypes();
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Class<?>> params = new ArrayList<>();
|
||||
for (ConstructorArgumentValues.ValueHolder holder : definition.getConstructorArgumentValues()
|
||||
.getIndexedArgumentValues().values()) {
|
||||
params.add(ClassUtils.resolveClassName(holder.getType(), null));
|
||||
}
|
||||
return params.toArray(new Class<?>[0]);
|
||||
}
|
||||
private static Class<?>[] getParamTypes(Class<?> factory,
|
||||
AbstractBeanDefinition definition) {
|
||||
if (definition instanceof RootBeanDefinition) {
|
||||
RootBeanDefinition root = (RootBeanDefinition) definition;
|
||||
for (Method method : getCandidateMethods(factory, root)) {
|
||||
if (root.isFactoryMethod(method)) {
|
||||
return method.getParameterTypes();
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Class<?>> params = new ArrayList<>();
|
||||
for (ConstructorArgumentValues.ValueHolder holder : definition
|
||||
.getConstructorArgumentValues().getIndexedArgumentValues().values()) {
|
||||
params.add(ClassUtils.resolveClassName(holder.getType(), null));
|
||||
}
|
||||
return params.toArray(new Class<?>[0]);
|
||||
}
|
||||
|
||||
private static Method[] getCandidateMethods(final Class<?> factoryClass,
|
||||
final RootBeanDefinition mbd) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
|
||||
@Override
|
||||
public Method[] run() {
|
||||
return (mbd.isNonPublicAccessAllowed()
|
||||
? ReflectionUtils.getAllDeclaredMethods(factoryClass)
|
||||
: factoryClass.getMethods());
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return (mbd.isNonPublicAccessAllowed()
|
||||
? ReflectionUtils.getAllDeclaredMethods(factoryClass)
|
||||
: factoryClass.getMethods());
|
||||
}
|
||||
}
|
||||
private static Method[] getCandidateMethods(final Class<?> factoryClass,
|
||||
final RootBeanDefinition mbd) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
|
||||
@Override
|
||||
public Method[] run() {
|
||||
return (mbd.isNonPublicAccessAllowed()
|
||||
? ReflectionUtils.getAllDeclaredMethods(factoryClass)
|
||||
: factoryClass.getMethods());
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return (mbd.isNonPublicAccessAllowed()
|
||||
? ReflectionUtils.getAllDeclaredMethods(factoryClass)
|
||||
: factoryClass.getMethods());
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
return ReflectionUtils.getField(field, target);
|
||||
}
|
||||
|
||||
private static Object getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
return ReflectionUtils.getField(field, target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,7 +39,6 @@ public abstract class MessageUtils {
|
||||
* isolated class loader, then the message will be created with the target class
|
||||
* loader (therefore the {@link Message} class must be on the classpath of the target
|
||||
* class loader).
|
||||
*
|
||||
* @param handler the function that will be applied to the message
|
||||
* @param payload the payload of the message
|
||||
* @param headers the headers for the message
|
||||
@@ -74,7 +73,6 @@ public abstract class MessageUtils {
|
||||
* class loader. If the handler is a wrapper for a function in an isolated class
|
||||
* loader, then the message will be created with the target class loader (therefore
|
||||
* the {@link Message} class must be on the classpath of the target class loader).
|
||||
*
|
||||
* @param handler the function that generated the message
|
||||
* @param message the message to convert
|
||||
* @return a message with the correct class loader
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,16 +42,16 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
@ContextConfiguration(loader = FunctionalTestContextLoader.class)
|
||||
public @interface FunctionalSpringBootTest {
|
||||
|
||||
@AliasFor(annotation=SpringBootTest.class, attribute="properties")
|
||||
@AliasFor(annotation = SpringBootTest.class, attribute = "properties")
|
||||
String[] value() default {};
|
||||
|
||||
@AliasFor(annotation=SpringBootTest.class, attribute="value")
|
||||
@AliasFor(annotation = SpringBootTest.class, attribute = "value")
|
||||
String[] properties() default {};
|
||||
|
||||
@AliasFor(annotation=SpringBootTest.class, attribute="classes")
|
||||
@AliasFor(annotation = SpringBootTest.class, attribute = "classes")
|
||||
Class<?>[] classes() default {};
|
||||
|
||||
@AliasFor(annotation=SpringBootTest.class, attribute="webEnvironment")
|
||||
@AliasFor(annotation = SpringBootTest.class, attribute = "webEnvironment")
|
||||
WebEnvironment webEnvironment() default WebEnvironment.MOCK;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,4 +34,5 @@ class FunctionalTestContextLoader extends SpringBootContextLoader {
|
||||
protected SpringApplication getSpringApplication() {
|
||||
return new FunctionalSpringApplication();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.json;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
@@ -34,11 +35,12 @@ public class GsonMapper implements JsonMapper {
|
||||
|
||||
@Override
|
||||
public <T> T toObject(String json, Type type) {
|
||||
return gson.fromJson(json, type);
|
||||
return this.gson.fromJson(json, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Object value) {
|
||||
return gson.toJson(value);
|
||||
return this.gson.toJson(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.json;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
@@ -36,7 +37,8 @@ public class JacksonMapper implements JsonMapper {
|
||||
@Override
|
||||
public <T> T toObject(String json, Type type) {
|
||||
try {
|
||||
return mapper.readValue(json, TypeFactory.defaultInstance().constructType(type));
|
||||
return this.mapper.readValue(json,
|
||||
TypeFactory.defaultInstance().constructType(type));
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException("Cannot convert JSON " + json, e);
|
||||
@@ -46,10 +48,11 @@ public class JacksonMapper implements JsonMapper {
|
||||
@Override
|
||||
public String toString(Object value) {
|
||||
try {
|
||||
return mapper.writeValueAsString(value);
|
||||
return this.mapper.writeValueAsString(value);
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("Cannot convert to JSON", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.json;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
@@ -28,6 +29,10 @@ import org.springframework.core.ResolvableType;
|
||||
public interface JsonMapper {
|
||||
|
||||
/**
|
||||
* @param <T> type for list arguments
|
||||
* @param json JSON input
|
||||
* @param type type of list arguments
|
||||
* @return list of elements
|
||||
* @deprecated since v2.0 in favor of {@link #toObject(String, Type)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -40,11 +45,19 @@ public interface JsonMapper {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> return type
|
||||
* @param json JSON input
|
||||
* @param type type
|
||||
* @return object
|
||||
* @since 2.0
|
||||
*/
|
||||
<T> T toObject(String json, Type type);
|
||||
|
||||
/**
|
||||
* @param <T> type for list arguments
|
||||
* @param json JSON input
|
||||
* @param type type of list arguments
|
||||
* @return single object
|
||||
* @deprecated since v2.0 in favor of {@link #toObject(String, Type)}
|
||||
*/
|
||||
default <T> T toSingle(String json, Class<T> type) {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"hints": [],
|
||||
"groups": [],
|
||||
"properties": [
|
||||
{
|
||||
"name": "spring.cloud.function.scan.packages",
|
||||
"type": "java.lang.String",
|
||||
"description": "Triggers scanning within the specified base packages for any class that is assignable to java.util.function.Function. For each detected Function class, a bean instance will be added to the context.",
|
||||
"defaultValue": "functions"
|
||||
},
|
||||
{
|
||||
"name": "spring.cloud.function.definition",
|
||||
"type": "java.lang.String",
|
||||
"description": "Name (e.g., 'foo') or composition instruction (e.g., 'foo|bar') used to resolve default function especially for cases where there is more then once function available in catalog.",
|
||||
"defaultValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
"hints": [],
|
||||
"groups": [],
|
||||
"properties": [
|
||||
{
|
||||
"name": "spring.cloud.function.scan.packages",
|
||||
"type": "java.lang.String",
|
||||
"description": "Triggers scanning within the specified base packages for any class that is assignable to java.util.function.Function. For each detected Function class, a bean instance will be added to the context.",
|
||||
"defaultValue": "functions"
|
||||
},
|
||||
{
|
||||
"name": "spring.cloud.function.definition",
|
||||
"type": "java.lang.String",
|
||||
"description": "Name (e.g., 'foo') or composition instruction (e.g., 'foo|bar') used to resolve default function especially for cases where there is more then once function available in catalog.",
|
||||
"defaultValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration
|
||||
|
||||
org.springframework.cloud.function.context.WrapperDetector=\
|
||||
org.springframework.cloud.function.context.config.FluxWrapperDetector
|
||||
|
||||
org.springframework.context.ApplicationContextInitializer=\
|
||||
org.springframework.cloud.function.context.config.ContextFunctionCatalogInitializer
|
||||
org.springframework.cloud.function.context.config.ContextFunctionCatalogInitializer
|
||||
|
||||
Reference in New Issue
Block a user