Refactor deployer app so that it starts empty
Functions are namespaced under the "app name", e.g. /sample/uppercase is the "uppercase" function in the "sample" app. Also added a README to get started quickly.
This commit is contained in:
56
spring-cloud-function-deployer/README.md
Normal file
56
spring-cloud-function-deployer/README.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
Spring Cloud Function Deployer is an app that can deploy functions packaged as jars. Once the app is running it can deploy a basic Spring Cloud Function app from a jar with locally cached dependencies in about 500ms (compared to 1500ms for the same application launched from cold). It can be used in a pool as a "warm" JVM to deploy functions quicker than they could be started from scratch.
|
||||||
|
|
||||||
|
The app has a single endpoint called "/admin" that you can use to manage the deployed functions. You GET from it to list the deployed apps, POST to `/{name}` to deploy a named app with a `path` parameter pointing to a jar resource, and then DELETE `/{name}` to remove it. Functions in the apps are exposed as `/{name}/{function}` with the usual conventions for Spring Cloud Function (i.e. the function name is the bean name by default).
|
||||||
|
|
||||||
|
== Running the Deployer
|
||||||
|
|
||||||
|
Run the main class `ApplicationRunner` in this project (from the command line or in the IDE). E.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./mvnw install -DskipTests
|
||||||
|
$ cd spring-cloud-function-deployer
|
||||||
|
$ ../mvnw spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
The app starts empty, so the admin resource shows no deployed apps:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl localhost:8080/admin
|
||||||
|
{}
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy a sample like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl localhost:8080/admin/pojos -d path=maven://com.example:function-sample-pojo:1.0.0.BUILD-SNAPSHOT
|
||||||
|
{"id":"81c568e36c7909ec1dd841aa7ee6d3e3"}
|
||||||
|
```
|
||||||
|
|
||||||
|
(takes about 500ms, once the local Maven cache is warm). Deploy another one:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl localhost:8080/admin/sample -d path=maven://com.example:function-sample:1.0.0.BUILD-SNAPSHOT
|
||||||
|
{"id":"cb2fdb3130f6349f143f4686848ea90f"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Undeploy the first one:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl localhost:8080/admin/pojos -X DELETE
|
||||||
|
{"name":"81c568e36c7909ec1dd841aa7ee6d3e3","id":"pojos","path":"maven://com.example:function-sample-pojo:1.0.0.BUILD-SNAPSHOT"}
|
||||||
|
```
|
||||||
|
|
||||||
|
List the deployed apps:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl localhost:8080/admin
|
||||||
|
{"sample":{"name":"sample","id":"cb2fdb3130f6349f143f4686848ea90","path":"maven://com.example:function-sample:1.0.0.BUILD-SNAPSHOT"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Send an event to one of the functions:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl -H "Content-Type: text/plain" localhost:8080/sample/uppercase -d foo
|
||||||
|
FOO
|
||||||
|
```
|
||||||
|
|
||||||
@@ -15,19 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.cloud.function.deployer;
|
package org.springframework.cloud.function.deployer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
|
||||||
import org.springframework.boot.loader.thin.ArchiveUtils;
|
|
||||||
import org.springframework.cloud.deployer.spi.app.AppDeployer;
|
|
||||||
import org.springframework.cloud.deployer.spi.core.AppDefinition;
|
|
||||||
import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest;
|
|
||||||
import org.springframework.context.support.LiveBeansView;
|
|
||||||
import org.springframework.core.io.FileSystemResource;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
@@ -42,7 +33,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/admin")
|
@RequestMapping("/admin")
|
||||||
public class FunctionAdminController implements CommandLineRunner {
|
public class FunctionAdminController {
|
||||||
|
|
||||||
private final FunctionExtractingFunctionCatalog deployer;
|
private final FunctionExtractingFunctionCatalog deployer;
|
||||||
|
|
||||||
@@ -68,21 +59,8 @@ public class FunctionAdminController implements CommandLineRunner {
|
|||||||
return deployer.deployed();
|
return deployer.deployed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(String... args) throws Exception {
|
|
||||||
deploy("sample", "maven://com.example:function-sample-pojo:1.0.0.BUILD-SNAPSHOT");
|
|
||||||
}
|
|
||||||
|
|
||||||
private String deploy(String name, String path, String... args) throws Exception {
|
private String deploy(String name, String path, String... args) throws Exception {
|
||||||
Resource resource = new FileSystemResource(
|
String deployed = deployer.deploy(name, path, args);
|
||||||
ArchiveUtils.getArchiveRoot(ArchiveUtils.getArchive(path)));
|
|
||||||
AppDefinition definition = new AppDefinition(resource.getFilename(),
|
|
||||||
Collections.singletonMap(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME,
|
|
||||||
"functions." + name));
|
|
||||||
AppDeploymentRequest request = new AppDeploymentRequest(definition, resource,
|
|
||||||
Collections.singletonMap(AppDeployer.GROUP_PROPERTY_KEY, "functions"),
|
|
||||||
Arrays.asList(args));
|
|
||||||
String deployed = deployer.deploy(name, request);
|
|
||||||
return deployed;
|
return deployed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.cloud.function.deployer;
|
package org.springframework.cloud.function.deployer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -26,10 +29,16 @@ import java.util.function.Supplier;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.boot.loader.thin.ArchiveUtils;
|
||||||
|
import org.springframework.cloud.deployer.spi.app.AppDeployer;
|
||||||
|
import org.springframework.cloud.deployer.spi.core.AppDefinition;
|
||||||
import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest;
|
import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest;
|
||||||
import org.springframework.cloud.deployer.thin.ThinJarAppDeployer;
|
import org.springframework.cloud.deployer.thin.ThinJarAppDeployer;
|
||||||
import org.springframework.cloud.function.context.FunctionInspector;
|
import org.springframework.cloud.function.context.FunctionInspector;
|
||||||
import org.springframework.cloud.function.registry.FunctionCatalog;
|
import org.springframework.cloud.function.registry.FunctionCatalog;
|
||||||
|
import org.springframework.context.support.LiveBeansView;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.util.MethodInvoker;
|
import org.springframework.util.MethodInvoker;
|
||||||
|
|
||||||
public class FunctionExtractingFunctionCatalog
|
public class FunctionExtractingFunctionCatalog
|
||||||
@@ -44,6 +53,8 @@ public class FunctionExtractingFunctionCatalog
|
|||||||
|
|
||||||
private Map<String, String> names = new LinkedHashMap<>();
|
private Map<String, String> names = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
private Map<String, String> ids = new LinkedHashMap<>();
|
||||||
|
|
||||||
public FunctionExtractingFunctionCatalog() {
|
public FunctionExtractingFunctionCatalog() {
|
||||||
this("thin", "slim");
|
this("thin", "slim");
|
||||||
}
|
}
|
||||||
@@ -123,15 +134,19 @@ public class FunctionExtractingFunctionCatalog
|
|||||||
return (String) inspect(function, "getName");
|
return (String) inspect(function, "getName");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String deploy(String name, AppDeploymentRequest request) {
|
public String deploy(String name, String path, String... args) {
|
||||||
|
Resource resource = new FileSystemResource(
|
||||||
|
ArchiveUtils.getArchiveRoot(ArchiveUtils.getArchive(path)));
|
||||||
|
AppDefinition definition = new AppDefinition(resource.getFilename(),
|
||||||
|
Collections.singletonMap(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME,
|
||||||
|
"functions." + name));
|
||||||
|
AppDeploymentRequest request = new AppDeploymentRequest(definition, resource,
|
||||||
|
Collections.singletonMap(AppDeployer.GROUP_PROPERTY_KEY, "functions"),
|
||||||
|
Arrays.asList(args));
|
||||||
String id = this.deployer.deploy(request);
|
String id = this.deployer.deploy(request);
|
||||||
try {
|
this.deployed.put(id, path);
|
||||||
this.deployed.put(id, request.getResource().getURI().toString());
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new IllegalStateException("Cannot locate resource for " + name, e);
|
|
||||||
}
|
|
||||||
this.names.put(name, id);
|
this.names.put(name, id);
|
||||||
|
this.ids.put(id, name);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,10 +157,10 @@ public class FunctionExtractingFunctionCatalog
|
|||||||
throw new IllegalStateException("No such app");
|
throw new IllegalStateException("No such app");
|
||||||
}
|
}
|
||||||
this.deployer.undeploy(id);
|
this.deployer.undeploy(id);
|
||||||
this.deployed.remove(id);
|
|
||||||
this.names.remove(name);
|
|
||||||
String path = this.deployed.remove(id);
|
String path = this.deployed.remove(id);
|
||||||
return new DeployedArtifact(id, name, path);
|
this.names.remove(name);
|
||||||
|
this.ids.remove(id);
|
||||||
|
return new DeployedArtifact(name, id, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object inspect(Object arg, String method) {
|
private Object inspect(Object arg, String method) {
|
||||||
@@ -170,11 +185,25 @@ public class FunctionExtractingFunctionCatalog
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object invoke(Class<?> type, String method, Object... arg) {
|
private Object invoke(Class<?> type, String method, Object... arg) {
|
||||||
|
Set<Object> results = new LinkedHashSet<>();
|
||||||
for (String id : this.deployed.keySet()) {
|
for (String id : this.deployed.keySet()) {
|
||||||
Object catalog = this.deployer.getBean(id, type);
|
Object catalog = this.deployer.getBean(id, type);
|
||||||
if (catalog == null) {
|
if (catalog == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
String name = this.ids.get(id);
|
||||||
|
String prefix = name + "/";
|
||||||
|
if (arg.length == 1) {
|
||||||
|
if (arg[0] instanceof String) {
|
||||||
|
String specific = arg[0].toString();
|
||||||
|
if (specific.startsWith(prefix)) {
|
||||||
|
arg[0] = specific.substring(prefix.length());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
MethodInvoker invoker = new MethodInvoker();
|
MethodInvoker invoker = new MethodInvoker();
|
||||||
invoker.setTargetObject(catalog);
|
invoker.setTargetObject(catalog);
|
||||||
@@ -183,14 +212,25 @@ public class FunctionExtractingFunctionCatalog
|
|||||||
invoker.prepare();
|
invoker.prepare();
|
||||||
Object result = invoker.invoke();
|
Object result = invoker.invoke();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
if (result instanceof Collection) {
|
||||||
|
for (Object value : (Collection<?>) result) {
|
||||||
|
results.add(prefix + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (result instanceof String) {
|
||||||
|
return prefix + result;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new IllegalStateException("Cannot extract catalog", e);
|
throw new IllegalStateException("Cannot extract catalog", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return arg.length > 0 ? null : results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> deployed() {
|
public Map<String, Object> deployed() {
|
||||||
|
|||||||
@@ -15,13 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.cloud.function.deployer;
|
package org.springframework.cloud.function.deployer;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.RequestEntity;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.util.SocketUtils;
|
import org.springframework.util.SocketUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -30,19 +34,33 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Ignore
|
|
||||||
// TODO: Salvage some stuff from this project
|
|
||||||
public class FunctionExtractingFunctionCatalogIntegrationTests {
|
public class FunctionExtractingFunctionCatalogIntegrationTests {
|
||||||
|
|
||||||
private static ConfigurableApplicationContext context;
|
private static ConfigurableApplicationContext context;
|
||||||
private static int port;
|
private static int port;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void open() {
|
public static void open() throws Exception {
|
||||||
port = SocketUtils.findAvailableTcpPort();
|
port = SocketUtils.findAvailableTcpPort();
|
||||||
// System.setProperty("debug", "true");
|
// System.setProperty("debug", "true");
|
||||||
context = new ApplicationRunner().start("--server.port=" + port,
|
context = new ApplicationRunner().start("--server.port=" + port,
|
||||||
"--spring.cloud.stream.enabled=false");
|
"--spring.cloud.stream.enabled=false");
|
||||||
|
deploy("sample", "maven://com.example:function-sample:1.0.0.BUILD-SNAPSHOT");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void deploy(String name, String path) throws Exception {
|
||||||
|
ResponseEntity<String> result = new TestRestTemplate().postForEntity(
|
||||||
|
"http://localhost:" + port + "/admin/" + name + "?path=" + path, "",
|
||||||
|
String.class);
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String undeploy(String name) throws Exception {
|
||||||
|
ResponseEntity<String> result = new TestRestTemplate().exchange(RequestEntity
|
||||||
|
.delete(new URI("http://localhost:" + port + "/admin/" + name)).build(),
|
||||||
|
String.class);
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
return result.getBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
@@ -52,18 +70,49 @@ public class FunctionExtractingFunctionCatalogIntegrationTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listing() {
|
||||||
|
assertThat(new TestRestTemplate()
|
||||||
|
.getForObject("http://localhost:" + port + "/admin", String.class))
|
||||||
|
.startsWith("{").contains("sample");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void words() {
|
public void words() {
|
||||||
assertThat(new TestRestTemplate()
|
assertThat(new TestRestTemplate()
|
||||||
.getForObject("http://localhost:" + port + "/words", String.class))
|
.getForObject("http://localhost:" + port + "/sample/words", String.class))
|
||||||
.isEqualTo("{\"value\":\"foo\"}{\"value\":\"bar\"}");
|
.isEqualTo("[{\"value\":\"foo\"},{\"value\":\"bar\"}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uppercase() {
|
public void uppercase() {
|
||||||
assertThat(new TestRestTemplate().postForObject(
|
assertThat(new TestRestTemplate().postForObject(
|
||||||
"http://localhost:" + port + "/uppercase", "{\"value\":\"foo\"}",
|
"http://localhost:" + port + "/sample/uppercase", "{\"value\":\"foo\"}",
|
||||||
String.class)).isEqualTo("{\"value\":\"FOO\"}");
|
String.class)).isEqualTo("[{\"value\":\"FOO\"}]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void another() throws Exception {
|
||||||
|
deploy("strings", "maven://com.example:function-sample:1.0.0.BUILD-SNAPSHOT");
|
||||||
|
assertThat(new TestRestTemplate().getForObject(
|
||||||
|
"http://localhost:" + port + "/strings/words", String.class))
|
||||||
|
.isEqualTo("[\"foo\",\"bar\"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cycle() throws Exception {
|
||||||
|
String undeploy = undeploy("sample");
|
||||||
|
assertThat(undeploy.contains("\"name\":\"sample\""));
|
||||||
|
assertThat(undeploy.contains(
|
||||||
|
"\"path\":\"maven://com.example:function-sample-pojo:1.0.0.BUILD-SNAPSHOT\""));
|
||||||
|
ResponseEntity<String> result = new TestRestTemplate().exchange(RequestEntity
|
||||||
|
.get(new URI("http://localhost:" + port + "/sample/words")).build(),
|
||||||
|
String.class);
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||||
|
deploy("sample", "maven://com.example:function-sample-pojo:1.0.0.BUILD-SNAPSHOT");
|
||||||
|
assertThat(new TestRestTemplate().postForObject(
|
||||||
|
"http://localhost:" + port + "/sample/uppercase", "{\"value\":\"foo\"}",
|
||||||
|
String.class)).isEqualTo("[{\"value\":\"FOO\"}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,21 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.cloud.function.deployer;
|
package org.springframework.cloud.function.deployer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import org.springframework.boot.loader.thin.ArchiveUtils;
|
|
||||||
import org.springframework.boot.loader.tools.LogbackInitializer;
|
import org.springframework.boot.loader.tools.LogbackInitializer;
|
||||||
import org.springframework.cloud.deployer.spi.core.AppDefinition;
|
|
||||||
import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest;
|
|
||||||
import org.springframework.core.io.FileSystemResource;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -55,8 +47,10 @@ public class FunctionExtractingFunctionCatalogTests {
|
|||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
id = deploy("maven://com.example:function-sample:1.0.0.BUILD-SNAPSHOT");
|
deploy("sample", "maven://com.example:function-sample:1.0.0.BUILD-SNAPSHOT");
|
||||||
// "--debug");
|
// "--debug");
|
||||||
|
id = deploy("pojos",
|
||||||
|
"maven://com.example:function-sample-pojo:1.0.0.BUILD-SNAPSHOT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,38 +58,63 @@ public class FunctionExtractingFunctionCatalogTests {
|
|||||||
public static void close() {
|
public static void close() {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
deployer.undeploy("sample");
|
deployer.undeploy("sample");
|
||||||
|
deployer.undeploy("pojos");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listFunctions() throws Exception {
|
||||||
|
assertThat(deployer.getFunctionNames()).contains("sample/uppercase",
|
||||||
|
"pojos/uppercase");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nameFunction() throws Exception {
|
||||||
|
assertThat(deployer.getName(deployer.lookupFunction("sample/uppercase")))
|
||||||
|
.isEqualTo("sample/uppercase");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deployAndExtractFunctions() throws Exception {
|
public void deployAndExtractFunctions() throws Exception {
|
||||||
// This one can only work if you change the boot classpath to contain reactor-core
|
// This one can only work if you change the boot classpath to contain reactor-core
|
||||||
// and reactive-streams
|
// and reactive-streams
|
||||||
expected.expect(ClassCastException.class);
|
expected.expect(ClassCastException.class);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Flux<String> result = (Flux<String>) deployer.lookupFunction("uppercase")
|
Flux<String> result = (Flux<String>) deployer.lookupFunction("pojos/uppercase")
|
||||||
.apply(Flux.just("foo"));
|
.apply(Flux.just("foo"));
|
||||||
assertThat(result.blockFirst()).isEqualTo("FOO");
|
assertThat(result.blockFirst()).isEqualTo("FOO");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listConsumers() throws Exception {
|
||||||
|
assertThat(deployer.getConsumerNames()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deployAndExtractConsumers() throws Exception {
|
public void deployAndExtractConsumers() throws Exception {
|
||||||
assertThat(deployer.lookupConsumer("sink")).isNull();
|
assertThat(deployer.lookupConsumer("pojos/sink")).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listSuppliers() throws Exception {
|
||||||
|
assertThat(deployer.getSupplierNames()).contains("sample/words", "pojos/words");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nameSupplier() throws Exception {
|
||||||
|
assertThat(deployer.getName(deployer.lookupSupplier("sample/words")))
|
||||||
|
.isEqualTo("sample/words");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deployAndExtractSuppliers() throws Exception {
|
public void deployAndExtractSuppliers() throws Exception {
|
||||||
assertThat(deployer.lookupSupplier("words")).isNotNull();
|
assertThat(deployer.lookupSupplier("sample/words")).isNotNull();
|
||||||
|
assertThat(deployer.lookupSupplier("pojos/words")).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String deploy(String jarName, String... args) throws Exception {
|
private static String deploy(String name, String path, String... args)
|
||||||
Resource resource = new FileSystemResource(
|
throws Exception {
|
||||||
ArchiveUtils.getArchiveRoot(ArchiveUtils.getArchive(jarName)));
|
String deployed = deployer.deploy(name, path, args);
|
||||||
AppDefinition definition = new AppDefinition(resource.getFilename(),
|
|
||||||
Collections.emptyMap());
|
|
||||||
AppDeploymentRequest request = new AppDeploymentRequest(definition, resource,
|
|
||||||
Collections.emptyMap(), Arrays.asList(args));
|
|
||||||
String deployed = deployer.deploy("sample", request);
|
|
||||||
return deployed;
|
return deployed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user