Insert explicit ids for headers

This commit is contained in:
Marcin Grzejszczak
2023-09-08 15:45:30 +02:00
parent b80f431964
commit 29708de88f
8 changed files with 94 additions and 1 deletions

View File

@@ -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[]

View File

@@ -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

View File

@@ -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

View File

@@ -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!:

View File

@@ -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
Lets 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
Lets 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:

View File

@@ -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.

View File

@@ -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

View File

@@ -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 dont 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 were 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