From 1fd83527a7a23cff26310152ac33ac377284afeb Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 4 Jun 2018 14:00:26 +0100 Subject: [PATCH] Add notes on AWS platform-specific features --- docs/src/main/asciidoc/adapters/aws.adoc | 20 +++- docs/src/main/asciidoc/getting-started.adoc | 92 ------------------- .../main/asciidoc/spring-cloud-function.adoc | 92 +++++++++++++++++++ 3 files changed, 111 insertions(+), 93 deletions(-) diff --git a/docs/src/main/asciidoc/adapters/aws.adoc b/docs/src/main/asciidoc/adapters/aws.adoc index fec169d38..328aa58be 100644 --- a/docs/src/main/asciidoc/adapters/aws.adoc +++ b/docs/src/main/asciidoc/adapters/aws.adoc @@ -2,4 +2,22 @@ The https://aws.amazon.com/[AWS] adapter takes a Spring Cloud Function app and c == Introduction -include::aws-intro.adoc[] \ No newline at end of file +include::aws-intro.adoc[] + +== Platfom Specific Features + +=== HTTP and API Gateway + +AWS has some platform-specific data types, including batching of messages, which is much more efficient than processing each one individually. To make use of these types you can write a function that depends on those types. Or you can rely on Spring to extract the data from the AWS types and convert it to a Spring `Message`. To do this you tell AWS that the function is of a specific generic handler type (depending on the AWS service) and provide a bean of type `Function,Message>`, where `S` and `T` are your business data types. If there is more than one bean of type `Function` you may also need to configure the Spring Boot property `function.name` to be the name of the target bean (e.g. use `FUNCTION_NAME` as an environment variable). + +The supported AWS services and generic handler types are listed below: + +|=== +| Service | AWS Types | Generic Handler | + +| API Gateway | `APIGatewayProxyRequestEvent`, `APIGatewayProxyResponseEvent` | `org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler` | +| Kinesis | KinesisEvent | org.springframework.cloud.function.adapter.aws.SpringBootKinesisEventHandler | +|=== + + +For example, to deploy behind an API Gateway, use `--handler org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler` in your AWS command line (in via the UI) and define a `@Bean` of type `Function,Message>` where `Foo` and `Bar` are POJO types (the data will be marshalled and unmarshalled by AWS using Jackson). diff --git a/docs/src/main/asciidoc/getting-started.adoc b/docs/src/main/asciidoc/getting-started.adoc index e0f5d4def..48a4dce2c 100644 --- a/docs/src/main/asciidoc/getting-started.adoc +++ b/docs/src/main/asciidoc/getting-started.adoc @@ -57,95 +57,3 @@ Functions can be grouped together in a single application, or deployed one-per-jar. It's up to the developer to choose. An app with multiple functions can be deployed multiple times in different "personalities", exposing different functions over different physical transports. - -== Dynamic Compilation - -There is a sample app that uses the function compiler to create a -function from a configuration property. The vanilla "function-sample" -also has that feature. And there are some examples that you can run to -see the compilation happening at run time. To run these examples, -change into the `scripts` directory: - ----- -cd scripts ----- - -Also, start a RabbitMQ server locally (e.g. execute `rabbitmq-server`). - -=== Start the Function Registry Service: - ----- -./function-registry.sh ----- - -=== Register a Function: - ----- -./registerFunction.sh -n uppercase -f "f->f.map(s->s.toString().toUpperCase())" ----- - -=== Run a REST Microservice using that Function: - ----- -./web.sh -f uppercase -p 9000 -curl -H "Content-Type: text/plain" -H "Accept: text/plain" localhost:9000/uppercase -d foo ----- - -=== Register a Supplier: - ----- -./registerSupplier.sh -n words -f "()->Flux.just(\"foo\",\"bar\")" ----- - -=== Run a REST Microservice using that Supplier: - ----- -./web.sh -s words -p 9001 -curl -H "Accept: application/json" localhost:9001/words ----- - -=== Register a Consumer: - ----- -./registerConsumer.sh -n print -t String -f "System.out::println" ----- - -=== Run a REST Microservice using that Consumer: - ----- -./web.sh -c print -p 9002 -curl -X POST -H "Content-Type: text/plain" -d foo localhost:9002/print ----- - -=== Run Stream Processing Microservices: - -First register a streaming words supplier: - ----- -./registerSupplier.sh -n wordstream -f "()->Flux.interval(Duration.ofMillis(1000)).map(i->\"message-\"+i)" ----- - -Then start the source (supplier), processor (function), and sink (consumer) apps -(in reverse order): - ----- -./stream.sh -p 9103 -i uppercaseWords -c print -./stream.sh -p 9102 -i words -f uppercase -o uppercaseWords -./stream.sh -p 9101 -s wordstream -o words ----- - -The output will appear in the console of the sink app (one message per second, converted to uppercase): - ----- -MESSAGE-0 -MESSAGE-1 -MESSAGE-2 -MESSAGE-3 -MESSAGE-4 -MESSAGE-5 -MESSAGE-6 -MESSAGE-7 -MESSAGE-8 -MESSAGE-9 -... ----- \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-function.adoc b/docs/src/main/asciidoc/spring-cloud-function.adoc index be0ebed8d..4a11a3f8e 100644 --- a/docs/src/main/asciidoc/spring-cloud-function.adoc +++ b/docs/src/main/asciidoc/spring-cloud-function.adoc @@ -112,6 +112,98 @@ Spring Cloud Function provides a "deployer" library that allows you to launch a The standard entry point of the API is the Spring configuration annotation `@EnableFunctionDeployer`. If that is used in a Spring Boot application the deployer kicks in and looks for some configuration to tell it where to find the function jar. At a minimum the user has to provide a `function.location` which is a URL or resource location for the archive containing the functions. It can optionally use a `maven:` prefix to locate the artifact via a dependency lookup (see `FunctionProperties` for complete details). A Spring Boot application is bootstrapped from the jar file, using the `MANIFEST.MF` to locate a start class, so that a standard Spring Boot fat jar works well, for example. If the target jar can be launched successfully then the result is a function registered in the main application's `FunctionCatalog`. The registered function can be applied by code in the main application, even though it was created in an isolated class loader (by deault). +== Dynamic Compilation + +There is a sample app that uses the function compiler to create a +function from a configuration property. The vanilla "function-sample" +also has that feature. And there are some scripts that you can run to +see the compilation happening at run time. To run these examples, +change into the `scripts` directory: + +---- +cd scripts +---- + +Also, start a RabbitMQ server locally (e.g. execute `rabbitmq-server`). + +Start the Function Registry Service: + +---- +./function-registry.sh +---- + +Register a Function: + +---- +./registerFunction.sh -n uppercase -f "f->f.map(s->s.toString().toUpperCase())" +---- + +Run a REST Microservice using that Function: + +---- +./web.sh -f uppercase -p 9000 +curl -H "Content-Type: text/plain" -H "Accept: text/plain" localhost:9000/uppercase -d foo +---- + +Register a Supplier: + +---- +./registerSupplier.sh -n words -f "()->Flux.just(\"foo\",\"bar\")" +---- + +Run a REST Microservice using that Supplier: + +---- +./web.sh -s words -p 9001 +curl -H "Accept: application/json" localhost:9001/words +---- + +Register a Consumer: + +---- +./registerConsumer.sh -n print -t String -f "System.out::println" +---- + +Run a REST Microservice using that Consumer: + +---- +./web.sh -c print -p 9002 +curl -X POST -H "Content-Type: text/plain" -d foo localhost:9002/print +---- + +Run Stream Processing Microservices: + +First register a streaming words supplier: + +---- +./registerSupplier.sh -n wordstream -f "()->Flux.interval(Duration.ofMillis(1000)).map(i->\"message-\"+i)" +---- + +Then start the source (supplier), processor (function), and sink (consumer) apps +(in reverse order): + +---- +./stream.sh -p 9103 -i uppercaseWords -c print +./stream.sh -p 9102 -i words -f uppercase -o uppercaseWords +./stream.sh -p 9101 -s wordstream -o words +---- + +The output will appear in the console of the sink app (one message per second, converted to uppercase): + +---- +MESSAGE-0 +MESSAGE-1 +MESSAGE-2 +MESSAGE-3 +MESSAGE-4 +MESSAGE-5 +MESSAGE-6 +MESSAGE-7 +MESSAGE-8 +MESSAGE-9 +... +---- + == Serverless Platform Adapters As well as being able to run as a standalone process, a Spring Cloud