diff --git a/docs/modules/ROOT/pages/adapters/aws-intro.adoc b/docs/modules/ROOT/pages/adapters/aws-intro.adoc index bac448e09..1753e1c0f 100644 --- a/docs/modules/ROOT/pages/adapters/aws-intro.adoc +++ b/docs/modules/ROOT/pages/adapters/aws-intro.adoc @@ -1,5 +1,6 @@ [[aws-lambda]] = AWS Lambda +:page-aliases: adapters/aws.adoc The https://aws.amazon.com/[AWS] adapter takes a Spring Cloud Function app and converts it to a form that can run in AWS Lambda. diff --git a/docs/modules/ROOT/pages/adapters/aws.adoc b/docs/modules/ROOT/pages/adapters/aws.adoc deleted file mode 100644 index f5c4d1977..000000000 --- a/docs/modules/ROOT/pages/adapters/aws.adoc +++ /dev/null @@ -1,155 +0,0 @@ -*{project-version}* - - -The https://aws.amazon.com/[AWS] adapter takes a Spring Cloud Function app and converts it to a form that can run in AWS Lambda. - -[[introduction]] -== Introduction - -The details of how to get stared with AWS Lambda is out of scope of this document, so the expectation is that user has some familiarity with -AWS and AWS Lambda and wants to learn what additional value spring provides. - - -=== Getting Started - -One of the goals of Spring Cloud Function framework is to provide necessary infrastructure elements to enable a _simple function application_ -to interact in a certain way in a particular environment. -A simple function application (in context or Spring) is an application that contains beans of type Supplier, Function or Consumer. -So, with AWS it means that a simple function bean should somehow be recognised and executed in AWS Lambda environment. - -Let’s look at the example: - -[source, java] ----- -@SpringBootApplication -public class FunctionConfiguration { - - public static void main(String[] args) { - SpringApplication.run(FunctionConfiguration.class, args); - } - - @Bean - public Function uppercase() { - return value -> value.toUpperCase(); - } -} ----- - -It shows a complete Spring Boot application with a function bean defined in it. What’s interesting is that on the surface this is just -another boot app, but in the context of AWS Adapter it is also a perfectly valid AWS Lambda application. No other code or configuration -is required. All you need to do is package it and deploy it, so let’s look how we can do that. - -To make things simpler we’ve provided a sample project ready to be built and deployed and you can access it -https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-aws[here]. - -You simply execute `./mvnw clean package` to generate JAR file. All the necessary maven plugins have already been setup to generate -appropriate AWS deployable JAR file. (You can read more details about JAR layout in <>). - -Then you have to upload the JAR file (via AWS dashboard or AWS CLI) to AWS. - -When asked about _handler_ you specify `org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest` which is a generic request handler. - -image::AWS-deploy.png[width=800,scaledwidth="75%",align="center"] - -That is all. Save and execute the function with some sample data which for this function is expected to be a -String which function will uppercase and return back. - -While `org.springframework.cloud.function.adapter.aws.FunctionInvoker` is a general purpose AWS's `RequestHandler` implementation aimed at completely -isolating you from the specifics of AWS Lambda API, for some cases you may want to specify which specific AWS's `RequestHandler` you want -to use. The next section will explain you how you can accomplish just that. - - -[[aws-request-handlers]] -== AWS Request Handlers - -The adapter has a couple of generic request handlers that you can use. The most generic is (and the one we used in the Getting Started section) -is `org.springframework.cloud.function.adapter.aws.FunctionInvoker` which is the implementation of AWS's `RequestStreamHandler`. -User doesn't need to do anything other then specify it as 'handler' on AWS dashboard when deploying function. -It will handle most of the cases including Kinesis, streaming etc. - - -If your app has more than one `@Bean` of type `Function` etc. then you can choose the one to use by configuring `spring.cloud.function.definition` -property or environment variable. The functions are extracted from the Spring Cloud `FunctionCatalog`. In the event you don't specify `spring.cloud.function.definition` -the framework will attempt to find a default following the search order where it searches first for `Function` then `Consumer` and finally `Supplier`). - -[[aws-context]] -== AWS Context - -In a typical implementation of AWS Handler user has access to AWS _context_ object. With function approach you can have the same experience if you need it. -Upon each invocation the framework will add `aws-context` message header containing the AWS _context_ instance for that particular invocation. So if you need to access it -you can simply have `Message` as an input parameter to your function and then access `aws-context` from message headers. -For convenience we provide AWSLambdaUtils.AWS_CONTEXT constant. - - -[[aws-function-routing]] -== AWS Function Routing - -One of the core features of Spring Cloud Function is https://docs.spring.io/spring-cloud-function/docs/{project-version}/reference/html/spring-cloud-function.html#_function_routing_and_filtering[routing] -- an ability to have one special function to delegate to other functions based on the user provided routing instructions. - -In AWS Lambda environment this feature provides one additional benefit, as it allows you to bind a single function (Routing Function) -as AWS Lambda and thus a single HTTP endpoint for API Gateway. So in the end you only manage one function and one endpoint, while benefiting -from many function that can be part of your application. - -More details are available in the provided https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-function-samples/function-sample-aws-routing[sample], -yet few general things worth mentioning. - -Routing capabilities will be enabled by default whenever there is more then one function in your application as `org.springframework.cloud.function.adapter.aws.FunctionInvoker` -can not determine which function to bind as AWS Lambda, so it defaults to `RoutingFunction`. -This means that all you need to do is provide routing instructions which you can do https://docs.spring.io/spring-cloud-function/docs/{project-version}/reference/html/spring-cloud-function.html#_function_routing_and_filtering[using several mechanisms] -(see https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-function-samples/function-sample-aws-routing[sample] for more details). - -Also, note that since AWS does not allow dots `.` and/or hyphens`-` in the name of the environment variable, you can benefit from boot support and simply substitute -dots with underscores and hyphens with camel case. So for example `spring.cloud.function.definition` becomes `spring_cloud_function_definition` -and `spring.cloud.function.routing-expression` becomes `spring_cloud_function_routingExpression`. - - -[[http-and-api-gateway]] -== 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). - -[[custom-runtime]] -== Custom Runtime - -You can also benefit from https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html[AWS Lambda custom runtime] feature of AWS Lambda -and Spring Cloud Function provides all the necessary components to make it easy. - -From the code perspective the application should look no different then any other Spring Cloud Function application. -The only thing you need to do is to provide a `bootstrap` script in the root of your zip/jar that runs the Spring Boot application. -and select "Custom Runtime" when creating a function in AWS. -Here is an example 'bootstrap' file: -```text -#!/bin/sh - -cd ${LAMBDA_TASK_ROOT:-.} - -java -Dspring.main.web-application-type=none -Dspring.jmx.enabled=false \ - -noverify -XX:TieredStopAtLevel=1 -Xss256K -XX:MaxMetaspaceSize=128M \ - -Djava.security.egd=file:/dev/./urandom \ - -cp .:`echo lib/*.jar | tr ' ' :` com.example.LambdaApplication -``` -The `com.example.LambdaApplication` represents your application which contains function beans. - -Set the handler name in AWS to the name of your function. You can use function composition here as well (e.g., `uppercase|reverse`). -That is pretty much all. Once you upload your zip/jar to AWS your function will run in custom runtime. -We provide a https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-aws-custom-new[sample project] -where you can also see how to configure your POM to properly generate the zip file. - -The functional bean definition style works for custom runtimes as well, and is -faster than the `@Bean` style. A custom runtime can start up much quicker even than a functional bean implementation -of a Java lambda - it depends mostly on the number of classes you need to load at runtime. -Spring doesn't do very much here, so you can reduce the cold start time by only using primitive types in your function, for instance, -and not doing any work in custom `@PostConstruct` initializers. diff --git a/docs/modules/ROOT/pages/adapters/azure-intro.adoc b/docs/modules/ROOT/pages/adapters/azure-intro.adoc index 039f35081..fa3ac447e 100644 --- a/docs/modules/ROOT/pages/adapters/azure-intro.adoc +++ b/docs/modules/ROOT/pages/adapters/azure-intro.adoc @@ -1,6 +1,6 @@ [[microsoft-azure-functions]] = Microsoft Azure Functions - +:page-aliases: adapters/azure.adoc https://azure.microsoft.com[Azure] function adapter for deploying `Spring Cloud Function` applications as native Azure Java Functions. diff --git a/docs/modules/ROOT/pages/adapters/azure.adoc b/docs/modules/ROOT/pages/adapters/azure.adoc deleted file mode 100644 index 490093572..000000000 --- a/docs/modules/ROOT/pages/adapters/azure.adoc +++ /dev/null @@ -1,2 +0,0 @@ -*{project-version}* - diff --git a/docs/modules/ROOT/pages/adapters/gcp-intro.adoc b/docs/modules/ROOT/pages/adapters/gcp-intro.adoc index 4b5054408..02a92c3d7 100644 --- a/docs/modules/ROOT/pages/adapters/gcp-intro.adoc +++ b/docs/modules/ROOT/pages/adapters/gcp-intro.adoc @@ -1,5 +1,6 @@ [[google-cloud-functions]] = Google Cloud Functions +:page-aliases: adapters/gcp.adoc The Google Cloud Functions adapter enables Spring Cloud Function apps to run on the https://cloud.google.com/functions[Google Cloud Functions] serverless platform. You can either run the function locally using the open source https://github.com/GoogleCloudPlatform/functions-framework-java[Google Functions Framework for Java] or on GCP. diff --git a/docs/modules/ROOT/pages/adapters/gcp.adoc b/docs/modules/ROOT/pages/adapters/gcp.adoc deleted file mode 100644 index 490093572..000000000 --- a/docs/modules/ROOT/pages/adapters/gcp.adoc +++ /dev/null @@ -1,2 +0,0 @@ -*{project-version}* - diff --git a/docs/pom.xml b/docs/pom.xml index e85461ee6..f2c7245d0 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -53,6 +53,11 @@ org.antora antora-maven-plugin + + + + + org.apache.maven.plugins