Add support for detecting FunctionRegistration or Function

User can now provide a Function or an ApplicationInitializer. Also
the initializer can create a FunctionRegistration with the handler
name instead of a bean with the handler name. Better control of
input and output types that way.

Fixes gh-231
This commit is contained in:
Dave Syer
2018-11-09 12:35:36 +00:00
parent d1b9a9b3fb
commit aba50816f7
10 changed files with 281 additions and 63 deletions

View File

@@ -18,13 +18,10 @@ package org.springframework.cloud.function.deployer;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.cloud.function.context.FunctionalSpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.StandardEnvironment;
@@ -59,16 +56,7 @@ public class ContextRunner {
new MapPropertySource("appDeployer", properties));
running = true;
Class<?> sourceClass = ClassUtils.resolveClassName(source, null);
ApplicationContextInitializer<?> initializer = null;
if (ApplicationContextInitializer.class.isAssignableFrom(sourceClass)) {
initializer = BeanUtils.instantiateClass(sourceClass, ApplicationContextInitializer.class);
sourceClass = Dummy.class;
}
SpringApplication builder = builder(sourceClass);
if (initializer!=null) {
builder.addInitializers(initializer);
builder.setDefaultProperties(Collections.singletonMap("spring.functional.enabled", "true"));
}
builder.setEnvironment(environment);
builder.setRegisterShutdownHook(false);
context = builder.run(args);
@@ -131,19 +119,8 @@ public class ContextRunner {
}
private static SpringApplication builder(Class<?> type) {
if (type==Dummy.class) {
SpringApplication application = new SpringApplication() {
@Override
protected void load(ApplicationContext context, Object[] sources) {
}
};
// Boot doesn't allow null sources
application.setSources(Collections.singleton(Dummy.class.getName()));
return application;
}
return new SpringApplication(type);
SpringApplication application = new FunctionalSpringApplication(type);
return application;
}
private class Dummy {}
}

View File

@@ -51,10 +51,12 @@ import org.springframework.boot.loader.archive.Archive;
import org.springframework.boot.loader.archive.ExplodedArchive;
import org.springframework.boot.loader.archive.JarFileArchive;
import org.springframework.cloud.deployer.resource.support.DelegatingResourceLoader;
import org.springframework.cloud.function.context.FunctionCatalog;
import org.springframework.cloud.function.context.FunctionRegistration;
import org.springframework.cloud.function.context.FunctionRegistry;
import org.springframework.cloud.function.context.FunctionType;
import org.springframework.cloud.function.context.catalog.FunctionInspector;
import org.springframework.cloud.function.core.FluxFunction;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@@ -381,6 +383,32 @@ class FunctionCreatorConfiguration {
Object result = null;
if (this.runner != null) {
result = this.runner.getBean(type);
if (result == null) {
if (this.runner.containsBean(FunctionCatalog.class.getName())) {
Object catalog = this.runner
.getBean(FunctionCatalog.class.getName());
result = this.runner.evaluate("lookup(#function).getTarget()",
catalog, "function", type);
if (result != null) {
logger.info("Located registration: " + type + " of type "
+ result.getClass());
}
}
}
else {
logger.info("Located bean: " + type + " of type "
+ result.getClass());
if (result.getClass().getName()
.equals(FunctionRegistration.class.getName())) {
result = this.runner.evaluate("getTarget()", result);
}
}
if (result != null) {
if (result.getClass().getName()
.equals(FluxFunction.class.getName())) {
result = this.runner.evaluate("getTarget()", result);
}
}
}
if (result == null) {
logger.info("No bean found. Instantiating: " + type);
@@ -390,7 +418,6 @@ class FunctionCreatorConfiguration {
}
}
if (result != null) {
logger.info("Located bean: " + type);
return result;
}
throw new IllegalStateException("Cannot create bean for: " + type);