Turned on checkstyle
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
@@ -12,12 +13,13 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath />
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud-function.version>2.0.2.BUILD-SNAPSHOT</spring-cloud-function.version>
|
||||
<spring-cloud-function.version>2.0.2.BUILD-SNAPSHOT
|
||||
</spring-cloud-function.version>
|
||||
<wrapper.version>1.0.17.RELEASE</wrapper.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -18,26 +18,27 @@ package com.example.functions;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class FunctionApp {
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(FunctionApp.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<Flux<Foo>, Flux<Foo>> foos() {
|
||||
return flux -> flux.map(value -> new Foo(value.getValue().toUpperCase()));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(FunctionApp.class, args);
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
@@ -64,4 +65,4 @@ class Foo {
|
||||
return "Foo [value=" + this.value + "]";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
@@ -12,12 +13,13 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath />
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud-function.version>2.0.2.BUILD-SNAPSHOT</spring-cloud-function.version>
|
||||
<spring-cloud-function.version>2.0.2.BUILD-SNAPSHOT
|
||||
</spring-cloud-function.version>
|
||||
<wrapper.version>1.0.17.RELEASE</wrapper.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -24,4 +24,5 @@ public class DoubleLogger implements Consumer<Integer> {
|
||||
public void accept(Integer i) {
|
||||
System.out.println(2 * i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -25,10 +25,11 @@ public class Emitter implements Supplier<String> {
|
||||
|
||||
private int i = 0;
|
||||
|
||||
private String[] values = {"one", "two", "three", "four"};
|
||||
private String[] values = { "one", "two", "three", "four" };
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
return values[i++ % values.length];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -25,7 +25,11 @@ import org.springframework.context.annotation.Bean;
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class FunctionApp {
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(FunctionApp.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DoubleLogger myDoubler() {
|
||||
return new DoubleLogger();
|
||||
@@ -41,7 +45,4 @@ public class FunctionApp {
|
||||
return new LengthCounter();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(FunctionApp.class, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -27,4 +27,5 @@ public class LengthCounter implements Function<String, Integer> {
|
||||
public Integer apply(String string) {
|
||||
return string.length();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-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.
|
||||
@@ -45,13 +45,23 @@ import org.springframework.util.StringUtils;
|
||||
public class ApplicationBootstrap {
|
||||
|
||||
private static Log logger = LogFactory.getLog(ApplicationBootstrap.class);
|
||||
|
||||
private ApplicationRunner runner;
|
||||
|
||||
private URLClassLoader classLoader;
|
||||
|
||||
private static boolean isolated(String[] args) {
|
||||
for (String arg : args) {
|
||||
if (arg.equals("--function.runner.isolated=false")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the provided main class as a Spring Boot application with the provided command
|
||||
* line arguments.
|
||||
*
|
||||
* @param mainClass the main class
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
@@ -104,15 +114,6 @@ public class ApplicationBootstrap {
|
||||
return this.runner;
|
||||
}
|
||||
|
||||
private static boolean isolated(String[] args) {
|
||||
for (String arg : args) {
|
||||
if (arg.equals("--function.runner.isolated=false")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private URLClassLoader createClassLoader(Class<?> mainClass) {
|
||||
URL[] urls = findClassPath(mainClass);
|
||||
if (urls.length == 1) {
|
||||
@@ -141,7 +142,6 @@ public class ApplicationBootstrap {
|
||||
return new URLClassLoader(child.toArray(new URL[0]), base);
|
||||
}
|
||||
|
||||
|
||||
private URL[] findClassPath(Class<?> mainClass) {
|
||||
ClassLoader base = mainClass.getClassLoader();
|
||||
if (!(base instanceof URLClassLoader)) {
|
||||
@@ -200,4 +200,5 @@ public class ApplicationBootstrap {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-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.
|
||||
@@ -52,12 +52,12 @@ public class ApplicationRunner {
|
||||
|
||||
private final String source;
|
||||
|
||||
private StandardEvaluationContext app;
|
||||
|
||||
private final SpelParserConfiguration config;
|
||||
|
||||
private final StandardTypeLocator typeLocator;
|
||||
|
||||
private StandardEvaluationContext app;
|
||||
|
||||
public ApplicationRunner(ClassLoader classLoader, String source) {
|
||||
this.classLoader = classLoader;
|
||||
this.source = source;
|
||||
@@ -70,7 +70,8 @@ public class ApplicationRunner {
|
||||
try {
|
||||
ClassUtils.overrideThreadContextClassLoader(this.classLoader);
|
||||
Class<?> cls = this.classLoader.loadClass(ContextRunner.class.getName());
|
||||
this.app = new StandardEvaluationContext(cls.getDeclaredConstructor().newInstance());
|
||||
this.app = new StandardEvaluationContext(
|
||||
cls.getDeclaredConstructor().newInstance());
|
||||
this.app.setTypeLocator(new StandardTypeLocator(this.classLoader));
|
||||
runContext(this.source, defaultProperties(UUID.randomUUID().toString()),
|
||||
args);
|
||||
@@ -148,8 +149,8 @@ public class ApplicationRunner {
|
||||
}
|
||||
|
||||
/**
|
||||
* List the bean names in the application context for a given type (by its fully qualified name).
|
||||
*
|
||||
* List the bean names in the application context for a given type (by its fully
|
||||
* qualified name).
|
||||
* @param type the name of the type (Class)
|
||||
* @return the bean names of that type
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -32,17 +32,31 @@ import org.springframework.util.ReflectionUtils;
|
||||
/**
|
||||
* Utility class for starting a Spring Boot application in a separate thread. Best used
|
||||
* from an isolated class loader, e.g. through {@link ApplicationRunner}.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ContextRunner {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
private Thread runThread;
|
||||
|
||||
private volatile boolean running = false;
|
||||
|
||||
private Throwable error;
|
||||
|
||||
private long timeout = 120000;
|
||||
|
||||
private static boolean isFunctional(StandardEnvironment environment) {
|
||||
if (!ClassUtils.isPresent(
|
||||
"org.springframework.cloud.function.context.FunctionalSpringApplication",
|
||||
null)) {
|
||||
return false;
|
||||
}
|
||||
return environment.resolvePlaceholders("${spring.functional.enabled:true}")
|
||||
.equals("true");
|
||||
}
|
||||
|
||||
public void run(final String source, final Map<String, Object> properties,
|
||||
final String... args) {
|
||||
// Run in new thread to ensure that the context classloader is setup
|
||||
@@ -59,21 +73,21 @@ public class ContextRunner {
|
||||
environment.getPropertySources().addFirst(
|
||||
new SimpleCommandLinePropertySource("args", args));
|
||||
}
|
||||
running = true;
|
||||
ContextRunner.this.running = true;
|
||||
Class<?> sourceClass = ClassUtils.resolveClassName(source, null);
|
||||
SpringApplication builder = builder(sourceClass, environment);
|
||||
context = builder.run(args);
|
||||
ContextRunner.this.context = builder.run(args);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
error = ex;
|
||||
ContextRunner.this.error = ex;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
this.runThread.start();
|
||||
try {
|
||||
this.runThread.join(timeout);
|
||||
this.running = context != null && context.isRunning();
|
||||
this.runThread.join(this.timeout);
|
||||
this.running = this.context != null && this.context.isRunning();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
this.running = false;
|
||||
@@ -114,7 +128,7 @@ public class ContextRunner {
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
return this.running;
|
||||
}
|
||||
|
||||
public Throwable getError() {
|
||||
@@ -134,21 +148,12 @@ public class ContextRunner {
|
||||
return application;
|
||||
}
|
||||
|
||||
private static boolean isFunctional(StandardEnvironment environment) {
|
||||
if (!ClassUtils.isPresent(
|
||||
"org.springframework.cloud.function.context.FunctionalSpringApplication",
|
||||
null)) {
|
||||
return false;
|
||||
}
|
||||
return environment.resolvePlaceholders("${spring.functional.enabled:true}")
|
||||
.equals("true");
|
||||
}
|
||||
|
||||
private static class FunctionalSpringApplicationCreator {
|
||||
|
||||
public static SpringApplication create(Class<?> type) {
|
||||
return new FunctionalSpringApplication(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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.function.deployer;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -26,7 +27,6 @@ import org.springframework.context.annotation.Import;
|
||||
/**
|
||||
* Annotation to be used on a Spring Boot application if it wants to deploy a jar file
|
||||
* containing a function definition.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@@ -36,4 +36,4 @@ import org.springframework.context.annotation.Import;
|
||||
@Import(FunctionDeployerConfiguration.class)
|
||||
public @interface EnableFunctionDeployer {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
// @checkstyle:off
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Dave Syer
|
||||
@@ -33,3 +34,4 @@ public class FunctionApplication {
|
||||
}
|
||||
|
||||
}
|
||||
// @checkstyle:on
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-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.
|
||||
@@ -42,6 +42,7 @@ import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
@@ -112,24 +113,25 @@ class FunctionCreatorConfiguration {
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
URL[] urls = Arrays.stream(properties.getLocation())
|
||||
.flatMap(toResourceURL(delegatingResourceLoader)).toArray(URL[]::new);
|
||||
URL[] roots = Arrays.stream(properties.getLocation()).map(this::toUrl)
|
||||
URL[] urls = Arrays.stream(this.properties.getLocation())
|
||||
.flatMap(toResourceURL(this.delegatingResourceLoader))
|
||||
.toArray(URL[]::new);
|
||||
URL[] roots = Arrays.stream(this.properties.getLocation()).map(this::toUrl)
|
||||
.toArray(URL[]::new);
|
||||
|
||||
try {
|
||||
logger.info(
|
||||
"Locating function from " + Arrays.asList(properties.getLocation()));
|
||||
logger.info("Locating function from "
|
||||
+ Arrays.asList(this.properties.getLocation()));
|
||||
this.creator = new BeanCreator(roots, urls);
|
||||
this.creator.run(properties.getMain());
|
||||
this.creator.run(this.properties.getMain());
|
||||
Arrays.stream(functionNames()).map(this.creator::create).sequential()
|
||||
.forEach(this.creator::register);
|
||||
if (properties.getName().contains("|")) {
|
||||
if (this.properties.getName().contains("|")) {
|
||||
// A composite function has to be explicitly registered before it is
|
||||
// looked up because we are using the SingleEntryFunctionRegistry
|
||||
this.registry.lookup(Consumer.class, properties.getName());
|
||||
this.registry.lookup(Function.class, properties.getName());
|
||||
this.registry.lookup(Supplier.class, properties.getName());
|
||||
this.registry.lookup(Consumer.class, this.properties.getName());
|
||||
this.registry.lookup(Function.class, this.properties.getName());
|
||||
this.registry.lookup(Supplier.class, this.properties.getName());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -150,8 +152,8 @@ class FunctionCreatorConfiguration {
|
||||
}
|
||||
|
||||
private String[] functionNames() {
|
||||
if (properties.getBean() != null && properties.getBean().length > 0) {
|
||||
return properties.getBean();
|
||||
if (this.properties.getBean() != null && this.properties.getBean().length > 0) {
|
||||
return this.properties.getBean();
|
||||
}
|
||||
return this.creator.getFunctionNames();
|
||||
}
|
||||
@@ -207,9 +209,78 @@ class FunctionCreatorConfiguration {
|
||||
return urls.toArray(new URL[urls.size()]);
|
||||
}
|
||||
|
||||
private static final class BeanCreatorClassLoader extends URLClassLoader {
|
||||
|
||||
private BeanCreatorClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve)
|
||||
throws ClassNotFoundException {
|
||||
try {
|
||||
if (name.startsWith("javax.") && JavaVersion.getJavaVersion()
|
||||
.isEqualOrNewerThan(JavaVersion.NINE)) {
|
||||
return getClass().getClassLoader().loadClass(name);
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
if (name.contains(ContextRunner.class.getName())
|
||||
|| name.contains(PostConstruct.class.getName())) {
|
||||
// Special case for the ContextRunner. We can re-use the bytes for it,
|
||||
// and the function jar doesn't have to include them since it is only
|
||||
// used here.
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = StreamUtils.copyToByteArray(
|
||||
getClass().getClassLoader().getResourceAsStream(
|
||||
ClassUtils.convertClassNameToResourcePath(name)
|
||||
+ ".class"));
|
||||
return defineClass(name, bytes, 0, bytes.length);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new ClassNotFoundException(
|
||||
"Cannot find runner class: " + name, ex);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class SingleEntryConfiguration implements BeanPostProcessor {
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof FunctionRegistry) {
|
||||
String name = FunctionProperties
|
||||
.functionName(this.env.getProperty("function.bean", ""));
|
||||
if (name.contains("|")) {
|
||||
// A single composite function with an empty name
|
||||
bean = new SingleEntryFunctionRegistry((FunctionRegistry) bean, name);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ComputeLauncher extends JarLauncher {
|
||||
|
||||
public ComputeLauncher(Archive archive) {
|
||||
ComputeLauncher(Archive archive) {
|
||||
super(archive);
|
||||
}
|
||||
|
||||
@@ -220,9 +291,10 @@ class FunctionCreatorConfiguration {
|
||||
if (manifest != null) {
|
||||
String functionClass = manifest.getMainAttributes()
|
||||
.getValue("Function-Class");
|
||||
if (StringUtils.hasText(functionClass)
|
||||
&& ObjectUtils.isEmpty(properties.getBean())) {
|
||||
properties.setBean(new String[] { functionClass });
|
||||
if (StringUtils.hasText(functionClass) && ObjectUtils.isEmpty(
|
||||
FunctionCreatorConfiguration.this.properties.getBean())) {
|
||||
FunctionCreatorConfiguration.this.properties
|
||||
.setBean(new String[] { functionClass });
|
||||
}
|
||||
mainClass = manifest.getMainAttributes().getValue("Start-Class");
|
||||
if (mainClass == null
|
||||
@@ -287,6 +359,7 @@ class FunctionCreatorConfiguration {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,8 +376,9 @@ class FunctionCreatorConfiguration {
|
||||
|
||||
private String defaultMain;
|
||||
|
||||
public BeanCreator(URL[] roots, URL[] urls) {
|
||||
functionClassLoader = new BeanCreatorClassLoader(expand(urls), getParent());
|
||||
BeanCreator(URL[] roots, URL[] urls) {
|
||||
FunctionCreatorConfiguration.this.functionClassLoader = new BeanCreatorClassLoader(
|
||||
expand(urls), getParent());
|
||||
this.defaultMain = findMain(roots);
|
||||
}
|
||||
|
||||
@@ -329,8 +403,7 @@ class FunctionCreatorConfiguration {
|
||||
File file = ResourceUtils.getFile(url);
|
||||
if (file.exists()) {
|
||||
Archive archive = file.getName().endsWith(".jar")
|
||||
? new JarFileArchive(file)
|
||||
: new ExplodedArchive(file);
|
||||
? new JarFileArchive(file) : new ExplodedArchive(file);
|
||||
String main = new ComputeLauncher(archive).getMainClass();
|
||||
if (main != null) {
|
||||
return main;
|
||||
@@ -388,13 +461,14 @@ class FunctionCreatorConfiguration {
|
||||
return;
|
||||
}
|
||||
if (ClassUtils.isPresent(SpringApplication.class.getName(),
|
||||
functionClassLoader)) {
|
||||
FunctionCreatorConfiguration.this.functionClassLoader)) {
|
||||
logger.info("SpringApplication available. Bootstrapping: " + main);
|
||||
ClassLoader contextClassLoader = ClassUtils
|
||||
.overrideThreadContextClassLoader(functionClassLoader);
|
||||
.overrideThreadContextClassLoader(
|
||||
FunctionCreatorConfiguration.this.functionClassLoader);
|
||||
try {
|
||||
ApplicationRunner runner = new ApplicationRunner(functionClassLoader,
|
||||
main);
|
||||
ApplicationRunner runner = new ApplicationRunner(
|
||||
FunctionCreatorConfiguration.this.functionClassLoader, main);
|
||||
// TODO: make the runtime properties configurable
|
||||
runner.run("--spring.main.webEnvironment=false",
|
||||
"--spring.cloud.stream.enabled=false",
|
||||
@@ -416,8 +490,8 @@ class FunctionCreatorConfiguration {
|
||||
|
||||
public String[] getFunctionNames() {
|
||||
Set<String> list = new LinkedHashSet<>();
|
||||
ClassLoader contextClassLoader = ClassUtils
|
||||
.overrideThreadContextClassLoader(functionClassLoader);
|
||||
ClassLoader contextClassLoader = ClassUtils.overrideThreadContextClassLoader(
|
||||
FunctionCreatorConfiguration.this.functionClassLoader);
|
||||
try {
|
||||
if (this.runner.containsBean(FunctionCatalog.class.getName())) {
|
||||
Object catalog = this.runner.getBean(FunctionCatalog.class.getName());
|
||||
@@ -447,9 +521,10 @@ class FunctionCreatorConfiguration {
|
||||
}
|
||||
|
||||
public Object create(String type) {
|
||||
ClassLoader contextClassLoader = ClassUtils
|
||||
.overrideThreadContextClassLoader(functionClassLoader);
|
||||
AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
|
||||
ClassLoader contextClassLoader = ClassUtils.overrideThreadContextClassLoader(
|
||||
FunctionCreatorConfiguration.this.functionClassLoader);
|
||||
AutowireCapableBeanFactory factory = FunctionCreatorConfiguration.this.context
|
||||
.getAutowireCapableBeanFactory();
|
||||
try {
|
||||
Object result = null;
|
||||
if (this.runner != null) {
|
||||
@@ -483,9 +558,10 @@ class FunctionCreatorConfiguration {
|
||||
}
|
||||
if (result == null) {
|
||||
logger.info("No bean found. Instantiating: " + type);
|
||||
if (ClassUtils.isPresent(type, functionClassLoader)) {
|
||||
result = factory.createBean(
|
||||
ClassUtils.resolveClassName(type, functionClassLoader));
|
||||
if (ClassUtils.isPresent(type,
|
||||
FunctionCreatorConfiguration.this.functionClassLoader)) {
|
||||
result = factory.createBean(ClassUtils.resolveClassName(type,
|
||||
FunctionCreatorConfiguration.this.functionClassLoader));
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
@@ -503,7 +579,8 @@ class FunctionCreatorConfiguration {
|
||||
return;
|
||||
}
|
||||
FunctionRegistration<Object> registration = new FunctionRegistration<Object>(
|
||||
bean, FunctionProperties.functionName(counter.getAndIncrement()));
|
||||
bean,
|
||||
FunctionProperties.functionName(this.counter.getAndIncrement()));
|
||||
if (this.runner != null) {
|
||||
if (this.runner.containsBean(FunctionInspector.class.getName())) {
|
||||
Object inspector = this.runner
|
||||
@@ -533,7 +610,7 @@ class FunctionCreatorConfiguration {
|
||||
registration.type(FunctionType.of(bean.getClass()).getType());
|
||||
}
|
||||
registration.target(bean);
|
||||
registry.register(registration);
|
||||
FunctionCreatorConfiguration.this.registry.register(registration);
|
||||
}
|
||||
|
||||
private Class<?> findType(String method, Object inspector, Object bean) {
|
||||
@@ -549,69 +626,4 @@ class FunctionCreatorConfiguration {
|
||||
|
||||
}
|
||||
|
||||
private static final class BeanCreatorClassLoader extends URLClassLoader {
|
||||
private BeanCreatorClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve)
|
||||
throws ClassNotFoundException {
|
||||
try {
|
||||
if (name.startsWith("javax.") && JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.NINE)) {
|
||||
return getClass().getClassLoader().loadClass(name);
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
if (name.contains(ContextRunner.class.getName())
|
||||
|| name.contains(PostConstruct.class.getName())) {
|
||||
// Special case for the ContextRunner. We can re-use the bytes for it,
|
||||
// and the function jar doesn't have to include them since it is only
|
||||
// used here.
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = StreamUtils.copyToByteArray(
|
||||
getClass().getClassLoader().getResourceAsStream(
|
||||
ClassUtils.convertClassNameToResourcePath(name)
|
||||
+ ".class"));
|
||||
return defineClass(name, bytes, 0, bytes.length);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new ClassNotFoundException(
|
||||
"Cannot find runner class: " + name, ex);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class SingleEntryConfiguration implements BeanPostProcessor {
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (bean instanceof FunctionRegistry) {
|
||||
String name = FunctionProperties
|
||||
.functionName(env.getProperty("function.bean", ""));
|
||||
if (name.contains("|")) {
|
||||
// A single composite function with an empty name
|
||||
bean = new SingleEntryFunctionRegistry((FunctionRegistry) bean, name);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.deployer;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -42,38 +42,10 @@ public class FunctionProperties {
|
||||
private String[] bean = new String[0];
|
||||
|
||||
/**
|
||||
* Optional main class from which to build a Spring application context
|
||||
* Optional main class from which to build a Spring application context.
|
||||
*/
|
||||
private String main;
|
||||
|
||||
public String getName() {
|
||||
return functionName(StringUtils.arrayToDelimitedString(bean, ","));
|
||||
}
|
||||
|
||||
public String[] getBean() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setBean(String[] bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public String[] getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String[] location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getMain() {
|
||||
return main;
|
||||
}
|
||||
|
||||
public void setMain(String main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
public static String functionName(String name) {
|
||||
if (!name.contains(",")) {
|
||||
return "function0";
|
||||
@@ -89,11 +61,40 @@ public class FunctionProperties {
|
||||
return "function" + value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return functionName(StringUtils.arrayToDelimitedString(this.bean, ","));
|
||||
}
|
||||
|
||||
public String[] getBean() {
|
||||
return this.bean;
|
||||
}
|
||||
|
||||
public void setBean(String[] bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public String[] getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public void setLocation(String[] location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getMain() {
|
||||
return this.main;
|
||||
}
|
||||
|
||||
public void setMain(String main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (location.length == 0) {
|
||||
if (this.location.length == 0) {
|
||||
throw new IllegalStateException(
|
||||
"No archive location provided, please configure function.location as a jar or directory.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.deployer;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -40,12 +41,13 @@ public class SingleEntryFunctionRegistry implements FunctionRegistry {
|
||||
@Override
|
||||
public <T> T lookup(Class<?> type, String name) {
|
||||
if (StringUtils.isEmpty(name)) {
|
||||
if (delegate.getNames(type).size() == 1) {
|
||||
return delegate.lookup(type, delegate.getNames(type).iterator().next());
|
||||
if (this.delegate.getNames(type).size() == 1) {
|
||||
return this.delegate.lookup(type,
|
||||
this.delegate.getNames(type).iterator().next());
|
||||
}
|
||||
name = this.name;
|
||||
}
|
||||
return name.equals(this.name) ? delegate.lookup(type, name) : null;
|
||||
return name.equals(this.name) ? this.delegate.lookup(type, name) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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 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.
|
||||
@@ -52,4 +52,5 @@ public class ApplicationRunnerTests {
|
||||
assertThat(runner.getBeanNames(FunctionRegistration.class.getName())).hasSize(2);
|
||||
runner.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -37,4 +37,5 @@ public class ContextRunnerTests {
|
||||
assertThat(runner.getContext()).isNotNull();
|
||||
runner.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2018 the original author or authors.
|
||||
* Copyright 2012-2019-2018 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,6 +22,8 @@ import java.util.function.Supplier;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -35,9 +37,6 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = { FunctionDeployerConfiguration.class })
|
||||
@DirtiesContext
|
||||
@@ -53,10 +52,11 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testDouble() {
|
||||
Function<Flux<Integer>, Flux<Integer>> function = catalog
|
||||
Function<Flux<Integer>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -68,10 +68,11 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testDouble() {
|
||||
Function<Flux<Integer>, Flux<Integer>> function = catalog
|
||||
Function<Flux<Integer>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -84,10 +85,11 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testDouble() {
|
||||
Function<Flux<Integer>, Flux<Integer>> function = catalog
|
||||
Function<Flux<Integer>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -100,7 +102,7 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testDouble() {
|
||||
Function<Flux<Integer>, Flux<Integer>> function = catalog
|
||||
Function<Flux<Integer>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
@@ -117,10 +119,11 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testFrenchize() {
|
||||
Function<Flux<Integer>, Flux<String>> function = catalog
|
||||
Function<Flux<Integer>, Flux<String>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo("deux");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -133,10 +136,11 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testDouble() {
|
||||
Function<Flux<Integer>, Flux<Integer>> function = catalog
|
||||
Function<Flux<Integer>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -147,10 +151,11 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testDouble() {
|
||||
Function<Flux<Integer>, Flux<Integer>> function = catalog
|
||||
Function<Flux<Integer>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -162,13 +167,13 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testSupplier() {
|
||||
Supplier<Integer> function = catalog.lookup(Supplier.class, "function0");
|
||||
Supplier<Integer> function = this.catalog.lookup(Supplier.class, "function0");
|
||||
assertThat(function).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunction() {
|
||||
Supplier<Flux<String>> function = catalog.lookup(Supplier.class,
|
||||
Supplier<Flux<String>> function = this.catalog.lookup(Supplier.class,
|
||||
"function0|function1");
|
||||
assertThat(function.get().blockFirst()).isEqualTo("un");
|
||||
}
|
||||
@@ -184,17 +189,18 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testFunction() {
|
||||
Function<Flux<Integer>, Flux<String>> function = catalog
|
||||
Function<Flux<Integer>, Flux<String>> function = this.catalog
|
||||
.lookup(Function.class, "function0|function1");
|
||||
assertThat(function.apply(Flux.just(2)).blockFirst()).isEqualTo("quatre");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThen() {
|
||||
Function<Integer, String> function = catalog.lookup(Function.class,
|
||||
Function<Integer, String> function = this.catalog.lookup(Function.class,
|
||||
"function1");
|
||||
assertThat(function).isNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -209,10 +215,12 @@ public abstract class FunctionCreatorConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testConsumer() {
|
||||
Function<Flux<Integer>, Mono<Void>> function = catalog.lookup(Function.class,
|
||||
"function0|function1");
|
||||
Function<Flux<Integer>, Mono<Void>> function = this.catalog
|
||||
.lookup(Function.class, "function0|function1");
|
||||
function.apply(Flux.just(2)).block();
|
||||
capture.expect(containsString("Seen deux"));
|
||||
this.capture.expect(containsString("Seen deux"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -34,33 +34,33 @@ public class SingleEntryFunctionRegistryTests {
|
||||
|
||||
@Test
|
||||
public void named() {
|
||||
delegate.register(new FunctionRegistration<Foos>(new Foos(), "foo"));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(delegate,
|
||||
"foo");
|
||||
this.delegate.register(new FunctionRegistration<Foos>(new Foos(), "foo"));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(
|
||||
this.delegate, "foo");
|
||||
assertThat((Foos) registry.lookup("foo")).isInstanceOf(Function.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void other() {
|
||||
delegate.register(new FunctionRegistration<Foos>(new Foos(), "foo"));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(delegate,
|
||||
"foo");
|
||||
this.delegate.register(new FunctionRegistration<Foos>(new Foos(), "foo"));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(
|
||||
this.delegate, "foo");
|
||||
assertThat((Foos) registry.lookup("bar")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void empty() {
|
||||
delegate.register(new FunctionRegistration<Foos>(new Foos(), ""));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(delegate,
|
||||
"");
|
||||
this.delegate.register(new FunctionRegistration<Foos>(new Foos(), ""));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(
|
||||
this.delegate, "");
|
||||
assertThat((Foos) registry.lookup("")).isInstanceOf(Function.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anonymous() {
|
||||
delegate.register(new FunctionRegistration<Foos>(new Foos(), "bar"));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(delegate,
|
||||
"foo");
|
||||
this.delegate.register(new FunctionRegistration<Foos>(new Foos(), "bar"));
|
||||
SingleEntryFunctionRegistry registry = new SingleEntryFunctionRegistry(
|
||||
this.delegate, "foo");
|
||||
assertThat((Foos) registry.lookup("")).isInstanceOf(Function.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -22,6 +22,8 @@ import java.util.function.Supplier;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -34,9 +36,6 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = FunctionDeployerConfiguration.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@TestPropertySource(properties = {
|
||||
@@ -53,7 +52,8 @@ public abstract class SpringFunctionAppConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Supplier<Flux<String>> function = catalog.lookup(Supplier.class, "function0");
|
||||
Supplier<Flux<String>> function = this.catalog.lookup(Supplier.class,
|
||||
"function0");
|
||||
assertThat(function.get().blockFirst()).isEqualTo("one");
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public abstract class SpringFunctionAppConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Supplier<Flux<Integer>> function = catalog.lookup(Supplier.class,
|
||||
Supplier<Flux<Integer>> function = this.catalog.lookup(Supplier.class,
|
||||
"function0|function1");
|
||||
assertThat(function.get().blockFirst()).isEqualTo(3);
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public abstract class SpringFunctionAppConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Function<Flux<String>, Flux<Integer>> function = catalog
|
||||
Function<Flux<String>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just("spam")).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
@@ -95,12 +95,12 @@ public abstract class SpringFunctionAppConfigurationTests {
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
// Can't assert side effects.
|
||||
Function<Flux<Integer>, Mono<Void>> function = catalog.lookup(Function.class,
|
||||
"function0");
|
||||
Function<Flux<Integer>, Mono<Void>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
function.apply(Flux.just(5)).block();
|
||||
capture.expect(containsString(String.format("10%n")));
|
||||
this.capture.expect(containsString(String.format("10%n")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -22,6 +22,8 @@ import java.util.function.Supplier;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -34,9 +36,6 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = FunctionDeployerConfiguration.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@TestPropertySource(properties = {
|
||||
@@ -53,7 +52,8 @@ public abstract class SpringFunctionAppExplodedConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Supplier<Flux<String>> function = catalog.lookup(Supplier.class, "function0");
|
||||
Supplier<Flux<String>> function = this.catalog.lookup(Supplier.class,
|
||||
"function0");
|
||||
assertThat(function.get().blockFirst()).isEqualTo("one");
|
||||
}
|
||||
|
||||
@@ -61,11 +61,12 @@ public abstract class SpringFunctionAppExplodedConfigurationTests {
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@TestPropertySource(properties = { "function.bean=myEmitter,myCounter" })
|
||||
public static class CompositeTests extends SpringFunctionAppExplodedConfigurationTests {
|
||||
public static class CompositeTests
|
||||
extends SpringFunctionAppExplodedConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Supplier<Flux<Integer>> function = catalog.lookup(Supplier.class,
|
||||
Supplier<Flux<Integer>> function = this.catalog.lookup(Supplier.class,
|
||||
"function0|function1");
|
||||
assertThat(function.get().blockFirst()).isEqualTo(3);
|
||||
}
|
||||
@@ -74,11 +75,12 @@ public abstract class SpringFunctionAppExplodedConfigurationTests {
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@TestPropertySource(properties = { "function.bean=myCounter" })
|
||||
public static class ProcessorTests extends SpringFunctionAppExplodedConfigurationTests {
|
||||
public static class ProcessorTests
|
||||
extends SpringFunctionAppExplodedConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Function<Flux<String>, Flux<Integer>> function = catalog
|
||||
Function<Flux<String>, Flux<Integer>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
assertThat(function.apply(Flux.just("spam")).blockFirst()).isEqualTo(4);
|
||||
}
|
||||
@@ -95,12 +97,12 @@ public abstract class SpringFunctionAppExplodedConfigurationTests {
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
// Can't assert side effects.
|
||||
Function<Flux<Integer>, Mono<Void>> function = catalog.lookup(Function.class,
|
||||
"function0");
|
||||
Function<Flux<Integer>, Mono<Void>> function = this.catalog
|
||||
.lookup(Function.class, "function0");
|
||||
function.apply(Flux.just(5)).block();
|
||||
capture.expect(containsString(String.format("10%n")));
|
||||
this.capture.expect(containsString(String.format("10%n")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-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.
|
||||
@@ -44,39 +44,42 @@ public class SpringFunctionFluxConfigurationTests {
|
||||
|
||||
@Before
|
||||
public void run() {
|
||||
if (bootstrap == null) {
|
||||
bootstrap = new ApplicationBootstrap();
|
||||
bootstrap.run(SpringFunctionFluxConfigurationTests.class,
|
||||
if (this.bootstrap == null) {
|
||||
this.bootstrap = new ApplicationBootstrap();
|
||||
this.bootstrap.run(SpringFunctionFluxConfigurationTests.class,
|
||||
"--function.location=file:target/it/flux/target/dependency",
|
||||
"--function.bean=foos",
|
||||
"--function.main=com.example.functions.FunctionApp");
|
||||
catalog = bootstrap.getRunner().getBean(FunctionCatalog.class.getName());
|
||||
inspector = bootstrap.getRunner().getBean(FunctionInspector.class.getName());
|
||||
this.catalog = this.bootstrap.getRunner()
|
||||
.getBean(FunctionCatalog.class.getName());
|
||||
this.inspector = this.bootstrap.getRunner()
|
||||
.getBean(FunctionInspector.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (bootstrap != null) {
|
||||
bootstrap.close();
|
||||
if (this.bootstrap != null) {
|
||||
this.bootstrap.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<Object, Object> function = (Function<Object, Object>) bootstrap
|
||||
Function<Object, Object> function = (Function<Object, Object>) this.bootstrap
|
||||
.getRunner()
|
||||
.evaluate("lookup(T(java.util.function.Function), 'function0')", catalog);
|
||||
.evaluate("lookup(T(java.util.function.Function), 'function0')",
|
||||
this.catalog);
|
||||
assertThat(function).isNotNull();
|
||||
Class<?> inputType = (Class<?>) bootstrap.getRunner()
|
||||
.evaluate("getInputType(#function)", inspector, "function", function);
|
||||
Class<?> inputType = (Class<?>) this.bootstrap.getRunner().evaluate(
|
||||
"getInputType(#function)", this.inspector, "function", function);
|
||||
assertThat(inputType.getName()).isEqualTo("com.example.functions.Foo");
|
||||
Object foo = create(inputType);
|
||||
Class<?> outputType = (Class<?>) bootstrap.getRunner()
|
||||
.evaluate("getOutputType(#function)", inspector, "function", function);
|
||||
Class<?> outputType = (Class<?>) this.bootstrap.getRunner().evaluate(
|
||||
"getOutputType(#function)", this.inspector, "function", function);
|
||||
assertThat(outputType.getName()).isEqualTo("com.example.functions.Foo");
|
||||
String value = (String) bootstrap.getRunner().evaluate(
|
||||
String value = (String) this.bootstrap.getRunner().evaluate(
|
||||
"apply(T(reactor.core.publisher.Flux).just(#foo)).blockFirst().getValue()",
|
||||
function, "foo", foo);
|
||||
assertThat(value).isEqualTo("FOO");
|
||||
@@ -115,4 +118,4 @@ class Foo {
|
||||
return "Foo [value=" + this.value + "]";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -19,8 +19,10 @@ package org.springframework.cloud.function.test;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Doubler implements Function<Integer, Integer> {
|
||||
|
||||
@Override
|
||||
public Integer apply(Integer integer) {
|
||||
return 2 * integer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -27,10 +27,10 @@ public class Frenchizer implements Function<Integer, String> {
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.numbers = new String[4];
|
||||
numbers[0] = "un";
|
||||
numbers[1] = "deux";
|
||||
numbers[2] = "trois";
|
||||
numbers[3] = "quatre";
|
||||
this.numbers[0] = "un";
|
||||
this.numbers[1] = "deux";
|
||||
this.numbers[2] = "trois";
|
||||
this.numbers[3] = "quatre";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,4 +40,5 @@ public class Frenchizer implements Function<Integer, String> {
|
||||
}
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -26,6 +26,10 @@ import org.springframework.context.annotation.Bean;
|
||||
@SpringBootConfiguration
|
||||
public class FunctionApp {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(FunctionApp.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Doubler myDoubler() {
|
||||
return new Doubler();
|
||||
@@ -36,7 +40,4 @@ public class FunctionApp {
|
||||
return new Frenchizer();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(FunctionApp.class, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -28,6 +28,12 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||
public class FunctionInitializer
|
||||
implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication application = new FunctionalSpringApplication(
|
||||
FunctionInitializer.class);
|
||||
application.run(args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Doubler myDoubler() {
|
||||
return new Doubler();
|
||||
@@ -38,16 +44,11 @@ public class FunctionInitializer
|
||||
return new Frenchizer();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication application = new FunctionalSpringApplication(
|
||||
FunctionInitializer.class);
|
||||
application.run(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(GenericApplicationContext context) {
|
||||
// TODO: support for FunctionRegistration
|
||||
context.registerBean("myDoubler", Doubler.class, () -> myDoubler());
|
||||
context.registerBean("myFrenchizer", Frenchizer.class, () -> myFrenchizer());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -30,6 +30,12 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||
public class FunctionRegistrar
|
||||
implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication application = new FunctionalSpringApplication(
|
||||
FunctionRegistrar.class);
|
||||
application.run(args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Doubler myDoubler() {
|
||||
return new Doubler();
|
||||
@@ -40,12 +46,6 @@ public class FunctionRegistrar
|
||||
return new Frenchizer();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication application = new FunctionalSpringApplication(
|
||||
FunctionRegistrar.class);
|
||||
application.run(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(GenericApplicationContext context) {
|
||||
context.registerBean("theDoubler", FunctionRegistration.class,
|
||||
@@ -58,4 +58,5 @@ public class FunctionRegistrar
|
||||
.type(FunctionType.of((Frenchizer.class)));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -19,8 +19,10 @@ package org.springframework.cloud.function.test;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class NumberEmitter implements Supplier<Integer> {
|
||||
|
||||
@Override
|
||||
public Integer get() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -24,4 +24,5 @@ public class Printer implements Consumer<Object> {
|
||||
public void accept(Object o) {
|
||||
System.err.println("Seen " + o);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
@@ -35,15 +35,16 @@ public class SpringDoubler implements Function<Integer, Integer> {
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (this.context == null) {
|
||||
context = new SpringApplicationBuilder(FunctionApp.class).bannerMode(Mode.OFF).registerShutdownHook(false)
|
||||
this.context = new SpringApplicationBuilder(FunctionApp.class)
|
||||
.bannerMode(Mode.OFF).registerShutdownHook(false)
|
||||
.web(WebApplicationType.NONE).run();
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,4 +52,5 @@ public class SpringDoubler implements Function<Integer, Integer> {
|
||||
public Integer apply(Integer integer) {
|
||||
return 2 * integer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user