Add support for explicit FunctionRegistration
A bean of type FunctionRegistration registers the function with user-specified name and other properties, rather than relying on the bean name. Alternatively, function catalog keys can be specified as a @Qualifier, which will be used instead of the bean name if no registration is found.
This commit is contained in:
@@ -24,6 +24,10 @@
|
|||||||
<artifactId>spring-cloud-function-core</artifactId>
|
<artifactId>spring-cloud-function-core</artifactId>
|
||||||
<version>${spring-cloud-function.version}</version>
|
<version>${spring-cloud-function.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
@@ -33,5 +37,10 @@
|
|||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -19,9 +19,12 @@ package org.springframework.cloud.function.context;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -32,6 +35,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
@@ -48,6 +52,7 @@ import org.springframework.cloud.function.support.FunctionUtils;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
import org.springframework.core.type.StandardMethodMetadata;
|
import org.springframework.core.type.StandardMethodMetadata;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
@@ -73,12 +78,14 @@ public class ContextFunctionCatalogAutoConfiguration {
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private Map<String, Consumer<?>> consumers = Collections.emptyMap();
|
private Map<String, Consumer<?>> consumers = Collections.emptyMap();
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private Map<String, FunctionRegistration<?>> registrations = Collections.emptyMap();
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public FunctionCatalog functionCatalog(ContextFunctionPostProcessor processor,
|
public FunctionCatalog functionCatalog(ContextFunctionPostProcessor processor,
|
||||||
ObjectMapper mapper) {
|
ObjectMapper mapper) {
|
||||||
return new InMemoryFunctionCatalog(processor.wrapSuppliers(mapper, suppliers),
|
return new InMemoryFunctionCatalog(
|
||||||
processor.wrapFunctions(mapper, functions),
|
processor.merge(registrations, consumers, suppliers, functions, mapper));
|
||||||
processor.wrapConsumers(mapper, consumers));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -96,17 +103,101 @@ public class ContextFunctionCatalogAutoConfiguration {
|
|||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Supplier<?>> wrapSuppliers(ObjectMapper mapper,
|
public Set<FunctionRegistration<?>> merge(
|
||||||
Map<String, Supplier<?>> suppliers) {
|
Map<String, FunctionRegistration<?>> initial,
|
||||||
Map<String, Supplier<?>> result = new HashMap<>();
|
Map<String, Consumer<?>> consumers, Map<String, Supplier<?>> suppliers,
|
||||||
for (String key : suppliers.keySet()) {
|
Map<String, Function<?, ?>> functions, ObjectMapper mapper) {
|
||||||
Supplier<?> target = target(suppliers.get(key), mapper, key);
|
Set<FunctionRegistration<?>> registrations = new HashSet<>();
|
||||||
result.put(key, target);
|
Map<Object, String> targets = new HashMap<>();
|
||||||
for (String name : registry.getAliases(key)) {
|
// Replace the initial registrations with new ones that have the right names
|
||||||
result.put(name, target);
|
for (String key : initial.keySet()) {
|
||||||
|
FunctionRegistration<?> registration = initial.get(key);
|
||||||
|
if (registration.getNames().isEmpty()) {
|
||||||
|
registration.names(getAliases(key));
|
||||||
|
}
|
||||||
|
registrations.add(registration);
|
||||||
|
targets.put(registration.getTarget(), key);
|
||||||
|
}
|
||||||
|
// Add consumers that were not already registered
|
||||||
|
for (String key : consumers.keySet()) {
|
||||||
|
if (!targets.containsKey(consumers.get(key))) {
|
||||||
|
FunctionRegistration<Object> target = new FunctionRegistration<Object>()
|
||||||
|
.target(consumers.get(key)).names(getAliases(key));
|
||||||
|
targets.put(target.getTarget(), key);
|
||||||
|
registrations.add(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
// Add suppliers that were not already registered
|
||||||
|
for (String key : suppliers.keySet()) {
|
||||||
|
if (!targets.containsKey(suppliers.get(key))) {
|
||||||
|
FunctionRegistration<Object> target = new FunctionRegistration<Object>()
|
||||||
|
.target(suppliers.get(key)).names(getAliases(key));
|
||||||
|
targets.put(target.getTarget(), key);
|
||||||
|
registrations.add(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add functions that were not already registered
|
||||||
|
for (String key : functions.keySet()) {
|
||||||
|
if (!targets.containsKey(functions.get(key))) {
|
||||||
|
FunctionRegistration<Object> target = new FunctionRegistration<Object>()
|
||||||
|
.target(functions.get(key)).names(getAliases(key));
|
||||||
|
targets.put(target.getTarget(), key);
|
||||||
|
registrations.add(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Wrap the functions so they handle reactive inputs and outputs
|
||||||
|
for (FunctionRegistration<?> registration : registrations) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
FunctionRegistration<Object> target = (FunctionRegistration<Object>) registration;
|
||||||
|
String key = targets.get(target.getTarget());
|
||||||
|
wrap(target, mapper, key);
|
||||||
|
}
|
||||||
|
return registrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<String> getAliases(String key) {
|
||||||
|
Collection<String> names = new LinkedHashSet<>();
|
||||||
|
String value = getQualifier(key);
|
||||||
|
if (value.equals(key)) {
|
||||||
|
names.add(key);
|
||||||
|
names.addAll(Arrays.asList(registry.getAliases(key)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
names.add(value);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void wrap(FunctionRegistration<Object> registration,
|
||||||
|
ObjectMapper mapper, String key) {
|
||||||
|
Object target = registration.getTarget();
|
||||||
|
if (target instanceof Supplier) {
|
||||||
|
registration.target(target((Supplier<?>) target, mapper, key));
|
||||||
|
}
|
||||||
|
else if (target instanceof Consumer) {
|
||||||
|
registration.target(target((Consumer<?>) target, mapper, key));
|
||||||
|
}
|
||||||
|
else if (target instanceof Function) {
|
||||||
|
registration.target(target((Function<?, ?>) target, mapper, key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getQualifier(String key) {
|
||||||
|
if (!registry.containsBeanDefinition(key)) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
String value = key;
|
||||||
|
BeanDefinition beanDefinition = registry.getBeanDefinition(key);
|
||||||
|
Object source = beanDefinition.getSource();
|
||||||
|
if (source instanceof StandardMethodMetadata) {
|
||||||
|
StandardMethodMetadata metadata = (StandardMethodMetadata) source;
|
||||||
|
Qualifier qualifier = AnnotatedElementUtils.findMergedAnnotation(
|
||||||
|
metadata.getIntrospectedMethod(), Qualifier.class);
|
||||||
|
if (qualifier != null && qualifier.value().length() > 0) {
|
||||||
|
return qualifier.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<?> target(Supplier<?> target, ObjectMapper mapper, String key) {
|
private Supplier<?> target(Supplier<?> target, ObjectMapper mapper, String key) {
|
||||||
@@ -125,19 +216,6 @@ public class ContextFunctionCatalogAutoConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Function<?, ?>> wrapFunctions(ObjectMapper mapper,
|
|
||||||
Map<String, Function<?, ?>> functions) {
|
|
||||||
Map<String, Function<?, ?>> result = new HashMap<>();
|
|
||||||
for (String key : functions.keySet()) {
|
|
||||||
Function<?, ?> target = target(functions.get(key), mapper, key);
|
|
||||||
result.put(key, target);
|
|
||||||
for (String name : registry.getAliases(key)) {
|
|
||||||
result.put(name, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Function<?, ?> target(Function<?, ?> target, ObjectMapper mapper,
|
private Function<?, ?> target(Function<?, ?> target, ObjectMapper mapper,
|
||||||
String key) {
|
String key) {
|
||||||
if (this.functions.contains(key)) {
|
if (this.functions.contains(key)) {
|
||||||
@@ -155,19 +233,6 @@ public class ContextFunctionCatalogAutoConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Consumer<?>> wrapConsumers(ObjectMapper mapper,
|
|
||||||
Map<String, Consumer<?>> consumers) {
|
|
||||||
Map<String, Consumer<?>> result = new HashMap<>();
|
|
||||||
for (String key : consumers.keySet()) {
|
|
||||||
Consumer<?> target = target(consumers.get(key), mapper, key);
|
|
||||||
result.put(key, target);
|
|
||||||
for (String name : registry.getAliases(key)) {
|
|
||||||
result.put(name, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Consumer<?> target(Consumer<?> target, ObjectMapper mapper, String key) {
|
private Consumer<?> target(Consumer<?> target, ObjectMapper mapper, String key) {
|
||||||
if (this.consumers.contains(key)) {
|
if (this.consumers.contains(key)) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 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
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cloud.function.context;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.cloud.function.registry.FunctionCatalog;
|
||||||
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Qualifier} annotation that specifies how to locate a function in the
|
||||||
|
* {@link FunctionCatalog} (instead of using the bean name).
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
*/
|
||||||
|
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
|
||||||
|
ElementType.ANNOTATION_TYPE })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Inherited
|
||||||
|
@Documented
|
||||||
|
@Qualifier
|
||||||
|
public @interface FunctionEntry {
|
||||||
|
@AliasFor(annotation=Qualifier.class)
|
||||||
|
String value() default "";
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2015 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
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cloud.function.context;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dave Syer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FunctionRegistration<T> {
|
||||||
|
|
||||||
|
private T target;
|
||||||
|
|
||||||
|
private Set<String> names = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
private Map<String, String> properties = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
public FunctionRegistration() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionRegistration(T target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getNames() {
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNames(Set<String> names) {
|
||||||
|
this.names = names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionRegistration<T> properties(Map<String, String> properties) {
|
||||||
|
this.properties.putAll(properties);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionRegistration<T> target(T target) {
|
||||||
|
this.target = target;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionRegistration<T> name(String name) {
|
||||||
|
this.names.add(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionRegistration<T> names(Collection<String> names) {
|
||||||
|
this.names.addAll(names);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionRegistration<T> names(String... names) {
|
||||||
|
this.names.addAll(Arrays.asList(names));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.springframework.cloud.function.context;
|
package org.springframework.cloud.function.context;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@@ -43,6 +45,29 @@ public class InMemoryFunctionCatalog implements FunctionCatalog {
|
|||||||
this.consumers = consumers;
|
this.consumers = consumers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InMemoryFunctionCatalog(Set<FunctionRegistration<?>> registrations) {
|
||||||
|
this.suppliers = new HashMap<>();
|
||||||
|
this.functions = new HashMap<>();
|
||||||
|
this.consumers = new HashMap<>();
|
||||||
|
for (FunctionRegistration<?> registration : registrations) {
|
||||||
|
if (registration.getTarget() instanceof Consumer) {
|
||||||
|
for (String name : registration.getNames()) {
|
||||||
|
consumers.put(name, (Consumer<?>) registration.getTarget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (registration.getTarget() instanceof Supplier) {
|
||||||
|
for (String name : registration.getNames()) {
|
||||||
|
suppliers.put(name, (Supplier<?>) registration.getTarget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (registration.getTarget() instanceof Function) {
|
||||||
|
for (String name : registration.getNames()) {
|
||||||
|
functions.put(name, (Function<?, ?>) registration.getTarget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> Supplier<T> lookupSupplier(String name) {
|
public <T> Supplier<T> lookupSupplier(String name) {
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2015 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
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cloud.function.context;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dave Syer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ContextFunctionCatalogAutoConfigurationTests {
|
||||||
|
|
||||||
|
private ConfigurableApplicationContext context;
|
||||||
|
private InMemoryFunctionCatalog catalog;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void close() {
|
||||||
|
if (context != null) {
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleFunction() {
|
||||||
|
create(SimpleConfiguration.class);
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(Function.class);
|
||||||
|
assertThat(catalog.lookupFunction("function")).isInstanceOf(Function.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleSupplier() {
|
||||||
|
create(SimpleConfiguration.class);
|
||||||
|
assertThat(context.getBean("supplier")).isInstanceOf(Supplier.class);
|
||||||
|
Supplier<Flux<String>> supplier = catalog.lookupSupplier("supplier");
|
||||||
|
assertThat(supplier.get().blockFirst()).isEqualTo("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleConsumer() {
|
||||||
|
create(SimpleConfiguration.class);
|
||||||
|
assertThat(context.getBean("consumer")).isInstanceOf(Consumer.class);
|
||||||
|
Consumer<Flux<String>> consumer = catalog.lookupConsumer("consumer");
|
||||||
|
consumer.accept(Flux.just("foo", "bar"));
|
||||||
|
assertThat(context.getBean(SimpleConfiguration.class).list).hasSize(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void qualifiedBean() {
|
||||||
|
create(QualifiedConfiguration.class);
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(Function.class);
|
||||||
|
assertThat(catalog.lookupFunction("function")).isNull();
|
||||||
|
assertThat(catalog.lookupFunction("other")).isInstanceOf(Function.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void aliasBean() {
|
||||||
|
create(AliasConfiguration.class);
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(Function.class);
|
||||||
|
assertThat(catalog.lookupFunction("function")).isNotNull();
|
||||||
|
assertThat(catalog.lookupFunction("other")).isInstanceOf(Function.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registrationBean() {
|
||||||
|
create(RegistrationConfiguration.class);
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(Function.class);
|
||||||
|
assertThat(catalog.lookupFunction("function")).isNull();
|
||||||
|
assertThat(catalog.lookupFunction("registration")).isNull();
|
||||||
|
assertThat(catalog.lookupFunction("other")).isInstanceOf(Function.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void create(Class<?>... types) {
|
||||||
|
context = new SpringApplicationBuilder((Object[]) types).run();
|
||||||
|
catalog = context.getBean(InMemoryFunctionCatalog.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@Configuration
|
||||||
|
protected static class SimpleConfiguration {
|
||||||
|
private List<String> list = new ArrayList<>();
|
||||||
|
@Bean
|
||||||
|
public Function<String, String> function() {
|
||||||
|
return value -> value.toUpperCase();
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public Supplier<String> supplier() {
|
||||||
|
return () -> "hello";
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public Consumer<String> consumer() {
|
||||||
|
return value -> list.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@Configuration
|
||||||
|
protected static class QualifiedConfiguration {
|
||||||
|
@Bean
|
||||||
|
@Qualifier("other")
|
||||||
|
public Function<String, String> function() {
|
||||||
|
return value -> value.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@Configuration
|
||||||
|
protected static class AliasConfiguration {
|
||||||
|
@Bean({"function", "other"})
|
||||||
|
public Function<String, String> function() {
|
||||||
|
return value -> value.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@Configuration
|
||||||
|
protected static class RegistrationConfiguration {
|
||||||
|
@Bean
|
||||||
|
public FunctionRegistration<Function<String, String>> registration() {
|
||||||
|
return new FunctionRegistration<Function<String, String>>(function()).name("other");
|
||||||
|
}
|
||||||
|
@Bean
|
||||||
|
public Function<String, String> function() {
|
||||||
|
return value -> value.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user