GH-293 Enhanced endpoint mapping support for functional form context configuration
- Enhanced HTTP endpoint mapping support for 'functional form' context configuration ensuring it can register multiple endpoint to maintain the same behaviour as with regular application context - Additional consolidation around Function Catalog - Added identical test for functional and non-functional form endpoint configuration. Resolves #293
This commit is contained in:
@@ -47,6 +47,7 @@ import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -186,6 +187,28 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionRegistration<?> getRegistration(Object function) {
|
||||
String functionName = function == null ? null
|
||||
: this.lookupFunctionName(function);
|
||||
if (StringUtils.hasText(functionName)) {
|
||||
FunctionRegistration<?> registration = new FunctionRegistration<Object>(
|
||||
function, functionName);
|
||||
FunctionType functionType = this.findType(registration);
|
||||
return registration.type(functionType.getType());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void register(FunctionRegistration<T> functionRegistration) {
|
||||
Assert.notEmpty(functionRegistration.getNames(),
|
||||
"'registration' must contain at least one name before it is registered in catalog.");
|
||||
register(functionRegistration, functionRegistration.getNames().iterator().next());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Registers function wrapped by the provided FunctionRegistration with
|
||||
* this FunctionRegistry.
|
||||
@@ -236,16 +259,13 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
|
||||
}
|
||||
|
||||
protected FunctionType findType(FunctionRegistration<?> functionRegistration) {
|
||||
FunctionType functionType = functionRegistration.getType();
|
||||
if (functionType != null) {
|
||||
return functionType;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Unless FunctionType is already available in FunctionRegistration, "
|
||||
+ "this operation must be overriden "
|
||||
+ "by the implementation of the FunctionRegistry.");
|
||||
String name = this.lookupFunctionName(functionRegistration.getTarget());
|
||||
return functionRegistration.getType() != null
|
||||
? functionRegistration.getType()
|
||||
: this.getFunctionType(name);
|
||||
}
|
||||
|
||||
|
||||
protected void addSupplier(String name, Supplier<?> supplier) {
|
||||
this.suppliers.put(name, supplier);
|
||||
}
|
||||
@@ -327,8 +347,8 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
|
||||
}
|
||||
else if (composedFunction instanceof Supplier) {
|
||||
this.addSupplier(name, (Supplier<?>) composedFunction);
|
||||
|
||||
}
|
||||
// this.register(composedRegistration);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,14 +17,10 @@
|
||||
package org.springframework.cloud.function.context.catalog;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.cloud.function.context.FunctionRegistration;
|
||||
import org.springframework.cloud.function.context.FunctionType;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -34,72 +30,21 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class InMemoryFunctionCatalog extends AbstractComposableFunctionRegistry {
|
||||
|
||||
private final Map<Object, FunctionRegistration<?>> registrations;
|
||||
|
||||
public InMemoryFunctionCatalog() {
|
||||
this(Collections.emptySet());
|
||||
}
|
||||
|
||||
public InMemoryFunctionCatalog(Set<FunctionRegistration<?>> registrations) {
|
||||
Assert.notNull(registrations, "'registrations' must not be null");
|
||||
this.registrations = new HashMap<>();
|
||||
registrations.stream().forEach(reg -> register(reg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionRegistration<?> getRegistration(Object function) {
|
||||
return this.registrations.get(function);
|
||||
protected FunctionType findType(FunctionRegistration<?> functionRegistration) {
|
||||
FunctionType functionType = super.findType(functionRegistration);
|
||||
if (functionType == null) {
|
||||
functionType = new FunctionType(functionRegistration.getTarget().getClass());
|
||||
}
|
||||
return functionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void register(FunctionRegistration<T> functionRegistration) {
|
||||
Assert.notEmpty(functionRegistration.getNames(),
|
||||
"'registration' must contain at least one name before it is registered in catalog.");
|
||||
// TODO should we just delegate to wrap(..)????
|
||||
// wrap(functionRegistration, functionRegistration.getNames().iterator().next());
|
||||
Class<?> type = Object.class;
|
||||
if (functionRegistration.getTarget() instanceof Function) {
|
||||
type = Function.class;
|
||||
}
|
||||
else if (functionRegistration.getTarget() instanceof Supplier) {
|
||||
type = Supplier.class;
|
||||
}
|
||||
else if (functionRegistration.getTarget() instanceof Consumer) {
|
||||
type = Consumer.class;
|
||||
}
|
||||
FunctionRegistrationEvent event = new FunctionRegistrationEvent(this, type,
|
||||
functionRegistration.getNames());
|
||||
|
||||
this.registrations.put(functionRegistration.getTarget(), functionRegistration);
|
||||
FunctionRegistration<T> wrapped = functionRegistration.wrap();
|
||||
if (wrapped != functionRegistration) {
|
||||
functionRegistration = wrapped;
|
||||
this.registrations.put(wrapped.getTarget(), wrapped);
|
||||
if (type == Consumer.class) {
|
||||
type = Function.class;
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : functionRegistration.getNames()) {
|
||||
addType(name, functionRegistration.getType());
|
||||
addName(functionRegistration.getTarget(), name);
|
||||
if (functionRegistration.getTarget() instanceof Function) {
|
||||
this.addFunction(name, (Function<?, ?>) functionRegistration.getTarget());
|
||||
}
|
||||
else if (functionRegistration.getTarget() instanceof Consumer) {
|
||||
this.addConsumer(name, (Consumer<?>) functionRegistration.getTarget());
|
||||
}
|
||||
else {
|
||||
this.addSupplier(name, (Supplier<?>) functionRegistration.getTarget());
|
||||
}
|
||||
}
|
||||
this.publishEvent(event);
|
||||
}
|
||||
|
||||
private void publishEvent(Object event) {
|
||||
if (this.applicationEventPublisher != null) {
|
||||
this.applicationEventPublisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,8 +62,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.type.StandardMethodMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -93,26 +91,6 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public FunctionRegistration<?> getRegistration(Object function) {
|
||||
String functionName = function == null ? null
|
||||
: this.lookupFunctionName(function);
|
||||
if (StringUtils.hasText(functionName)) {
|
||||
FunctionRegistration<?> registration = new FunctionRegistration<Object>(
|
||||
function, functionName);
|
||||
FunctionType functionType = this.findType(registration);
|
||||
return registration.type(functionType.getType());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void register(FunctionRegistration<T> functionRegistration) {
|
||||
Assert.notEmpty(functionRegistration.getNames(),
|
||||
"'registration' must contain at least one name before it is registered in catalog.");
|
||||
register(functionRegistration, functionRegistration.getNames().iterator().next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Will collect all suppliers, functions, consumers and function registration as
|
||||
* late as possible in the lifecycle.
|
||||
@@ -160,13 +138,9 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
@Override
|
||||
protected FunctionType findType(FunctionRegistration<?> functionRegistration) {
|
||||
if (functionRegistration.getType() != null) {
|
||||
return functionRegistration.getType();
|
||||
}
|
||||
String name = this.lookupFunctionName(functionRegistration.getTarget());
|
||||
FunctionType functionType = this.getFunctionType(name);
|
||||
|
||||
FunctionType functionType = super.findType(functionRegistration);
|
||||
if (functionType == null) {
|
||||
String name = this.lookupFunctionName(functionRegistration.getTarget());
|
||||
functionType = functionByNameExist(name)
|
||||
? new FunctionType(functionRegistration.getTarget().getClass())
|
||||
: new FunctionType(
|
||||
|
||||
@@ -44,7 +44,7 @@ public class InMemoryFunctionCatalogTests {
|
||||
InMemoryFunctionCatalog catalog = new InMemoryFunctionCatalog();
|
||||
catalog.register(registration);
|
||||
FunctionRegistration<?> registration2 = catalog.getRegistration(function);
|
||||
assertThat(registration2).isSameAs(registration);
|
||||
assertThat(registration2.getType()).isEqualTo(registration.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -50,7 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class ContextFunctionCatalogInitializerTests {
|
||||
|
||||
@@ -163,7 +163,7 @@ public class ContextFunctionCatalogInitializerTests {
|
||||
assertThat(bean).isNotSameAs(function);
|
||||
assertThat(this.inspector.getRegistration(function)).isNotNull();
|
||||
assertThat(this.inspector.getRegistration(function).getType()).isEqualTo(
|
||||
FunctionType.from(String.class).to(String.class).wrap(Flux.class));
|
||||
FunctionType.from(String.class).to(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user