Introducing spring-cloud-function-integration
Spring Integration Java DSL, is a tool to compose integration flows programmatically. We can build the flow not only based on standard EIP components, but also using protocol-specific channel adapters. Any generic services also can be used as handler in the flow. This includes simple lambda operations or functions. On the other hand Spring Cloud Function provides a `FunctionCatalog` for registered functions and their compositions & conversions. With this change we introduce a more high-level DSL to use functions from catalog directly in the `IntegrationFlow` to gain the best from both worlds. * Introduce `spring-cloud-function-integration` module based on `spring-cloud-function-context` and `spring-boot-starter-integration` * Expose a `FunctionFlowBuilder` auto-configuration * Add `FunctionFlowDefinition` to expose `apply()` and `accept()` operators * Document this new module
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
= Spring Cloud Function Reference Documentation
|
||||
Mark Fisher, Dave Syer, Oleg Zhurakousky, Anshul Mehra, Dan Dobrin, Chris Bono
|
||||
Mark Fisher, Dave Syer, Oleg Zhurakousky, Anshul Mehra, Dan Dobrin, Chris Bono, Artem Bilan
|
||||
|
||||
*{project-version}*
|
||||
|
||||
@@ -11,6 +11,7 @@ The reference documentation consists of the following sections:
|
||||
<<spring-cloud-function.adoc#,Reference Guide>> :: Spring Cloud Function Reference
|
||||
https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-cloudevent[Cloud Events] :: Cloud Events
|
||||
https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-rsocket[RSocket] :: RSocket
|
||||
<<./spring-integration.adoc#spring-integration,Spring Integration>> :: Spring Integration Framework Interaction
|
||||
<<aws.adoc#,AWS Adapter>> :: AWS Adapter Reference
|
||||
<<azure.adoc#, Azure Adapter>> :: Azure Adapter Reference
|
||||
<<gcp.adoc#, GCP Adapter>> :: GCP Adapter Reference
|
||||
|
||||
101
docs/src/main/asciidoc/spring-integration.adoc
Normal file
101
docs/src/main/asciidoc/spring-integration.adoc
Normal file
@@ -0,0 +1,101 @@
|
||||
[[spring-integration]]
|
||||
== Spring Integration Interaction
|
||||
|
||||
https://spring.io/projects/spring-integration[Spring Integration Framework] extends the Spring programming model to support the well-known Enterprise Integration Patterns.
|
||||
It enables lightweight messaging within Spring-based applications and supports integration with external systems via declarative adapters.
|
||||
It also provides a high-level DSL to compose various operations (endpoints) into a logical integration flow.
|
||||
With a lambda style of this DSL configuration, Spring Integration already has a good level of `java.util.function` interfaces adoption.
|
||||
The `@MessagingGateway` proxy interface can also be as a `Function` or `Consumer`, which according to the Spring Cloud Function environment can be registered into a function catalog.
|
||||
See more information in Spring Integration https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#functions-support[ReferenceManual] about its support for functions.
|
||||
|
||||
On the other hand, starting with version `4.0.3`, Spring Cloud Function introduces a `spring-cloud-function-integration` module which provides deeper, more cloud-specific and auto-configuration based API for interaction with a `FunctionCatalog` from Spring Integration DSL perspective.
|
||||
The `FunctionFlowBuilder` is auto-configured and autowired with a `FunctionCatalog` and represents an entry point for function-specific DSL for target `IntegrationFlow` instance.
|
||||
In addition to standard `IntegrationFlow.from()` factories (for convenience), the `FunctionFlowBuilder` exposes a `fromSupplier(String supplierDefinition)` factory to lookup the target `Supplier` in the provided `FunctionCatalog`.
|
||||
Then this `FunctionFlowBuilder` leads to the `FunctionFlowDefinition`.
|
||||
This `FunctionFlowDefinition` is an implementation of the `IntegrationFlowExtension` and exposes `apply(String functionDefinition)` and `accept(String consumerDefinition)` operators to lookup `Function` or `Consumer` from the `FunctionCatalog`, respectively.
|
||||
See their Javadocs for more information.
|
||||
|
||||
The following example demonstrates the `FunctionFlowBuilder` in action alongside with the power of the rest of `IntegrationFlow` API:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Configuration
|
||||
static class IntegrationConfiguration {
|
||||
|
||||
@Bean
|
||||
Supplier<byte[]> simpleByteArraySupplier() {
|
||||
return "simple test data"::getBytes;
|
||||
}
|
||||
|
||||
@Bean
|
||||
Function<String, String> upperCaseFunction() {
|
||||
return String::toUpperCase;
|
||||
}
|
||||
|
||||
@Bean
|
||||
BlockingQueue<String> results() {
|
||||
return new LinkedBlockingQueue<>();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Consumer<String> simpleStringConsumer(BlockingQueue<String> results) {
|
||||
return results::add;
|
||||
}
|
||||
|
||||
@Bean
|
||||
QueueChannel wireTapChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
IntegrationFlow someFunctionFlow(FunctionFlowBuilder functionFlowBuilder) {
|
||||
return functionFlowBuilder
|
||||
.fromSupplier("simpleByteArraySupplier")
|
||||
.wireTap("wireTapChannel")
|
||||
.apply("upperCaseFunction")
|
||||
.log(LoggingHandler.Level.WARN)
|
||||
.accept("simpleStringConsumer");
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Since the `FunctionCatalog.lookup()` functionality is not limited just to simple function names, a function composition feature can also be used in the mentioned `apply()` and `accept()` operators:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
IntegrationFlow functionCompositionFlow(FunctionFlowBuilder functionFlowBuilder) {
|
||||
return functionFlowBuilder
|
||||
.from("functionCompositionInput")
|
||||
.accept("upperCaseFunction|simpleStringConsumer");
|
||||
}
|
||||
----
|
||||
|
||||
This API becomes more relevant, when we add into our Spring Cloud applications auto-configuration dependencies for predefined functions.
|
||||
For example https://spring.io/projects/spring-cloud-stream-applications[Stream Applications] project, in addition to application images, provides artifacts with functions for various integration use-case, e.g. `debezium-supplier`, `elasticsearch-consumer`, `aggregator-function` etc.
|
||||
|
||||
The following configuration is based on the `http-supplier`, `spel-function` and `file-consumer`, respectively:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
IntegrationFlow someFunctionFlow(FunctionFlowBuilder functionFlowBuilder) {
|
||||
return functionFlowBuilder
|
||||
.fromSupplier("httpSupplier", e -> e.poller(Pollers.trigger(new OnlyOnceTrigger())))
|
||||
.<Flux<?>>handle((fluxPayload, headers) -> fluxPayload, e -> e.async(true))
|
||||
.channel(c -> c.flux())
|
||||
.apply("spelFunction")
|
||||
.<String, String>transform(String::toUpperCase)
|
||||
.accept("fileConsumer");
|
||||
}
|
||||
----
|
||||
|
||||
What we would need else is just to add their configuration into an `application.properties` (if necessary):
|
||||
|
||||
[source,properties]
|
||||
----
|
||||
http.path-pattern=/testPath
|
||||
spel.function.expression=new String(payload)
|
||||
file.consumer.name=test-data.txt
|
||||
----
|
||||
Reference in New Issue
Block a user