diff --git a/spring-cloud-function-compiler/pom.xml b/spring-cloud-function-compiler/pom.xml index 4e6d0fd9d..76f96ea9c 100644 --- a/spring-cloud-function-compiler/pom.xml +++ b/spring-cloud-function-compiler/pom.xml @@ -40,6 +40,10 @@ org.springframework.boot spring-boot-starter-logging + + org.springframework + spring-context + diff --git a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/support/LambdaCompilingFunction.java b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/LambdaCompilingFunction.java similarity index 97% rename from spring-cloud-function-core/src/main/java/org/springframework/cloud/function/support/LambdaCompilingFunction.java rename to spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/LambdaCompilingFunction.java index 5e01d1a7d..e730dfa2a 100644 --- a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/support/LambdaCompilingFunction.java +++ b/spring-cloud-function-compiler/src/main/java/org/springframework/cloud/function/compiler/LambdaCompilingFunction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.function.support; +package org.springframework.cloud.function.compiler; import java.io.InputStreamReader; import java.util.function.Function; diff --git a/spring-cloud-function-core/pom.xml b/spring-cloud-function-core/pom.xml index dd2917fdc..d55adbe58 100644 --- a/spring-cloud-function-core/pom.xml +++ b/spring-cloud-function-core/pom.xml @@ -22,15 +22,20 @@ org.springframework.boot spring-boot-starter - - org.springframework.cloud - spring-cloud-function-compiler - ${project.version} - org.springframework spring-context + + io.projectreactor + reactor-core + 3.0.4.RELEASE + + + commons-io + commons-io + 2.3 + org.springframework.boot spring-boot-starter-logging diff --git a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/gateway/LocalFunctionGateway.java b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/gateway/LocalFunctionGateway.java index 8275777d6..ed8e9e7e5 100644 --- a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/gateway/LocalFunctionGateway.java +++ b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/gateway/LocalFunctionGateway.java @@ -25,7 +25,7 @@ import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.springframework.cloud.function.invoker.FunctionInvokingRunnable; -import org.springframework.cloud.function.registry.FunctionRegistry; +import org.springframework.cloud.function.registry.FunctionCatalog; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.Trigger; import org.springframework.util.Assert; @@ -35,32 +35,32 @@ import org.springframework.util.Assert; */ public class LocalFunctionGateway implements FunctionGateway { - private final FunctionRegistry registry; + private final FunctionCatalog catalog; private final TaskScheduler scheduler; - public LocalFunctionGateway(FunctionRegistry registry, TaskScheduler scheduler) { - Assert.notNull(registry, "FunctionRegistry must not be null"); + public LocalFunctionGateway(FunctionCatalog catalog, TaskScheduler scheduler) { + Assert.notNull(catalog, "FunctionCatalog must not be null"); Assert.notNull(scheduler, "TaskScheduler must not be null"); - this.registry = registry; + this.catalog = catalog; this.scheduler = scheduler; } @Override public R invoke(String functionName, T request) { - Function function = this.registry.lookupFunction(functionName); + Function function = this.catalog.lookupFunction(functionName); return function.apply(request); } @Override public void schedule(String functionName, Trigger trigger, Supplier supplier, Consumer consumer) { - Function function = this.registry.lookupFunction(functionName); + Function function = this.catalog.lookupFunction(functionName); this.scheduler.schedule(new FunctionInvokingRunnable(supplier, function, consumer), trigger); } @Override public void subscribe(Publisher publisher, String functionName, final Consumer consumer) { - final Function function = this.registry.lookupFunction(functionName); + final Function function = this.catalog.lookupFunction(functionName); publisher.subscribe(new Subscriber() { @Override diff --git a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/AbstractFunctionRegistry.java b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/AbstractFunctionRegistry.java deleted file mode 100644 index 8a80aa2f0..000000000 --- a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/AbstractFunctionRegistry.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2016 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.registry; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -import org.springframework.cloud.function.compiler.CompiledFunctionFactory; -import org.springframework.cloud.function.compiler.ConsumerCompiler; -import org.springframework.cloud.function.compiler.ConsumerFactory; -import org.springframework.cloud.function.compiler.FunctionCompiler; -import org.springframework.cloud.function.compiler.FunctionFactory; -import org.springframework.cloud.function.compiler.SupplierCompiler; -import org.springframework.cloud.function.compiler.SupplierFactory; -import org.springframework.cloud.function.compiler.java.SimpleClassLoader; -import org.springframework.util.Assert; - -/** - * @author Mark Fisher - */ -public abstract class AbstractFunctionRegistry implements FunctionRegistry { - - private static final Map> CONSUMER_FACTORY_CACHE = new HashMap<>(); - - private static final Map> FUNCTION_FACTORY_CACHE = new HashMap<>(); - - private static final Map> SUPPLIER_FACTORY_CACHE = new HashMap<>(); - - private final ConsumerCompiler consumerCompiler = new ConsumerCompiler<>(); - - private final FunctionCompiler functionCompiler = new FunctionCompiler<>(); - - private final SupplierCompiler supplierCompiler = new SupplierCompiler<>(); - - private final SimpleClassLoader classLoader = new SimpleClassLoader(AbstractFunctionRegistry.class.getClassLoader()); - - @Override - public Consumer lookupConsumer(String name) { - @SuppressWarnings("unchecked") - ConsumerFactory factory = (ConsumerFactory) CONSUMER_FACTORY_CACHE.get(name); - if (factory != null) { - return factory.getResult(); - } - return this.doLookupConsumer(name); - } - - @Override - public final Function lookupFunction(String name) { - @SuppressWarnings("unchecked") - FunctionFactory factory = (FunctionFactory) FUNCTION_FACTORY_CACHE.get(name); - if (factory != null) { - return factory.getResult(); - } - return this.doLookupFunction(name); - } - - @Override - public Supplier lookupSupplier(String name) { - @SuppressWarnings("unchecked") - SupplierFactory factory = (SupplierFactory) SUPPLIER_FACTORY_CACHE.get(name); - if (factory != null) { - return factory.getResult(); - } - return this.doLookupSupplier(name); - } - - protected abstract Consumer doLookupConsumer(String name); - - protected abstract Function doLookupFunction(String name); - - protected abstract Supplier doLookupSupplier(String name); - - protected CompiledFunctionFactory> compileConsumer(String name, String code) { - return this.consumerCompiler.compile(name, code); - } - - protected CompiledFunctionFactory> compileFunction(String name, String code) { - return this.functionCompiler.compile(name, code); - } - - protected CompiledFunctionFactory> compileSupplier(String name, String code) { - return this.supplierCompiler.compile(name, code); - } - - @SuppressWarnings("unchecked") - protected Consumer deserializeConsumer(final String name, byte[] bytes) { - String className = formatClassName(name, Consumer.class); - Class factoryClass = this.classLoader.defineClass(className, bytes); - try { - ConsumerFactory factory = ((ConsumerFactory) factoryClass.newInstance()); - CONSUMER_FACTORY_CACHE.put(name, factory); - return factory.getResult(); - } - catch (InstantiationException | IllegalAccessException e) { - throw new IllegalArgumentException("failed to deserialize Consumer", e); - } - } - - @SuppressWarnings("unchecked") - protected Function deserializeFunction(final String name, byte[] bytes) { - String className = formatClassName(name, Function.class); - Class factoryClass = this.classLoader.defineClass(className, bytes); - try { - FunctionFactory factory = ((FunctionFactory) factoryClass.newInstance()); - FUNCTION_FACTORY_CACHE.put(name, factory); - return factory.getResult(); - } - catch (InstantiationException | IllegalAccessException e) { - throw new IllegalArgumentException("failed to deserialize Function", e); - } - } - - @SuppressWarnings("unchecked") - protected Supplier deserializeSupplier(final String name, byte[] bytes) { - String className = formatClassName(name, Supplier.class); - Class factoryClass = this.classLoader.defineClass(className, bytes); - try { - SupplierFactory factory = ((SupplierFactory) factoryClass.newInstance()); - SUPPLIER_FACTORY_CACHE.put(name, factory); - return factory.getResult(); - } - catch (InstantiationException | IllegalAccessException e) { - throw new IllegalArgumentException("failed to deserialize Supplier", e); - } - } - - private String formatClassName(String name, Class type) { - Assert.hasLength(name, "name must not be empty"); - String firstLetter = name.substring(0, 1).toUpperCase(); - String upperCasedName = (name.length() > 1) ? firstLetter + name.substring(1) : firstLetter; - return String.format("%s.%s%sFactory", FunctionCompiler.class.getPackage().getName(), upperCasedName, type.getSimpleName()); - } -} diff --git a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/FunctionRegistry.java b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/FunctionRegistry.java deleted file mode 100644 index e58e7639f..000000000 --- a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/FunctionRegistry.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016 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.registry; - -/** - * @author Mark Fisher - */ -public interface FunctionRegistry extends FunctionCatalog { - - void registerConsumer(String name, String consumer); - - void registerFunction(String name, String function); - - void registerSupplier(String name, String supplier); - -} diff --git a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/InMemoryFunctionRegistry.java b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/InMemoryFunctionRegistry.java deleted file mode 100644 index 1cdd6e4f7..000000000 --- a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/registry/InMemoryFunctionRegistry.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2016 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.registry; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * @author Mark Fisher - */ -public class InMemoryFunctionRegistry extends AbstractFunctionRegistry { - - private final ConcurrentHashMap> consumerMap = new ConcurrentHashMap<>(); - - private final ConcurrentHashMap> functionMap = new ConcurrentHashMap<>(); - - private final ConcurrentHashMap> supplierMap = new ConcurrentHashMap<>(); - - @Override - @SuppressWarnings("unchecked") - protected Consumer doLookupConsumer(String name) { - return this.consumerMap.get(name); - } - - @Override - @SuppressWarnings("unchecked") - public Function doLookupFunction(String name) { - return this.functionMap.get(name); - } - - @Override - @SuppressWarnings("unchecked") - protected Supplier doLookupSupplier(String name) { - return this.supplierMap.get(name); - } - - @Override - public void registerConsumer(String name, String consumer) { - this.consumerMap.put(name, this.compileConsumer(name, consumer).getResult()); - } - - @Override - public void registerFunction(String name, String function) { - this.functionMap.put(name, this.compileFunction(name, function).getResult()); - } - - @Override - public void registerSupplier(String name, String supplier) { - this.supplierMap.put(name, this.compileSupplier(name, supplier).getResult()); - } -} diff --git a/spring-cloud-function-core/src/test/java/org/springframework/cloud/function/gateway/LocalFunctionGatewayTests.java b/spring-cloud-function-core/src/test/java/org/springframework/cloud/function/gateway/LocalFunctionGatewayTests.java index 63091a99e..288b9c0ec 100644 --- a/spring-cloud-function-core/src/test/java/org/springframework/cloud/function/gateway/LocalFunctionGatewayTests.java +++ b/spring-cloud-function-core/src/test/java/org/springframework/cloud/function/gateway/LocalFunctionGatewayTests.java @@ -19,12 +19,14 @@ package org.springframework.cloud.function.gateway; import static org.junit.Assert.assertEquals; import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; import org.junit.Before; import org.junit.Test; -import org.springframework.cloud.function.registry.FunctionRegistry; -import org.springframework.cloud.function.registry.InMemoryFunctionRegistry; +import org.springframework.cloud.function.registry.FunctionCatalog; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import reactor.core.publisher.Flux; @@ -34,19 +36,35 @@ import reactor.core.publisher.Flux; */ public class LocalFunctionGatewayTests { - private final FunctionRegistry registry = new InMemoryFunctionRegistry(); + private final FunctionCatalog catalog = new FunctionCatalog() { + + @Override + public Supplier lookupSupplier(String name) { + return null; + } + + @Override + @SuppressWarnings("unchecked") + public Function, Flux> lookupFunction(String name) { + return ("uppercase".equals(name) ? f->f.map(s->s.toString().toUpperCase()) : null); + } + + @Override + public Consumer lookupConsumer(String name) { + return null; + } + }; private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); @Before public void init() { - registry.registerFunction("uppercase", "f->f.map(s->s.toString().toUpperCase())"); this.scheduler.initialize(); } @Test public void test() { - LocalFunctionGateway gateway = new LocalFunctionGateway(registry, scheduler); + LocalFunctionGateway gateway = new LocalFunctionGateway(catalog, scheduler); Flux output = gateway.invoke("uppercase", Flux.just("foo", "bar")); List results = output.collectList().block(); assertEquals("FOO", results.get(0)); diff --git a/spring-cloud-function-samples/spring-cloud-function-sample/pom.xml b/spring-cloud-function-samples/spring-cloud-function-sample/pom.xml index a740993aa..c2d277cc1 100644 --- a/spring-cloud-function-samples/spring-cloud-function-sample/pom.xml +++ b/spring-cloud-function-samples/spring-cloud-function-sample/pom.xml @@ -31,7 +31,7 @@ org.springframework.cloud - spring-cloud-function-context + spring-cloud-function-compiler ${spring-cloud-function.version} diff --git a/spring-cloud-function-samples/spring-cloud-function-sample/src/main/java/com/example/SampleApplication.java b/spring-cloud-function-samples/spring-cloud-function-sample/src/main/java/com/example/SampleApplication.java index 6c7c3ba28..d24f78aab 100644 --- a/spring-cloud-function-samples/spring-cloud-function-sample/src/main/java/com/example/SampleApplication.java +++ b/spring-cloud-function-samples/spring-cloud-function-sample/src/main/java/com/example/SampleApplication.java @@ -21,7 +21,7 @@ import java.util.function.Supplier; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.function.compiler.FunctionCompiler; -import org.springframework.cloud.function.support.LambdaCompilingFunction; +import org.springframework.cloud.function.compiler.LambdaCompilingFunction; import org.springframework.context.annotation.Bean; import org.springframework.core.io.ByteArrayResource; diff --git a/spring-cloud-function-web/pom.xml b/spring-cloud-function-web/pom.xml index 28c9ec8fd..b5a3b0bba 100644 --- a/spring-cloud-function-web/pom.xml +++ b/spring-cloud-function-web/pom.xml @@ -23,11 +23,6 @@ org.springframework.boot.experimental spring-boot-starter-web-reactive - - org.springframework.cloud - spring-cloud-function-core - ${project.version} - org.springframework.cloud spring-cloud-function-context diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java index ab4e16ade..262bf7d26 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java @@ -23,10 +23,6 @@ import java.util.List; import java.util.Map; import java.util.function.Function; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; - import org.apache.commons.io.Charsets; import org.reactivestreams.Publisher; @@ -44,6 +40,9 @@ import org.springframework.util.MimeType; import org.springframework.util.StreamUtils; import org.springframework.web.reactive.config.WebReactiveConfigurer; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; import reactor.core.publisher.Flux; /**