Insert explicit ids for headers
This commit is contained in:
@@ -2,18 +2,22 @@
|
||||
|
||||
image::https://travis-ci.org/spring-cloud/spring-cloud-function.svg?branch={branch}[Build Status, link=https://travis-ci.org/spring-cloud/spring-cloud-function]
|
||||
|
||||
[[introduction]]
|
||||
== Introduction
|
||||
|
||||
include::_intro.adoc[]
|
||||
|
||||
[[getting-started]]
|
||||
== Getting Started
|
||||
|
||||
include::getting-started.adoc[]
|
||||
|
||||
[[building]]
|
||||
== Building
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building.adoc[]
|
||||
|
||||
[[contributing]]
|
||||
== Contributing
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
:branch: master
|
||||
|
||||
[[aws-lambda]]
|
||||
=== AWS Lambda
|
||||
|
||||
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.
|
||||
@@ -7,6 +8,7 @@ The https://aws.amazon.com/[AWS] adapter takes a Spring Cloud Function app and c
|
||||
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]]
|
||||
==== Getting Started
|
||||
|
||||
One of the goals of Spring Cloud Function framework is to provide necessary infrastructure elements to enable a _simple function application_
|
||||
@@ -56,6 +58,7 @@ isolating you from the specifics of AWS Lambda API, for some cases you may 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)
|
||||
@@ -69,6 +72,7 @@ property or environment variable. The functions are extracted from the Spring Cl
|
||||
the framework will attempt to find a default following the search order where it searches first for `Function` then `Consumer` and finally `Supplier`).
|
||||
|
||||
|
||||
[[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]
|
||||
@@ -90,10 +94,12 @@ Also, note that since AWS does not allow dots `.` and/or hyphens`-` in the name
|
||||
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`.
|
||||
|
||||
[[aws-function-routing-with-custom-runtime]]
|
||||
===== AWS Function Routing with Custom Runtime
|
||||
|
||||
When using <<Custom Runtime>> Function Routing works the same way. All you need is to specify `functionRouter` as AWS Handler the same way you would use the name of the function as handler.
|
||||
|
||||
[[notes-on-jar-layout]]
|
||||
==== Notes on JAR Layout
|
||||
|
||||
You don't need the Spring Cloud Function Web or Stream adapter at runtime in Lambda, so you might
|
||||
@@ -158,12 +164,14 @@ then additional transformers must be configured as part of the maven-shade-plugi
|
||||
</plugin>
|
||||
----
|
||||
|
||||
[[build-file-setup]]
|
||||
==== Build file setup
|
||||
|
||||
In order to run Spring Cloud Function applications on AWS Lambda, you can leverage Maven or Gradle
|
||||
plugins offered by the cloud platform provider.
|
||||
|
||||
|
||||
[[maven]]
|
||||
===== Maven
|
||||
|
||||
In order to use the adapter plugin for Maven, add the plugin dependency to your `pom.xml`
|
||||
@@ -202,6 +210,7 @@ You can use the Spring Boot Maven Plugin to generate the <<thin-jar>>.
|
||||
You can find the entire sample `pom.xml` file for deploying Spring Cloud Function
|
||||
applications to AWS Lambda with Maven https://github.com/spring-cloud/spring-cloud-function/blob/{branch}/spring-cloud-function-samples/function-sample-aws/pom.xml[here].
|
||||
|
||||
[[gradle]]
|
||||
===== Gradle
|
||||
|
||||
In order to use the adapter plugin for Gradle, add the dependency to your `build.gradle` file:
|
||||
@@ -270,6 +279,7 @@ assemble.dependsOn = [thinJar]
|
||||
You can find the entire sample `build.gradle` file for deploying Spring Cloud Function
|
||||
applications to AWS Lambda with Gradle https://github.com/spring-cloud/spring-cloud-function/blob/{branch}/spring-cloud-function-samples/function-sample-aws/build.gradle[here].
|
||||
|
||||
[[upload]]
|
||||
==== Upload
|
||||
|
||||
Build the sample under `spring-cloud-function-samples/function-sample-aws` and upload the `-aws` jar file to Lambda. The handler can be `example.Handler` or `org.springframework.cloud.function.adapter.aws.SpringBootStreamHandler` (FQN of the class, _not_ a method reference, although Lambda does accept method references).
|
||||
@@ -295,6 +305,7 @@ The input type for the function in the AWS sample is a Foo with a single propert
|
||||
NOTE: The AWS sample app is written in the "functional" style (as an `ApplicationContextInitializer`). This is much faster on startup in Lambda than the traditional `@Bean` style, so if you don't need `@Beans` (or `@EnableAutoConfiguration`) it's a good choice. Warm starts are not affected.
|
||||
|
||||
|
||||
[[type-conversion]]
|
||||
==== Type Conversion
|
||||
|
||||
Spring Cloud Function will attempt to transparently handle type conversion between the raw
|
||||
@@ -306,6 +317,7 @@ incoming stream event to an instance of `Foo`.
|
||||
In the event type is not known or can not be determined (e.g., `Function<?, ?>`) we will attempt to
|
||||
convert an incoming stream event to a generic `Map`.
|
||||
|
||||
[[raw-input]]
|
||||
====== Raw Input
|
||||
|
||||
There are times when you may want to have access to a raw input. In this case all you need is to declare your
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
|
||||
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
|
||||
|
||||
include::adapters/aws-intro.adoc[]
|
||||
|
||||
[[functional-bean-definitions]]
|
||||
== Functional Bean Definitions
|
||||
|
||||
Your functions will start much quicker if you can use functional bean definitions instead of `@Bean`. To do this make your main class
|
||||
@@ -37,6 +39,7 @@ public class FuncApplication implements ApplicationContextInitializer<GenericApp
|
||||
}
|
||||
```
|
||||
|
||||
[[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.
|
||||
@@ -44,8 +47,10 @@ Upon each invocation the framework will add `aws-context` message header contain
|
||||
you can simply have `Message<YourPojo>` as an input parameter to your function and then access `aws-context` from message headers.
|
||||
For convenience we provide AWSLambdaUtils.AWS_CONTEXT constant.
|
||||
|
||||
[[platform-specific-features]]
|
||||
== Platform Specific Features
|
||||
|
||||
[[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<S>,Message<T>>`, 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).
|
||||
@@ -62,6 +67,7 @@ The supported AWS services and generic handler types are listed below:
|
||||
|
||||
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<Foo>,Message<Bar>>` 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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
:branch: master
|
||||
|
||||
[[microsoft-azure-functions]]
|
||||
== Microsoft Azure Functions
|
||||
:sectnums:
|
||||
|
||||
@@ -19,10 +20,12 @@ With the Azure Web Adapter you can deploy any Spring Web application as an Azure
|
||||
This adapter hides the Azure annotations complexity and uses the familiar https://docs.spring.io/spring-boot/docs/current/reference/html/web.html[Spring Web] programming model instead.
|
||||
For further information follow the <<azure.web.adapter,Azure Web Adapter>> section below.
|
||||
|
||||
[[azure-adapter]]
|
||||
== Azure Adapter
|
||||
|
||||
Provides `Spring` & `Spring Cloud Function` integration for Azure Functions.
|
||||
|
||||
[[dependencies]]
|
||||
=== Dependencies
|
||||
|
||||
In order to enable the Azure Function integration add the azure adapter dependency to your `pom.xml` or `build.gradle`
|
||||
@@ -127,6 +130,7 @@ public class HttpTriggerDemoApplication {
|
||||
<1> The `@SpringBootApplication` annotated class is used as a `Main-Class` as explained in <<star-class-configuration, main class configuration>>.
|
||||
<2> Functions auto-wired and used in the Azure function handlers.
|
||||
|
||||
[[function-catalog]]
|
||||
==== Function Catalog
|
||||
|
||||
The Spring Cloud Function supports a range of type signatures for user-defined functions, while providing a consistent execution model.
|
||||
@@ -137,6 +141,7 @@ But those are treated as plain Java class instances, not as a canonical Spring C
|
||||
|
||||
To leverage Spring Cloud Function and have access to the canonical function representations, you need to auto-wire the `FunctionCatalog` and use it in your handler, like the `functionCatalog` instance the `springCloudFunction()` handler above.
|
||||
|
||||
[[accessing-azure-executioncontext]]
|
||||
==== Accessing Azure ExecutionContext
|
||||
|
||||
Some time there is a need to access the target execution context provided by the Azure runtime in the form of `com.microsoft.azure.functions.ExecutionContext`.
|
||||
@@ -186,6 +191,7 @@ Usually the Azure Maven (or Gradle) plugins are used to generate the necessary c
|
||||
IMPORTANT: The Azure https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-java?tabs=bash%2Cconsumption#folder-structure[packaging format] is not compatible with the default Spring Boot packaging (e.g. `uber jar`).
|
||||
The <<disable.spring.boot.plugin,Disable Spring Boot Plugin>> section below explains how to handle this.
|
||||
|
||||
[[azure-maven/gradle-plugins]]
|
||||
==== Azure Maven/Gradle Plugins
|
||||
|
||||
Azure provides https://github.com/microsoft/azure-maven-plugins/tree/develop/azure-functions-maven-plugin[Maven] and https://github.com/microsoft/azure-gradle-plugins/tree/master/azure-functions-gradle-plugin[Gradle] plugins to process the annotated classes, generate the necessary configurations and produce the expected package layout.
|
||||
@@ -327,6 +333,7 @@ For local runs, add the `MAIN_CLASS` variable to your `local.settings.json` file
|
||||
|
||||
IMPORTANT: If the `MAIN_CLASS` variable is not set, the Azure adapter lookups the `MANIFEST/META-INFO` attributes from the jars found on the classpath and selects the first `Main-Class:` annotated with either a `@SpringBootApplication` or `@SpringBootConfiguration` annotation.
|
||||
|
||||
[[metadata-configuration]]
|
||||
==== Metadata Configuration
|
||||
|
||||
You can use a shared https://learn.microsoft.com/en-us/azure/azure-functions/functions-host-json[host.json] file to configure the function app.
|
||||
@@ -346,6 +353,7 @@ The host.json metadata file contains configuration options that affect all funct
|
||||
|
||||
TIP: If the file is not in the project top folder you need to configure your plugins accordingly (like `hostJson` maven attribute).
|
||||
|
||||
[[samples]]
|
||||
=== Samples
|
||||
|
||||
Here is a list of various Spring Cloud Function Azure Adapter samples you can explore:
|
||||
@@ -389,6 +397,7 @@ dependencies {
|
||||
The same <<azure.configuration, Configuration>> and <<azure.usage,Usage>> instructions apply to the `Azure Web Adapter` as well.
|
||||
|
||||
|
||||
[[samples]]
|
||||
=== Samples
|
||||
|
||||
For further information, explore the following, Azure Web Adapter, sample:
|
||||
@@ -400,6 +409,7 @@ For further information, explore the following, Azure Web Adapter, sample:
|
||||
|
||||
Common instructions for building and deploying both, `Azure Adapter` and `Azure Web Adapter` type of applications.
|
||||
|
||||
[[build]]
|
||||
=== Build
|
||||
|
||||
====
|
||||
@@ -416,6 +426,7 @@ Common instructions for building and deploying both, `Azure Adapter` and `Azure
|
||||
----
|
||||
====
|
||||
|
||||
[[running-locally]]
|
||||
=== Running locally
|
||||
|
||||
To run locally on top of `Azure Functions`, and to deploy to your live Azure environment, you will need `Azure Functions Core Tools` installed along with the Azure CLI (see https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-java?tabs=bash%2Cazure-cli%2Cbrowser#configure-your-local-environment[here]).
|
||||
@@ -437,6 +448,7 @@ Then run the sample:
|
||||
----
|
||||
====
|
||||
|
||||
[[running-on-azure]]
|
||||
=== Running on Azure
|
||||
|
||||
Make sure you are logged in your Azure account.
|
||||
@@ -461,6 +473,7 @@ and deploy
|
||||
----
|
||||
====
|
||||
|
||||
[[debug-locally]]
|
||||
=== Debug locally
|
||||
|
||||
Run the function in debug mode.
|
||||
@@ -516,12 +529,14 @@ Here is snippet for a `VSCode` remote debugging configuration:
|
||||
}
|
||||
----
|
||||
|
||||
[[functioninvoker-deprecated]]
|
||||
== FunctionInvoker (deprecated)
|
||||
|
||||
WARNING: The legacy `FunctionInvoker` programming model is deprecated and will not be supported going forward.
|
||||
|
||||
For additional documentation and samples about the Function Integration approach follow the https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-function-samples/function-sample-azure/[azure-sample] README and code.
|
||||
|
||||
[[relevant-links]]
|
||||
== Relevant Links
|
||||
|
||||
- https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/getting-started-with-spring-cloud-function-in-azure[Spring Cloud Function in Azure]
|
||||
@@ -530,4 +545,4 @@ For additional documentation and samples about the Function Integration approach
|
||||
- https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-java?tabs=bash%2Cconsumption[Azure Functions Java developer guide]
|
||||
- https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference?tabs=blob[Azure Functions developer guide]
|
||||
|
||||
:sectnums!:
|
||||
:sectnums!:
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
:branch: master
|
||||
|
||||
[[google-cloud-functions]]
|
||||
=== Google Cloud Functions
|
||||
|
||||
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.
|
||||
|
||||
[[project-dependencies]]
|
||||
==== Project Dependencies
|
||||
|
||||
Start by adding the `spring-cloud-function-adapter-gcp` dependency to your project.
|
||||
@@ -62,10 +64,12 @@ NOTE: The function target should always be set to `org.springframework.cloud.fun
|
||||
|
||||
A full example of a working `pom.xml` can be found in the https://github.com/spring-cloud/spring-cloud-function/blob/master/spring-cloud-function-samples/function-sample-gcp-http/pom.xml[Spring Cloud Functions GCP sample].
|
||||
|
||||
[[http-functions]]
|
||||
==== HTTP Functions
|
||||
|
||||
Google Cloud Functions supports deploying https://cloud.google.com/functions/docs/writing/http[HTTP Functions], which are functions that are invoked by HTTP request. The sections below describe instructions for deploying a Spring Cloud Function as an HTTP Function.
|
||||
|
||||
[[getting-started]]
|
||||
===== Getting Started
|
||||
|
||||
Let’s start with a simple Spring Cloud Function example:
|
||||
@@ -106,6 +110,7 @@ Invoke the HTTP function:
|
||||
curl http://localhost:8080/ -d "hello"
|
||||
----
|
||||
|
||||
[[deploy-to-gcp]]
|
||||
===== Deploy to GCP
|
||||
|
||||
Start by packaging your application.
|
||||
@@ -158,6 +163,7 @@ public Function<String, Message<String>> function() {
|
||||
|
||||
|
||||
|
||||
[[background-functions]]
|
||||
==== Background Functions
|
||||
|
||||
Google Cloud Functions also supports deploying https://cloud.google.com/functions/docs/writing/background[Background Functions] which are invoked indirectly in response to an event, such as a message on a https://cloud.google.com/pubsub[Cloud Pub/Sub] topic, a change in a https://cloud.google.com/storage[Cloud Storage] bucket, or a https://firebase.google.com/[Firebase] event.
|
||||
@@ -167,6 +173,7 @@ The `spring-cloud-function-adapter-gcp` allows for functions to be deployed as b
|
||||
The sections below describe the process for writing a Cloud Pub/Sub topic background function.
|
||||
However, there are a number of different event types that can trigger a background function to execute which are not discussed here; these are described in the https://cloud.google.com/functions/docs/calling[Background Function triggers documentation].
|
||||
|
||||
[[getting-started]]
|
||||
===== Getting Started
|
||||
|
||||
Let’s start with a simple Spring Cloud Function which will run as a GCF background function:
|
||||
@@ -259,6 +266,7 @@ curl localhost:8080 -H "Content-Type: application/json" -d '{"data":"hello"}'
|
||||
|
||||
Verify that the function was invoked by viewing the logs.
|
||||
|
||||
[[deploy-to-gcp]]
|
||||
===== Deploy to GCP
|
||||
|
||||
In order to deploy your background function to GCP, first package your application.
|
||||
@@ -287,6 +295,7 @@ Google Cloud Function will now invoke the function every time a message is publi
|
||||
|
||||
For a walkthrough on testing and verifying your background function, see the instructions for running the https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-gcp-background/[GCF Background Function sample].
|
||||
|
||||
[[sample-functions]]
|
||||
==== Sample Functions
|
||||
|
||||
The project provides the following sample functions as reference:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
Spring Cloud Function supports a "functional" style of bean declarations for small apps where you need fast startup. The functional style of bean declaration was a feature of Spring Framework 5.0 with significant enhancements in 5.1.
|
||||
|
||||
[[comparing-functional-with-traditional-bean-definitions]]
|
||||
== Comparing Functional with Traditional Bean Definitions
|
||||
|
||||
Here's a vanilla Spring Cloud Function application from with the
|
||||
@@ -113,6 +114,7 @@ public void initialize(GenericApplicationContext context) {
|
||||
}
|
||||
----
|
||||
|
||||
[[limitations-of-functional-bean-declaration]]
|
||||
== Limitations of Functional Bean Declaration
|
||||
|
||||
Most Spring Cloud Function apps have a relatively small scope compared to the whole of Spring Boot,
|
||||
@@ -128,6 +130,7 @@ functional mode" using `spring.functional.enabled=false` so that Spring Boot can
|
||||
|
||||
Spring Cloud Function supports visualization of functions available in `FunctionCatalog` through Actuator endpoints as well as programmatic way.
|
||||
|
||||
[[programmatic-way]]
|
||||
==== Programmatic way
|
||||
|
||||
To see function available within your application context programmatically all you need is access to `FunctionCatalog`. There you can
|
||||
@@ -143,6 +146,7 @@ Set<String> names = functionCatalog.getNames(null); will list the names of all t
|
||||
. . .
|
||||
----
|
||||
|
||||
[[actuator]]
|
||||
==== Actuator
|
||||
Since actuator and web are optional, you must first add one of the web dependencies as well as add the actuator dependency manually.
|
||||
The following example shows how to add the dependency for the Web framework:
|
||||
@@ -198,6 +202,7 @@ Your output should look something like this:
|
||||
{"type":"SUPPLIER","output-type":"string"}. . .
|
||||
----
|
||||
|
||||
[[testing-functional-applications]]
|
||||
= Testing Functional Applications
|
||||
|
||||
Spring Cloud Function also has some utilities for integration testing that will be very familiar to Spring Boot users.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
[[spring-cloud-function-reference-documentation]]
|
||||
= Spring Cloud Function Reference Documentation
|
||||
Mark Fisher, Dave Syer, Oleg Zhurakousky, Anshul Mehra, Dan Dobrin, Chris Bono, Artem Bilan
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
[[spring-cloud-function]]
|
||||
= Spring Cloud Function
|
||||
|
||||
Mark Fisher, Dave Syer, Oleg Zhurakousky, Anshul Mehra, Dan Dobrin
|
||||
@@ -12,20 +13,24 @@ Mark Fisher, Dave Syer, Oleg Zhurakousky, Anshul Mehra, Dan Dobrin
|
||||
:nofooter:
|
||||
:branch: master
|
||||
|
||||
[[introduction]]
|
||||
== Introduction
|
||||
|
||||
include::_intro.adoc[]
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing-docs.adoc[]
|
||||
|
||||
[[getting-started]]
|
||||
== Getting Started
|
||||
|
||||
include::getting-started.adoc[]
|
||||
|
||||
[[programming-model]]
|
||||
== Programming model
|
||||
|
||||
[[function.catalog]]
|
||||
|
||||
[[function-catalog-and-flexible-function-signatures]]
|
||||
=== Function Catalog and Flexible Function Signatures
|
||||
|
||||
One of the main features of Spring Cloud Function is to adapt and support a range of type signatures for user-defined functions,
|
||||
@@ -42,6 +47,7 @@ your function implementation.
|
||||
Reactive programming model also enables functional support for features that would be otherwise difficult to impossible to implement
|
||||
using imperative programming style. For more on this please read <<Function Arity>> section.
|
||||
|
||||
[[java-8-function-support]]
|
||||
=== Java 8 function support
|
||||
|
||||
Spring Cloud Function embraces and builds on top of the 3 core functional interfaces defined by Java
|
||||
@@ -80,6 +86,7 @@ adapters as well as other frameworks using Spring Cloud Function as the core pro
|
||||
So in summary Spring Cloud Function instruments java functions with additional features to be utilised in variety of execution contexts.
|
||||
|
||||
|
||||
[[function-definition]]
|
||||
==== Function definition
|
||||
While the previous example shows you how to lookup function in FunctionCatalog programmatically, in a typical integration case where Spring Cloud Function used as programming model by another framework (e.fg. Spring Cloud Stream), you declare which functions to use via `spring.cloud.function.definition` property. Knowing that it is important to understand some default behaviour when it comes to discovering functions in `FunctionCatalog`. For example, if you only have one Functional bean in your `ApplicationContext`, the `spring.cloud.function.definition` property typically will not be required, since a single function in `FunctionCatalog` can be looked up by an empty name or any name. For example, assuming that `uppercase` is the only function in your catalog, it can be looked up as `catalog.lookup(null)`, `catalog.lookup(“”)`, `catalog.lookup(“foo”)`
|
||||
That said, for cases where you are using framework such as Spring Cloud Stream which uses `spring.cloud.function.definition` it is best practice and recommended to always use `spring.cloud.function.definition` property.
|
||||
@@ -91,6 +98,7 @@ For example,
|
||||
spring.cloud.function.definition=uppercase
|
||||
----
|
||||
|
||||
[[filtering-ineligible-functions]]
|
||||
==== Filtering ineligible functions
|
||||
A typical Application Context may include beans that are valid java functions, but not intended to be candidates to be registered with `FunctionCatalog`.
|
||||
Such beans could be auto-configurations from other projects or any other beans that qualify to be Java functions.
|
||||
@@ -105,6 +113,7 @@ For example,
|
||||
spring.cloud.function.ineligible-definitions=foo,bar
|
||||
----
|
||||
|
||||
[[supplier]]
|
||||
==== Supplier
|
||||
Supplier can be _reactive_ - `Supplier<Flux<T>>`
|
||||
or _imperative_ - `Supplier<T>`. From the invocation standpoint this should make no difference
|
||||
@@ -138,23 +147,27 @@ public Supplier<Flux<String>> someSupplier() {
|
||||
}
|
||||
----
|
||||
|
||||
[[function]]
|
||||
==== Function
|
||||
Function can also be written in imperative or reactive way, yet unlike Supplier and Consumer there are
|
||||
no special considerations for the implementor other then understanding that when used within frameworks
|
||||
such as https://spring.io/projects/spring-cloud-stream[Spring Cloud Stream] and others, reactive function is
|
||||
invoked only once to pass a reference to the stream (Flux or Mono) and imperative is invoked once per event.
|
||||
|
||||
[[consumer]]
|
||||
==== Consumer
|
||||
Consumer is a little bit special because it has a `void` return type,
|
||||
which implies blocking, at least potentially. Most likely you will not
|
||||
need to write `Consumer<Flux<?>>`, but if you do need to do that,
|
||||
remember to subscribe to the input flux.
|
||||
|
||||
[[function-composition]]
|
||||
=== Function Composition
|
||||
Function Composition is a feature that allows one to compose several functions into one.
|
||||
The core support is based on function composition feature available with https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html#andThen-java.util.function.Function-[Function.andThen(..)]
|
||||
support available since Java 8. However on top of it, we provide few additional features.
|
||||
|
||||
[[declarative-function-composition]]
|
||||
==== Declarative Function Composition
|
||||
|
||||
This feature allows you to provide composition instruction in a declarative way using `|` (pipe) or `,` (comma) delimiter
|
||||
@@ -169,6 +182,7 @@ function `uppercase` and function `reverse`. In fact that is one of the reasons
|
||||
since the definition of a function can be a composition of several named functions.
|
||||
And as mentioned you can use `,` instead of pipe (such as `...definition=uppercase,reverse`).
|
||||
|
||||
[[composing-non-functions]]
|
||||
==== Composing non-Functions
|
||||
Spring Cloud Function also supports composing Supplier with `Consumer` or `Function` as well as `Function` with `Consumer`.
|
||||
What's important here is to understand the end product of such definitions.
|
||||
@@ -178,6 +192,7 @@ Following the same logic composing Function with Consumer will result in Consume
|
||||
And of course you can't compose uncomposable such as Consumer and Function, Consumer and Supplier etc.
|
||||
|
||||
|
||||
[[function-routing-and-filtering]]
|
||||
=== Function Routing and Filtering
|
||||
|
||||
Since version 2.2 Spring Cloud Function provides routing feature allowing
|
||||
@@ -199,6 +214,7 @@ public class RoutingFunction implements Function<Object, Object> {
|
||||
The routing instructions could be communicated in several ways. We support providing instructions via Message headers, System
|
||||
properties as well as pluggable strategy. So let's look at some of the details
|
||||
|
||||
[[messageroutingcallback]]
|
||||
==== MessageRoutingCallback
|
||||
|
||||
The `MessageRoutingCallback` is a strategy to assist with determining the name of the route-to function definition.
|
||||
@@ -299,6 +315,7 @@ public DefaultMessageRoutingHandler defaultRoutingHandler() {
|
||||
}
|
||||
----
|
||||
|
||||
[[function-filtering]]
|
||||
==== Function Filtering
|
||||
Filtering is the type of routing where there are only two paths - 'go' or 'discard'. In terms of functions it mean
|
||||
you only want to invoke a certain function if some condition returns 'true', otherwise you want to discard input.
|
||||
@@ -329,6 +346,7 @@ due to the nature of the reactive functions which are invoked only once to pass
|
||||
is handled by the reactor, hence we can not access and/or rely on the routing instructions communicated via individual
|
||||
values (e.g., Message).
|
||||
|
||||
[[multiple-routers]]
|
||||
==== Multiple Routers
|
||||
|
||||
By default the framework will always have a single routing function configured as described in previous sections. However, there are times when you may need more than one routing function.
|
||||
@@ -381,6 +399,7 @@ public void testMultipleRouters() {
|
||||
}
|
||||
----
|
||||
|
||||
[[input/output-enrichment]]
|
||||
=== Input/Output Enrichment
|
||||
|
||||
There are often times when you need to modify or refine an incoming or outgoing Message and to keep your code clean of non-functional concerns. You don’t want to do it inside of your business logic.
|
||||
@@ -461,6 +480,7 @@ In the event you are dealing with functions that have multiple inputs (next sect
|
||||
--spring.cloud.function.configuration.echo.input-header-mapping-expression[1].key2='hello2'
|
||||
----
|
||||
|
||||
[[function-arity]]
|
||||
=== Function Arity
|
||||
|
||||
There are times when a stream of data needs to be categorized and organized. For example,
|
||||
@@ -496,6 +516,7 @@ IMPORTANT: IMPORTANT: At the moment, function arity is *only* supported for reac
|
||||
where evaluation and computation on confluence of events typically requires view into a
|
||||
stream of events rather than single event.
|
||||
|
||||
[[input-header-propagation]]
|
||||
=== Input Header propagation
|
||||
|
||||
In a typical scenario input Message headers are not propagated to output and rightfully so, since the output of a function may be an input to something else requiring it's own set of Message headers.
|
||||
@@ -531,6 +552,7 @@ Message<byte[]> result = uppercase.apply(MessageBuilder.withPayload("bob").setHe
|
||||
assertThat(result.getHeaders()).containsKey("foo");
|
||||
----
|
||||
|
||||
[[type-conversion-content-type-negotiation]]
|
||||
=== Type conversion (Content-Type negotiation)
|
||||
|
||||
Content-Type negotiation is one of the core features of Spring Cloud Function as it allows to not only transform the incoming data to the types declared
|
||||
@@ -569,6 +591,7 @@ For example, HTTP POST request will have its content-type HTTP header copied to
|
||||
For cases when such header does not exist framework relies on the default content type as `application/json`.
|
||||
|
||||
|
||||
[[content-type-versus-argument-type]]
|
||||
==== Content Type versus Argument Type
|
||||
|
||||
As mentioned earlier, for the framework to select the appropriate `MessageConverter`, it requires argument type and, optionally, content type information.
|
||||
@@ -586,6 +609,7 @@ NOTE: Do not expect `Message` to be converted into some other type based only on
|
||||
Remember that the `contentType` is complementary to the target type.
|
||||
It is a hint, which `MessageConverter` may or may not take into consideration.
|
||||
|
||||
[[message-converters]]
|
||||
==== Message Converters
|
||||
|
||||
`MessageConverters` define two methods:
|
||||
@@ -604,6 +628,7 @@ The payload of the `Message` could be any type, and it is
|
||||
up to the actual implementation of the `MessageConverter` to support multiple types.
|
||||
|
||||
|
||||
[[provided-messageconverters]]
|
||||
==== Provided MessageConverters
|
||||
|
||||
As mentioned earlier, the framework already provides a stack of `MessageConverters` to handle most common use cases.
|
||||
@@ -662,6 +687,7 @@ public class MyCustomMessageConverter extends AbstractMessageConverter {
|
||||
}
|
||||
----
|
||||
|
||||
[[note-on-json-options]]
|
||||
==== Note on JSON options
|
||||
|
||||
In Spring Cloud Function we support Jackson and Gson mechanisms to deal with JSON.
|
||||
@@ -677,6 +703,7 @@ That said, the type conversion is usually transparent to the developer, however
|
||||
you can easily inject it into your code if needed.
|
||||
|
||||
|
||||
[[kotlin-lambda-support]]
|
||||
=== Kotlin Lambda support
|
||||
|
||||
We also provide support for Kotlin lambdas (since v2.0).
|
||||
@@ -708,12 +735,14 @@ same rules for signature transformation outlined in "Java 8 function support" se
|
||||
To enable Kotlin support all you need is to add Kotlin SDK libraries on the classpath which will trigger appropriate
|
||||
autoconfiguration and supporting classes.
|
||||
|
||||
[[function-component-scan]]
|
||||
=== Function Component Scan
|
||||
|
||||
Spring Cloud Function will scan for implementations of `Function`, `Consumer` and `Supplier` in a package called `functions` if it exists. Using this
|
||||
feature you can write functions that have no dependencies on Spring - not even the `@Component` annotation is needed. If you want to use a different
|
||||
package, you can set `spring.cloud.function.scan.packages`. You can also use `spring.cloud.function.scan.enabled=false` to switch off the scan completely.
|
||||
|
||||
[[standalone-web-applications]]
|
||||
== Standalone Web Applications
|
||||
|
||||
Functions could be automatically exported as HTTP endpoints.
|
||||
@@ -756,6 +785,7 @@ When POSTing text the response format might be different with Spring Boot 2.0 an
|
||||
|
||||
See <<Testing Functional Applications>> to see the details and example on how to test such application.
|
||||
|
||||
[[http-request-parameters]]
|
||||
==== HTTP Request Parameters
|
||||
As you have noticed from the previous table, you can pass an argument to a function as path variable (i.e., `/{function}/{item}`).
|
||||
For example, `http://localhost:8080/uppercase/foo` will result in calling `uppercase` function with its input parameter being `foo`.
|
||||
@@ -764,6 +794,7 @@ While this is the recommended approach and the one that fits most use cases case
|
||||
The framework will treat HTTP request parameters similar to the HTTP headers by storing them in the `Message` headers under the header key `http_request_param`
|
||||
with its value being a `Map` of request parameters, so in order to access them your function input signature should accept `Message` type (e.g., `Function<Message<String>, String>`). For convenience we provide `HeaderUtils.HTTP_REQUEST_PARAM` constant.
|
||||
|
||||
[[function-mapping-rules]]
|
||||
=== Function Mapping rules
|
||||
|
||||
If there is only a single function (consumer etc.) in the catalog, the name in the path is optional.
|
||||
@@ -790,6 +821,7 @@ However there are function `foo` and `bar`. So, in this case `localhost:8080/upp
|
||||
This could be useful especially for cases when URL is used to communicate certain information since there will be Message header called `uri` with the value
|
||||
of the actual URL, giving user ability to use it for evaluation and computation.
|
||||
|
||||
[[function-filtering-rules]]
|
||||
=== Function Filtering rules
|
||||
|
||||
In situations where there are more than one function in catalog there may be a need to only export certain functions or function compositions. In that case you can use
|
||||
@@ -810,6 +842,7 @@ This will only export function `foo` and function `bar` regardless how many func
|
||||
|
||||
This will only export function composition `foo|bar` and function `baz` regardless how many functions are available in catalog (e.g., `localhost:8080/foo,bar`).
|
||||
|
||||
[[crud-rest-with-spring-cloud-function]]
|
||||
=== CRUD REST with Spring Cloud Function
|
||||
|
||||
By now it should be clear that functions are exported as REST endpoints and can be invoked using various HTTP methods. In other words a single
|
||||
@@ -829,11 +862,13 @@ spring.cloud.function.http.DELETE=deleteById
|
||||
|
||||
As you can see, here we’re mapping functions to various HTTP methods using the same rules as `spring.cloud.function.definition` property where “;” allows us to define several functions and “|” signifies function composition.
|
||||
|
||||
[[standalone-streaming-applications]]
|
||||
== Standalone Streaming Applications
|
||||
|
||||
To send or receive messages from a broker (such as RabbitMQ or Kafka) you can leverage `spring-cloud-stream` project and it's integration with Spring Cloud Function.
|
||||
Please refer to https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/current/reference/html/spring-cloud-stream.html#spring_cloud_function[Spring Cloud Function] section of the https://spring.io/projects/spring-cloud-stream[Spring Cloud Stream] reference manual for more details and examples.
|
||||
|
||||
[[deploying-a-packaged-function]]
|
||||
== Deploying a Packaged Function
|
||||
|
||||
Spring Cloud Function provides a "deployer" library that allows you to launch a jar file (or exploded archive, or set of jar files) with an isolated class loader and expose the functions defined in it. This is quite a powerful tool that would allow you to, for instance, adapt a function to a range of different input-output adapters without changing the target jar file. Serverless platforms often have this kind of feature built in, so you could see it as a building block for a function invoker in such a platform (indeed the https://projectriff.io[Riff] Java function invoker uses this library).
|
||||
@@ -907,10 +942,12 @@ public MavenProperties mavenProperties() {
|
||||
}
|
||||
```
|
||||
|
||||
[[supported-packaging-scenarios]]
|
||||
=== Supported Packaging Scenarios
|
||||
|
||||
Currently Spring Cloud Function supports several packaging scenarios to give you the most flexibility when it comes to deploying functions.
|
||||
|
||||
[[simple-jar]]
|
||||
==== Simple JAR
|
||||
|
||||
This packaging option implies no dependency on anything related to Spring.
|
||||
@@ -954,6 +991,7 @@ package named `functions`, you can omit `spring.cloud.function.function-class` p
|
||||
Keep in mind the naming convention to follow when doing function lookup. For example function class `functions.UpperCaseFunction` will be available in `FunctionCatalog`
|
||||
under the name `upperCaseFunction`.
|
||||
|
||||
[[spring-boot-jar]]
|
||||
==== Spring Boot JAR
|
||||
|
||||
This packaging option implies there is a dependency on Spring Boot and that the JAR was generated as Spring Boot JAR. That said, given that the deployed JAR
|
||||
@@ -978,6 +1016,7 @@ As before all you need to do is specify `location` and `function-class` properti
|
||||
For more details please reference the complete sample available https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-deployer/src/it/bootjar[here].
|
||||
You can also find a corresponding test in https://github.com/spring-cloud/spring-cloud-function/blob/master/spring-cloud-function-deployer/src/test/java/org/springframework/cloud/function/deployer/FunctionDeployerTests.java#L50[FunctionDeployerTests].
|
||||
|
||||
[[spring-boot-application]]
|
||||
==== Spring Boot Application
|
||||
|
||||
This packaging option implies your JAR is complete stand alone Spring Boot application with functions as managed Spring beans.
|
||||
@@ -1012,10 +1051,12 @@ You can also find a corresponding test in https://github.com/spring-cloud/spring
|
||||
|
||||
NOTE: This particular deployment option may or may not have Spring Cloud Function on it's classpath. From the deployer perspective this doesn't matter.
|
||||
|
||||
[[functional-bean-definitions]]
|
||||
== Functional Bean Definitions
|
||||
|
||||
include::functional.adoc[leveloffset=+1]
|
||||
|
||||
[[serverless-platform-adapters]]
|
||||
== Serverless Platform Adapters
|
||||
|
||||
As well as being able to run as a standalone process, a Spring Cloud
|
||||
|
||||
Reference in New Issue
Block a user