Fix indentation for all pages
This commit is contained in:
@@ -11,20 +11,21 @@ image::https://codecov.io/gh/spring-cloud/spring-cloud-stream/branch/{github-tag
|
||||
// ======================================================================================
|
||||
|
||||
[[introduction]]
|
||||
== Introduction
|
||||
= Introduction
|
||||
|
||||
include::intro.adoc[]
|
||||
|
||||
[[resources]]
|
||||
== Resources
|
||||
= Resources
|
||||
|
||||
For more information, please visit the https://spring.io/projects/spring-cloud-stream[project website]:
|
||||
|
||||
[[building]]
|
||||
== Building
|
||||
= Building
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building.adoc[]
|
||||
|
||||
[[contributing]]
|
||||
== Contributing
|
||||
= Contributing
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
*{project-version}*
|
||||
|
||||
[[binders]]
|
||||
== Binder Implementations
|
||||
= Binder Implementations
|
||||
|
||||
The following binder implementations are available:
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ While these two binder implementations are based on Message Channels, Spring Clo
|
||||
Below, you can find more information on how to use these various out-of-the-box binder implementations in your applications.
|
||||
|
||||
[[apache-kafka-binder]]
|
||||
== Apache Kafka Binder
|
||||
= Apache Kafka Binder
|
||||
|
||||
[[usage]]
|
||||
=== Usage
|
||||
== Usage
|
||||
|
||||
To use Apache Kafka binder, you need to add `spring-cloud-stream-binder-kafka` as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven:
|
||||
|
||||
@@ -34,10 +34,10 @@ Alternatively, you can also use the Spring Cloud Stream Kafka Starter, as shown
|
||||
----
|
||||
|
||||
[[apache-kafka-streams-binder]]
|
||||
== Apache Kafka Streams Binder
|
||||
= Apache Kafka Streams Binder
|
||||
|
||||
[[usage]]
|
||||
=== Usage
|
||||
== Usage
|
||||
|
||||
To use Apache Kafka Streams binder, you need to add `spring-cloud-stream-binder-kafka-streams` as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven:
|
||||
|
||||
@@ -50,9 +50,9 @@ To use Apache Kafka Streams binder, you need to add `spring-cloud-stream-binder-
|
||||
----
|
||||
|
||||
[[rabbitmq-binder]]
|
||||
== RabbitMQ Binder
|
||||
= RabbitMQ Binder
|
||||
[[usage]]
|
||||
=== Usage
|
||||
== Usage
|
||||
|
||||
To use the RabbitMQ binder, you can add it to your Spring Cloud Stream application, by using the following Maven coordinates:
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[[reactive-kafka-binder]]
|
||||
== Reactive Kafka Binder
|
||||
= Reactive Kafka Binder
|
||||
|
||||
Kafka binder in Spring Cloud Stream provides a dedicated reactive binder based on the https://projectreactor.io/docs/kafka/release/reference/[Reactor Kafka] project.
|
||||
This reactive Kafka binder enables full end-to-end reactive capabilities such as backpressure, reactive streams etc. in applications based on Apache Kafka.
|
||||
When your Spring Cloud Stream Kafka application is written using reactive types (`Flux`, `Mono` etc.), it is recommended to use this reactive Kafka binder instead of the regular message channel based Kafka binder.
|
||||
|
||||
[[maven-coordinates]]
|
||||
=== Maven Coordinates
|
||||
== Maven Coordinates
|
||||
|
||||
Following are the maven coordinates for the reactive Kafka binder.
|
||||
|
||||
@@ -18,7 +18,7 @@ Following are the maven coordinates for the reactive Kafka binder.
|
||||
```
|
||||
|
||||
[[basic-example-using-the-reactive-kafka-binder]]
|
||||
=== Basic Example using the Reactive Kafka Binder
|
||||
== Basic Example using the Reactive Kafka Binder
|
||||
|
||||
In this section, we show some basic code snippets for writing a reactive Kafka application using the reactive binder and details around them.
|
||||
|
||||
@@ -96,7 +96,7 @@ Given that Spring has no access to the contents of the inner flux, the applicati
|
||||
This requires the use of native decoding (by specifying a `Deserializer` of the appropriate type in the configuration) to return record keys/values of the desired types.
|
||||
|
||||
[[consuming-records-in-the-raw-format]]
|
||||
=== Consuming Records in the Raw Format
|
||||
== Consuming Records in the Raw Format
|
||||
|
||||
In the above `upppercase` function, we are consuming the record as `Flux<String>` and then produce it as `Flux<String>`.
|
||||
There might be occasions in which you need to receive the record in the original received format - the `ReceiverRecord`.
|
||||
@@ -163,7 +163,7 @@ If `reactiveAutoCommit` is `false` (default), call `rec.receiverOffset().acknowl
|
||||
Refer to the `reactor-kafka` documentation and javadocs for more information.
|
||||
|
||||
[[concurrency]]
|
||||
=== Concurrency
|
||||
== Concurrency
|
||||
|
||||
When using reactive functions with the reactive Kafka binder, if you set concurrency on the consumer binding, then the binder creates as many dedicated `KafkaReceiver` objects as provided by the concurrency value.
|
||||
In other words, this creates multiple reactive streams with separate `Flux` implementations.
|
||||
@@ -179,19 +179,19 @@ spring.cloud.stream.bindings.lowercase-in-0.consumer.concurrency=3
|
||||
That will create three dedicated `KafkaReceiver` objects that generate three separate `Flux` implementations and then stream them to the handler method.
|
||||
|
||||
[[multiplex]]
|
||||
=== Multiplex
|
||||
== Multiplex
|
||||
|
||||
Starting with version 4.0.3, the common consumer property `multiplex` is now supported by the reactive binder, where a single binding can consume from multiple topics.
|
||||
When `false` (default), a separate binding is created for each topic specified in a comma-delimited list in the common `destination` property.
|
||||
|
||||
[[destination-is-pattern]]
|
||||
=== Destination is Pattern
|
||||
== Destination is Pattern
|
||||
|
||||
Starting with version 4.0.3, the `destination-is-pattern` Kafka binding consumer property is now supported.
|
||||
The receiver options are conigured with a regex `Pattern`, allowing the binding to consume from any topic that matches the pattern.
|
||||
|
||||
[[sender-result-channel]]
|
||||
=== Sender Result Channel
|
||||
== Sender Result Channel
|
||||
|
||||
Starting with version 4.0.3, you can configure the `resultMetadataChannel` to receive `SenderResult<?>` s to determine success/failure of sends.
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[[kafka-streams-binder]]
|
||||
== Kafka Streams Binder
|
||||
= Kafka Streams Binder
|
||||
|
||||
|
||||
[[usage]]
|
||||
=== Usage
|
||||
== Usage
|
||||
|
||||
For using the Kafka Streams binder, you just need to add it to your Spring Cloud Stream application, using the following maven coordinates:
|
||||
|
||||
@@ -20,7 +20,7 @@ A quick way to bootstrap a new project for Kafka Streams binder is to use http:/
|
||||
image::{github-raw}/docs/src/main/asciidoc/images/spring-initializr-kafka-streams.png[width=800,scaledwidth="75%",align="center"]
|
||||
|
||||
[[overview]]
|
||||
=== Overview
|
||||
== Overview
|
||||
|
||||
Spring Cloud Stream includes a binder implementation designed explicitly for https://kafka.apache.org/documentation/streams/[Apache Kafka Streams] binding.
|
||||
With this native integration, a Spring Cloud Stream "processor" application can directly use the
|
||||
@@ -36,13 +36,13 @@ Alternatively, a Processor application with no outbound destination can be defin
|
||||
In the following sections, we are going to look at the details of Spring Cloud Stream's integration with Kafka Streams.
|
||||
|
||||
[[programming-model]]
|
||||
=== Programming Model
|
||||
== Programming Model
|
||||
|
||||
When using the programming model provided by Kafka Streams binder, both the high-level https://docs.confluent.io/current/streams/developer-guide/dsl-api.html[Streams DSL] and a mix of both the higher level and the lower level https://docs.confluent.io/current/streams/developer-guide/processor-api.html[Processor-API] can be used as options.
|
||||
When mixing both higher and lower level API's, this is usually achieved by invoking `transform` or `process` API methods on `KStream`.
|
||||
|
||||
[[functional-style]]
|
||||
==== Functional Style
|
||||
=== Functional Style
|
||||
|
||||
Starting with Spring Cloud Stream `3.0.0`, Kafka Streams binder allows the applications to be designed and developed using the functional programming style that is available in Java 8.
|
||||
This means that the applications can be concisely represented as a lambda expression of types `java.util.function.Function` or `java.util.function.Consumer`.
|
||||
@@ -161,7 +161,7 @@ In addition, you can also provide topic patterns as destinations if you want to
|
||||
`spring.cloud.stream.bindings.process-in-0.destination=input.*`
|
||||
|
||||
[[multiple-input-bindings]]
|
||||
===== Multiple Input Bindings
|
||||
==== Multiple Input Bindings
|
||||
|
||||
Many non-trivial Kafka Streams applications often consume data from more than one topic through multiple bindings.
|
||||
For instance, one topic is consumed as `Kstream` and another as `KTable` or `GlobalKTable`.
|
||||
@@ -171,7 +171,7 @@ If the application specifies that the data needs to be bound as `KTable` or `Glo
|
||||
We will look at a few different scenarios how multiple input bindings are handled in the Kafka Streams binder.
|
||||
|
||||
[[bifunction-in-kafka-streams-binder]]
|
||||
====== BiFunction in Kafka Streams Binder
|
||||
===== BiFunction in Kafka Streams Binder
|
||||
|
||||
Here is an example where we have two inputs and an output. In this case, the application can leverage on `java.util.function.BiFunction`.
|
||||
|
||||
@@ -197,7 +197,7 @@ The default binding names generated by the binder for the inputs are `process-in
|
||||
In this example, the first parameter of `BiFunction` is bound as a `KStream` for the first input and the second parameter is bound as a `KTable` for the second input.
|
||||
|
||||
[[biconsumer-in-kafka-streams-binder]]
|
||||
====== BiConsumer in Kafka Streams Binder
|
||||
===== BiConsumer in Kafka Streams Binder
|
||||
|
||||
If there are two inputs, but no outputs, in that case we can use `java.util.function.BiConsumer` as shown below.
|
||||
|
||||
@@ -210,7 +210,7 @@ public BiConsumer<KStream<String, Long>, KTable<String, String>> process() {
|
||||
----
|
||||
|
||||
[[beyond-two-inputs]]
|
||||
====== Beyond two inputs
|
||||
===== Beyond two inputs
|
||||
|
||||
What if you have more than two inputs?
|
||||
There are situations in which you need more than two inputs. In that case, the binder allows you to chain partial functions.
|
||||
@@ -264,7 +264,7 @@ With curried functions, you can virtually have any number of inputs. However, ke
|
||||
Therefore if your Kafka Streams application requires more than a reasonably smaller number of input bindings, and you want to use this functional model, then you may want to rethink your design and decompose the application appropriately.
|
||||
|
||||
[[output-bindings]]
|
||||
===== Output Bindings
|
||||
==== Output Bindings
|
||||
|
||||
Kafka Streams binder allows types of either `KStream` or `KTable` as output bindings.
|
||||
Behind the scenes, the binder uses the `to` method on `KStream` to send the resultant records to the output topic.
|
||||
@@ -286,7 +286,7 @@ public Function<KTable<String, String>, KStream<String, String>> bar() {
|
||||
```
|
||||
|
||||
[[multiple-output-bindings]]
|
||||
===== Multiple Output Bindings
|
||||
==== Multiple Output Bindings
|
||||
|
||||
Kafka Streams allows writing outbound data into multiple topics. This feature is known as branching in Kafka Streams.
|
||||
When using multiple output bindings, you need to provide an array of KStream (`KStream[]`) as the outbound return type.
|
||||
@@ -328,7 +328,7 @@ The reason why the binder generates three output bindings is because it detects
|
||||
Note that in this example, we provide a `noDefaultBranch()`; if we have used `defaultBranch()` instead, that would have required an extra output binding, essentially returning a `KStream` array of length four.
|
||||
|
||||
[[summary-of-function-based-programming-styles-for-kafka-streams]]
|
||||
===== Summary of Function based Programming Styles for Kafka Streams
|
||||
==== Summary of Function based Programming Styles for Kafka Streams
|
||||
|
||||
In summary, the following table shows the various options that can be used in the functional paradigm.
|
||||
|
||||
@@ -346,7 +346,7 @@ In summary, the following table shows the various options that can be used in th
|
||||
* In the case of more than one output in this table, the type simply becomes `KStream[]`.
|
||||
|
||||
[[function-composition-in-kafka-streams-binder]]
|
||||
===== Function composition in Kafka Streams binder
|
||||
==== Function composition in Kafka Streams binder
|
||||
|
||||
Kafka Streams binder supports minimal forms of functional composition for linear topologies.
|
||||
Using the Java functional API support, you can write multiple functions and then compose them on your own using the `andThen` method.
|
||||
@@ -391,7 +391,7 @@ spring.cloud.function.definition=foo|bar;foo;bar
|
||||
The composed function's default binding names in this example becomes `foobar-in-0` and `foobar-out-0`.
|
||||
|
||||
[[limitations-of-functional-composition-in-kafka-streams-bincer]]
|
||||
====== Limitations of functional composition in Kafka Streams bincer
|
||||
===== Limitations of functional composition in Kafka Streams bincer
|
||||
|
||||
When you have `java.util.function.Function` bean, that can be composed with another function or multiple functions.
|
||||
The same function bean can be composed with a `java.util.function.Consumer` as well. In this case, consumer is the last component composed.
|
||||
@@ -426,7 +426,7 @@ The default input bindings in this case are going to be `curriedFoobar-in-0` and
|
||||
The default output binding for this example becomes `curriedFoobar-out-0`.
|
||||
|
||||
[[special-note-on-using-ktable-as-output-in-function-composition]]
|
||||
====== Special note on using `KTable` as output in function composition
|
||||
===== Special note on using `KTable` as output in function composition
|
||||
|
||||
Lets say you have the following two functions.
|
||||
|
||||
@@ -446,10 +446,10 @@ public Function<KTable<String, String>, KStream<String, String>> bar() {
|
||||
You can compose them as `foo|bar`, but keep in mind that the second function (`bar` in this case) must have a `KTable` as input since the first function (`foo`) has `KTable` as output.
|
||||
|
||||
[[ancillaries-to-the-programming-model]]
|
||||
=== Ancillaries to the programming model
|
||||
== Ancillaries to the programming model
|
||||
|
||||
[[multiple-kafka-streams-processors-within-a-single-application]]
|
||||
==== Multiple Kafka Streams processors within a single application
|
||||
=== Multiple Kafka Streams processors within a single application
|
||||
|
||||
Binder allows to have multiple Kafka Streams processors within a single Spring Cloud Stream application.
|
||||
You can have an application as below.
|
||||
@@ -483,7 +483,7 @@ If you want certain functions to be not activated right away, you can remove tha
|
||||
This is also true when you have a single Kafka Streams processor and other types of `Function` beans in the same application that is handled through a different binder (for e.g., a function bean that is based on the regular Kafka Message Channel binder)
|
||||
|
||||
[[kafka-streams-application-id]]
|
||||
==== Kafka Streams Application ID
|
||||
=== Kafka Streams Application ID
|
||||
|
||||
Application id is a mandatory property that you need to provide for a Kafka Streams application.
|
||||
Spring Cloud Stream Kafka Streams binder allows you to configure this application id in multiple ways.
|
||||
@@ -535,14 +535,14 @@ The generated application ID in this manner will be static over application rest
|
||||
In the case of functional model, the generated application ID will be the function bean name followed by the literal `applicationID`, for e.g `process-applicationID` if `process` if the function bean name.
|
||||
|
||||
[[summary-of-setting-application-id]]
|
||||
====== Summary of setting Application ID
|
||||
===== Summary of setting Application ID
|
||||
|
||||
* By default, binder will auto generate the application ID per function methods.
|
||||
* If you have a single processor, then you can use `spring.kafka.streams.applicationId`, `spring.application.name` or `spring.cloud.stream.kafka.streams.binder.applicationId`.
|
||||
* If you have multiple processors, then application ID can be set per function using the property - `spring.cloud.stream.kafka.streams.binder.functions.<function-name>.applicationId`.
|
||||
|
||||
[[overriding-the-default-binding-names-generated-by-the-binder-with-the-functional-style]]
|
||||
==== Overriding the default binding names generated by the binder with the functional style
|
||||
=== Overriding the default binding names generated by the binder with the functional style
|
||||
|
||||
By default, the binder uses the strategy discussed above to generate the binding name when using the functional style, i.e. <function-bean-name>-<in>|<out>-[0..n], for e.g. process-in-0, process-out-0 etc.
|
||||
If you want to override those binding names, you can do that by specifying the following properties.
|
||||
@@ -576,7 +576,7 @@ Please keep in mind that with the functional programming model described above,
|
||||
The only reason you may still want to do this overriding is when you have larger number of configuration properties and you want to map the bindings to something more domain friendly.
|
||||
|
||||
[[setting-up-bootstrap-server-configuration]]
|
||||
==== Setting up bootstrap server configuration
|
||||
=== Setting up bootstrap server configuration
|
||||
|
||||
When running Kafka Streams applications, you must provide the Kafka broker server information.
|
||||
If you don't provide this information, the binder expects that you are running the broker at the default `localhost:9092`.
|
||||
@@ -589,14 +589,14 @@ When it comes to the binder level property, it doesn't matter if you use the bro
|
||||
Kafka Streams binder will first check if Kafka Streams binder specific broker property is set (`spring.cloud.stream.kafka.streams.binder.brokers`) and if not found, it looks for `spring.cloud.stream.kafka.binder.brokers`.
|
||||
|
||||
[[record-serialization-and-deserialization]]
|
||||
=== Record serialization and deserialization
|
||||
== Record serialization and deserialization
|
||||
|
||||
Kafka Streams binder allows you to serialize and deserialize records in two ways.
|
||||
One is the native serialization and deserialization facilities provided by Kafka and the other one is the message conversion capabilities of Spring Cloud Stream framework.
|
||||
Lets look at some details.
|
||||
|
||||
[[inbound-deserialization]]
|
||||
==== Inbound deserialization
|
||||
=== Inbound deserialization
|
||||
|
||||
Keys are always deserialized using native Serdes.
|
||||
|
||||
@@ -674,7 +674,7 @@ spring.cloud.stream.bindings.process-in-0.contentType
|
||||
```
|
||||
|
||||
[[outbound-serialization]]
|
||||
==== Outbound serialization
|
||||
=== Outbound serialization
|
||||
|
||||
Outbound serialization pretty much follows the same rules as above for inbound deserialization.
|
||||
As with the inbound deserialization, one major change from the previous versions of Spring Cloud Stream is that the serialization on the outbound is handled by Kafka natively.
|
||||
@@ -729,7 +729,7 @@ Your business logic might still need to call Kafka Streams API's that explicitly
|
||||
Those are still the responsibility of the application and must be handled accordingly by the developer.
|
||||
|
||||
[[error-handling]]
|
||||
=== Error Handling
|
||||
== Error Handling
|
||||
|
||||
Apache Kafka Streams provides the capability for natively handling exceptions from deserialization errors.
|
||||
For details on this support, please see https://cwiki.apache.org/confluence/display/KAFKA/KIP-161%3A+streams+deserialization+exception+handlers[this].
|
||||
@@ -737,7 +737,7 @@ Out of the box, Apache Kafka Streams provides two kinds of deserialization excep
|
||||
As the name indicates, the former will log the error and continue processing the next records and the latter will log the error and fail. `LogAndFailExceptionHandler` is the default deserialization exception handler.
|
||||
|
||||
[[handling-deserialization-exceptions-in-the-binder]]
|
||||
==== Handling Deserialization Exceptions in the Binder
|
||||
=== Handling Deserialization Exceptions in the Binder
|
||||
|
||||
Kafka Streams binder allows to specify the deserialization exception handlers above using the following property.
|
||||
|
||||
@@ -804,7 +804,7 @@ For instance, if your binding's destination topic is `inputTopic` and the applic
|
||||
It is always recommended to explicitly create a DLQ topic for each input binding if it is your intention to enable DLQ.
|
||||
|
||||
[[dlq-per-input-consumer-binding]]
|
||||
==== DLQ per input consumer binding
|
||||
=== DLQ per input consumer binding
|
||||
|
||||
The property `spring.cloud.stream.kafka.streams.binder.deserializationExceptionHandler` is applicable for the entire application.
|
||||
This implies that if there are multiple functions in the same application, this property is applied to all of them.
|
||||
@@ -827,7 +827,7 @@ and you only want to enable DLQ on the first input binding and skipAndContinue o
|
||||
Setting deserialization exception handlers this way has a higher precedence than setting at the binder level.
|
||||
|
||||
[[dlq-partitioning]]
|
||||
==== DLQ partitioning
|
||||
=== DLQ partitioning
|
||||
|
||||
By default, records are published to the Dead-Letter topic using the same partition as the original record.
|
||||
This means the Dead-Letter topic must have at least as many partitions as the original record.
|
||||
@@ -857,13 +857,13 @@ This implies that if there are multiple functions in the same application, this
|
||||
* The exception handling for deserialization works consistently with native deserialization and framework provided message conversion.
|
||||
|
||||
[[handling-production-exceptions-in-the-binder]]
|
||||
==== Handling Production Exceptions in the Binder
|
||||
=== Handling Production Exceptions in the Binder
|
||||
|
||||
Unlike the support for deserialization exception handlers as described above, the binder does not provide such first class mechanisms for handling production exceptions.
|
||||
However, you still can configure production exception handlers using the `StreamsBuilderFactoryBean` customizer which you can find more details about, in a subsequent section below.
|
||||
|
||||
[[runtime-error-handling]]
|
||||
==== Runtime Error Handling
|
||||
=== Runtime Error Handling
|
||||
|
||||
When it comes to handling errors from application code, i.e. from the business logic execution, it is usually up to the application to handle that.
|
||||
Because, the Kafka Streams binder does not have a way to interfere with the application code.
|
||||
@@ -924,7 +924,7 @@ In this case, when the record fails, the `DltAwareProcessor`, instead of using i
|
||||
In this case also, you can provide an optional `Supplier<Long>` to dictate the timestamp used in the record passed in to the `BiConsumer` recoverer.
|
||||
|
||||
[[retrying-critical-business-logic]]
|
||||
=== Retrying critical business logic
|
||||
== Retrying critical business logic
|
||||
|
||||
There are scenarios in which you might want to retry parts of your business logic that are critical to the application.
|
||||
There maybe an external call to a relational database or invoking a REST endpoint from the Kafka Streams processor.
|
||||
@@ -1029,7 +1029,7 @@ retryTemplate.execute(context -> {
|
||||
Refer to the https://github.com/spring-projects/spring-retry[Spring Retry] project for more information about the RetryTemplate, retry policies, backoff policies and more.
|
||||
|
||||
[[state-store]]
|
||||
=== State Store
|
||||
== State Store
|
||||
|
||||
State stores are created automatically by Kafka Streams when the high level DSL is used and appropriate calls are made those trigger a state store.
|
||||
|
||||
@@ -1098,7 +1098,7 @@ This will not work when it comes to registering global state stores.
|
||||
In order to register a global state store, please see the section below on customizing `StreamsBuilderFactoryBean`.
|
||||
|
||||
[[interactive-queries]]
|
||||
=== Interactive Queries
|
||||
== Interactive Queries
|
||||
|
||||
Kafka Streams binder API exposes a class called `InteractiveQueryService` to interactively query the state stores.
|
||||
You can access this as a Spring bean in your application. An easy way to get access to this bean from your application is to `autowire` the bean.
|
||||
@@ -1158,7 +1158,7 @@ For these methods also, during startup, if the underlying KafkaStreams objects a
|
||||
The aforementioned retry properties are applicable for these methods as well.
|
||||
|
||||
[[other-api-methods-available-through-the-interactivequeryservice]]
|
||||
==== Other API methods available through the InteractiveQueryService
|
||||
=== Other API methods available through the InteractiveQueryService
|
||||
|
||||
Use the following API method to retrieve the `KeyQueryMetadata` object associated with the combination of given store and key.
|
||||
|
||||
@@ -1173,7 +1173,7 @@ public <K> KafkaStreams getKafkaStreams(String store, K key, Serializer<K> seria
|
||||
```
|
||||
|
||||
[[customizing-store-query-parameters]]
|
||||
==== Customizing Store Query Parameters
|
||||
=== Customizing Store Query Parameters
|
||||
|
||||
Sometimes it is necessary that you need to fine tune the store query parameters before querying the store through `InteractiveQueryService`.
|
||||
For this purpose, starting with the `4.0.1` version of the binder, you can provide a bean for `StoreQueryParametersCustomizer` which is a functional interface with a `customize` method that takes a `StoreQueryParameter` as the argument.
|
||||
@@ -1190,7 +1190,7 @@ When this bean is present in this application, `InteractiveQueryService` will ca
|
||||
NOTE: Keep in mind that, there must be a unique bean for `StoreQueryParametersCustomizer` available in the application.
|
||||
|
||||
[[health-indicator]]
|
||||
=== Health Indicator
|
||||
== Health Indicator
|
||||
|
||||
The health indicator requires the dependency `spring-boot-starter-actuator`. For maven use:
|
||||
[source,xml]
|
||||
@@ -1224,7 +1224,7 @@ When enabling `show-details`, some of the information reported may be redundant.
|
||||
When there are multiple Kafka Streams processors present in the same application, then the health checks will be reported for all of them and will be categorized by the application ID of Kafka Streams.
|
||||
|
||||
[[accessing-kafka-streams-metrics]]
|
||||
=== Accessing Kafka Streams Metrics
|
||||
== Accessing Kafka Streams Metrics
|
||||
|
||||
Spring Cloud Stream Kafka Streams binder provides Kafka Streams metrics which can be exported through a Micrometer `MeterRegistry`.
|
||||
|
||||
@@ -1235,7 +1235,7 @@ When accessing metrics through the Boot actuator endpoint, make sure to add `met
|
||||
Then you can access `/acutator/metrics` to get a list of all the available metrics, which then can be individually accessed through the same URI (`/actuator/metrics/<metric-name>`).
|
||||
|
||||
[[mixing-high-level-dsl-and-low-level-processor-api]]
|
||||
=== Mixing high level DSL and low level Processor API
|
||||
== Mixing high level DSL and low level Processor API
|
||||
|
||||
Kafka Streams provides two variants of APIs.
|
||||
It has a higher level DSL like API where you can chain various operations that maybe familiar to a lot of functional programmers.
|
||||
@@ -1298,7 +1298,7 @@ public Consumer<KStream<Object, String>> process() {
|
||||
The `process` API method call is a terminal operation while the `transform` API is non terminal and gives you a potentially transformed `KStream` using which you can continue further processing using either the DSL or the processor API.
|
||||
|
||||
[[partition-support-on-the-outbound]]
|
||||
=== Partition support on the outbound
|
||||
== Partition support on the outbound
|
||||
|
||||
A Kafka Streams processor usually sends the processed output into an outbound Kafka topic.
|
||||
If the outbound topic is partitioned and the processor needs to send the outgoing data into particular partitions, the applications needs to provide a bean of type `StreamPartitioner`.
|
||||
@@ -1357,7 +1357,7 @@ spring.cloud.stream.kafka.streams.bindings.process-out-0.producer.streamPartitio
|
||||
Each output topic in the application needs to be configured separately like this.
|
||||
|
||||
[[streamsbuilderfactorybean-customizer]]
|
||||
=== StreamsBuilderFactoryBean customizer
|
||||
== StreamsBuilderFactoryBean customizer
|
||||
|
||||
It is often required to customize the `StreamsBuilderFactoryBean` that creates the `KafkaStreams` objects.
|
||||
Based on the underlying support provided by Spring Kafka, the binder allows you to customize the `StreamsBuilderFactoryBean`.
|
||||
@@ -1427,7 +1427,7 @@ public StreamsBuilderFactoryBeanCustomizer streamsBuilderFactoryBeanCustomizer()
|
||||
```
|
||||
|
||||
[[using-customizer-to-register-a-global-state-store]]
|
||||
==== Using Customizer to register a global state store
|
||||
=== Using Customizer to register a global state store
|
||||
|
||||
As mentioned above, the binder does not provide a first class way to register global state stores as a feature.
|
||||
For that, you need to use the customizer.
|
||||
@@ -1451,7 +1451,7 @@ public StreamsBuilderFactoryBeanCustomizer customizer() {
|
||||
Again, if you have multiple processors, you want to attach the global state store to the right `StreamsBuilder` by filtering out the other `StreamsBuilderFactoryBean` objects using the application id as outlined above.
|
||||
|
||||
[[using-customizer-to-register-a-production-exception-handler]]
|
||||
==== Using customizer to register a production exception handler
|
||||
=== Using customizer to register a production exception handler
|
||||
|
||||
In the error handling section, we indicated that the binder does not provide a first class way to deal with production exceptions.
|
||||
Though that is the case, you can still use the `StreamsBuilderFacotryBean` customizer to register production exception handlers. See below.
|
||||
@@ -1470,7 +1470,7 @@ Once again, if you have multiple processors, you may want to set it appropriatel
|
||||
You may also add such production exception handlers using the configuration property (See below for more on that), but this is an option if you choose to go with a programmatic approach.
|
||||
|
||||
[[timestamp-extractor]]
|
||||
=== Timestamp extractor
|
||||
== Timestamp extractor
|
||||
|
||||
Kafka Streams allows you to control the processing of the consumer records based on various notions of timestamp.
|
||||
By default, Kafka Streams extracts the timestamp metadata embedded in the consumer record.
|
||||
@@ -1504,7 +1504,7 @@ spring.cloud.stream.kafka.streams.bindings.process-in-2.consumer.timestampExtrac
|
||||
If you skip an input consumer binding for setting a custom timestamp extractor, that consumer will use the default settings.
|
||||
|
||||
[[multi-binders-with-kafka-streams-based-binders-and-regular-kafka-binder]]
|
||||
=== Multi binders with Kafka Streams based binders and regular Kafka Binder
|
||||
== Multi binders with Kafka Streams based binders and regular Kafka Binder
|
||||
|
||||
You can have an application where you have both a function/consumer/supplier that is based on the regular Kafka binder and a Kafka Streams based processor.
|
||||
However, you cannot mix both of them within a single function or consumer.
|
||||
@@ -1605,7 +1605,7 @@ spring.cloud.stream.bindings.enrichOrder-out-0.binder=kafka1 #kstream
|
||||
```
|
||||
|
||||
[[state-cleanup]]
|
||||
=== State Cleanup
|
||||
== State Cleanup
|
||||
|
||||
By default, no local state is cleaned up when the binding is stopped.
|
||||
This is the same behavior effective from Spring Kafka version 2.7.
|
||||
@@ -1613,7 +1613,7 @@ See https://docs.spring.io/spring-kafka/reference/html/#streams-config[Spring Ka
|
||||
To modify this behavior simply add a single `CleanupConfig` `@Bean` (configured to clean up on start, stop, or neither) to the application context; the bean will be detected and wired into the factory bean.
|
||||
|
||||
[[kafka-streams-topology-visualization]]
|
||||
=== Kafka Streams topology visualization
|
||||
== Kafka Streams topology visualization
|
||||
|
||||
Kafka Streams binder provides the following actuator endpoints for retrieving the topology description using which you can visualize the topology using external tools.
|
||||
|
||||
@@ -1626,7 +1626,7 @@ Further, you also need to add `kafkastreamstopology` to `management.endpoints.we
|
||||
By default, the `kafkastreamstopology` endpoint is disabled.
|
||||
|
||||
[[event-type-based-routing-in-kafka-streams-applications]]
|
||||
=== Event type based routing in Kafka Streams applications
|
||||
== Event type based routing in Kafka Streams applications
|
||||
|
||||
Routing functions available in regular message channel based binders are not supported in Kafka Streams binder.
|
||||
However, Kafka Streams binder still provides routing capabilities through the event type record header on the inbound records.
|
||||
@@ -1669,7 +1669,7 @@ In order to address this issue, you can set the following property on the bindin
|
||||
This way, the application can detect deserialization issues right away when using the event routing feature and can take appropriate handling decisions.
|
||||
|
||||
[[binding-visualization-and-control-in-kafka-streams-binder]]
|
||||
=== Binding visualization and control in Kafka Streams binder
|
||||
== Binding visualization and control in Kafka Streams binder
|
||||
|
||||
Starting with version 3.1.2, Kafka Streams binder supports binding visualization and control.
|
||||
The only two lifecycle phases supported are `STOPPED` and `STARTED`.
|
||||
@@ -1782,7 +1782,7 @@ This is because all the bindings on a single function are backed by the same `St
|
||||
Therefore, for the function above, either `function-in-0` or `function-out-0` will work.
|
||||
|
||||
[[manually-starting-kafka-streams-processors]]
|
||||
=== Manually starting Kafka Streams processors
|
||||
== Manually starting Kafka Streams processors
|
||||
|
||||
Spring Cloud Stream Kafka Streams binder offers an abstraction called `StreamsBuilderFactoryManager` on top of the `StreamsBuilderFactoryBean` from Spring for Apache Kafka.
|
||||
This manager API is used for controlling the multiple `StreamsBuilderFactoryBean` per processor in a binder based application.
|
||||
@@ -1807,7 +1807,7 @@ In order to correct this, you can set `spring.kafka.streams.auto-startup` to `fa
|
||||
Keep in mind that, when using the Spring Cloud Stream binder, you are not directly dealing with `StreamsBuilderFactoryBean` from Spring for Apache Kafka, rather `StreamsBuilderFactoryManager`, as the `StreamsBuilderFactoryBean` objects are internally managed by the binder.
|
||||
|
||||
[[manually-starting-kafka-streams-processors-selectively]]
|
||||
=== Manually starting Kafka Streams processors selectively
|
||||
== Manually starting Kafka Streams processors selectively
|
||||
|
||||
While the approach laid out above will unconditionally apply auto start `false` to all the Kafka Streams processors in the application through `StreamsBuilderFactoryManager`, it is often desirable that only individually selected Kafka Streams processors are not auto started.
|
||||
For instance, let us assume that you have three different functions (processors) in your application and for one of the processors, you do not want to start it as part of the application startup.
|
||||
@@ -1880,7 +1880,7 @@ NOTE: When controlling the bindings by disabling `auto-startup` as described in
|
||||
In other words, if you use the producer binding, `process3-out-0`, that does not have any effect in terms of disabling the auto starting of the processor, although this producer binding uses the same `StreamsBuilderFactoryBean` as the consumer bindings.
|
||||
|
||||
[[tracing-using-spring-cloud-sleuth]]
|
||||
=== Tracing using Spring Cloud Sleuth
|
||||
== Tracing using Spring Cloud Sleuth
|
||||
|
||||
When Spring Cloud Sleuth is on the classpath of a Spring Cloud Stream Kafka Streams binder based application, both its consumer and producer are automatically instrumented with tracing information.
|
||||
However, in order to trace any application specific operations, those need to be explicitly instrumented by the user code.
|
||||
@@ -1944,14 +1944,14 @@ public Function<KStream<String, String>, KStream<String, String>> process(KafkaS
|
||||
```
|
||||
|
||||
[[configuration-options]]
|
||||
=== Configuration Options
|
||||
== Configuration Options
|
||||
|
||||
This section contains the configuration options used by the Kafka Streams binder.
|
||||
|
||||
For common configuration options and properties pertaining to binder, refer to the <<binding-properties,core documentation>>.
|
||||
|
||||
[[kafka-streams-binder-properties]]
|
||||
==== Kafka Streams Binder Properties
|
||||
=== Kafka Streams Binder Properties
|
||||
|
||||
The following properties are available at the binder level and must be prefixed with `spring.cloud.stream.kafka.streams.binder.`
|
||||
Any Kafka binder provided properties re-used in Kafka Streams binder must be prefixed with `spring.cloud.stream.kafka.streams.binder` instead of `spring.cloud.stream.kafka.binder`.
|
||||
@@ -2034,7 +2034,7 @@ Set this property to `true` to enable health check for all processors including
|
||||
Default: false
|
||||
|
||||
[[kafka-streams-producer-properties]]
|
||||
==== Kafka Streams Producer Properties
|
||||
=== Kafka Streams Producer Properties
|
||||
|
||||
The following properties are _only_ available for Kafka Streams producers and must be prefixed with `spring.cloud.stream.kafka.streams.bindings.<binding name>.producer.`
|
||||
For convenience, if there are multiple output bindings and they all require a common value, that can be configured by using the prefix `spring.cloud.stream.kafka.streams.default.producer.`.
|
||||
@@ -2066,7 +2066,7 @@ Custom name for the sink component to which the processor is producing to.
|
||||
Deafult: `none` (generated by Kafka Streams)
|
||||
|
||||
[[kafka-streams-consumer-properties]]
|
||||
==== Kafka Streams Consumer Properties
|
||||
=== Kafka Streams Consumer Properties
|
||||
|
||||
The following properties are available for Kafka Streams consumers and must be prefixed with `spring.cloud.stream.kafka.streams.bindings.<binding-name>.consumer.`
|
||||
For convenience, if there are multiple input bindings and they all require a common value, that can be configured by using the prefix `spring.cloud.stream.kafka.streams.default.consumer.`.
|
||||
@@ -2141,7 +2141,7 @@ Custom name for the source component from which the processor is consuming from.
|
||||
Deafult: `none` (generated by Kafka Streams)
|
||||
|
||||
[[special-note-on-concurrency]]
|
||||
==== Special note on concurrency
|
||||
=== Special note on concurrency
|
||||
|
||||
In Kafka Streams, you can control of the number of threads a processor can create using the `num.stream.threads` property.
|
||||
This, you can do using the various `configuration` options described above under binder, functions, producer or consumer level.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[[kafka-dlq-processing]]
|
||||
=== Dead-Letter Topic Processing
|
||||
= Dead-Letter Topic Processing
|
||||
|
||||
[[dlq-partition-selection]]
|
||||
==== Dead-Letter Topic Partition Selection
|
||||
== Dead-Letter Topic Partition Selection
|
||||
|
||||
By default, records are published to the Dead-Letter topic using the same partition as the original record.
|
||||
This means the Dead-Letter topic must have at least as many partitions as the original record.
|
||||
@@ -52,7 +52,7 @@ This is because there is no way for the binder to infer the names of all the DLQ
|
||||
Therefore, if you provide DLQ names using this strategy, it is the application's responsibility to ensure that those topics are created beforehand.
|
||||
|
||||
[[dlq-handling]]
|
||||
==== Handling Records in a Dead-Letter Topic
|
||||
== Handling Records in a Dead-Letter Topic
|
||||
|
||||
Because the framework cannot anticipate how users would want to dispose of dead-lettered messages, it does not provide any standard mechanism to handle them.
|
||||
If the reason for the dead-lettering is transient, you may wish to route the messages back to the original topic.
|
||||
|
||||
@@ -6,10 +6,10 @@ In addition, this guide explains the Kafka Streams binding capabilities of Sprin
|
||||
--
|
||||
|
||||
[[apache-kafka-binder]]
|
||||
== Apache Kafka Binder
|
||||
= Apache Kafka Binder
|
||||
|
||||
[[usage]]
|
||||
=== Usage
|
||||
== Usage
|
||||
|
||||
To use Apache Kafka binder, you need to add `spring-cloud-stream-binder-kafka` as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven:
|
||||
|
||||
@@ -32,7 +32,7 @@ Alternatively, you can also use the Spring Cloud Stream Kafka Starter, as shown
|
||||
----
|
||||
|
||||
[[overview]]
|
||||
=== Overview
|
||||
== Overview
|
||||
|
||||
The following image shows a simplified diagram of how the Apache Kafka binder operates:
|
||||
|
||||
@@ -49,14 +49,14 @@ For example, with versions earlier than 0.11.x.x, native headers are not support
|
||||
Also, 0.11.x.x does not support the `autoAddPartitions` property.
|
||||
|
||||
[[configuration-options]]
|
||||
=== Configuration Options
|
||||
== Configuration Options
|
||||
|
||||
This section contains the configuration options used by the Apache Kafka binder.
|
||||
|
||||
For common configuration options and properties pertaining to the binder, see the https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/current/reference/html/spring-cloud-stream.html#binding-properties[binding properties] in core documentation.
|
||||
|
||||
[[kafka-binder-properties]]
|
||||
==== Kafka Binder Properties
|
||||
=== Kafka Binder Properties
|
||||
|
||||
spring.cloud.stream.kafka.binder.brokers::
|
||||
A list of brokers to which the Kafka binder connects.
|
||||
@@ -185,7 +185,7 @@ Enable Micrometer observation registry on all the bindings in this binder.
|
||||
Default: false
|
||||
|
||||
[[kafka-consumer-properties]]
|
||||
==== Kafka Consumer Properties
|
||||
=== Kafka Consumer Properties
|
||||
|
||||
NOTE: To avoid repetition, Spring Cloud Stream supports setting values for all channels, in the format of `spring.cloud.stream.kafka.default.consumer.<property>=<value>`.
|
||||
|
||||
@@ -357,7 +357,7 @@ Default: none.
|
||||
|
||||
|
||||
[[reset-offsets]]
|
||||
==== Resetting Offsets
|
||||
=== Resetting Offsets
|
||||
|
||||
When an application starts, the initial position in each assigned partition depends on two properties `startOffset` and `resetOffsets`.
|
||||
If `resetOffsets` is `false`, normal Kafka consumer https://kafka.apache.org/documentation/#consumerconfigs_auto.offset.reset[`auto.offset.reset`] semantics apply.
|
||||
@@ -384,7 +384,7 @@ IMPORTANT: If a rebalance occurs after the initial assignment, the seeks will on
|
||||
For more control over topic offsets, see <<rebalance-listener>>; when a listener is provided, `resetOffsets` should not be set to `true`, otherwise, that will cause an error.
|
||||
|
||||
[[consuming-batches]]
|
||||
==== Consuming Batches
|
||||
=== Consuming Batches
|
||||
|
||||
Starting with version 3.0, when `spring.cloud.stream.bindings.<name>.consumer.batch-mode` is set to `true`, all of the records received by polling the Kafka `Consumer` will be presented as a `List<?>` to the listener method.
|
||||
Otherwise, the method will be called with one record at a time.
|
||||
@@ -399,7 +399,7 @@ You can also use a manual `AckMode` and call `Ackowledgment.nack(index, sleep)`
|
||||
Refer to the https://docs.spring.io/spring-kafka/docs/2.3.15.BUILD-SNAPSHOT/reference/html/#committing-offsets[Spring for Apache Kafka documentation] for more information about these techniques.
|
||||
|
||||
[[kafka-producer-properties]]
|
||||
==== Kafka Producer Properties
|
||||
=== Kafka Producer Properties
|
||||
|
||||
NOTE: To avoid repetition, Spring Cloud Stream supports setting values for all channels, in the format of `spring.cloud.stream.kafka.default.producer.<property>=<value>`.
|
||||
|
||||
@@ -523,12 +523,12 @@ If set to true, records published to this output binding will not be run in a tr
|
||||
Default: `false`
|
||||
|
||||
[[usage-examples]]
|
||||
==== Usage examples
|
||||
=== Usage examples
|
||||
|
||||
In this section, we show the use of the preceding properties for specific scenarios.
|
||||
|
||||
[[example:-setting-ackmode-to-manual-and-relying-on-manual-acknowledgement]]
|
||||
===== Example: Setting `ackMode` to `MANUAL` and Relying on Manual Acknowledgement
|
||||
==== Example: Setting `ackMode` to `MANUAL` and Relying on Manual Acknowledgement
|
||||
|
||||
This example illustrates how one may manually acknowledge offsets in a consumer application.
|
||||
|
||||
@@ -557,7 +557,7 @@ public class ManuallyAcknowdledgingConsumer {
|
||||
----
|
||||
|
||||
[[example:-security-configuration]]
|
||||
===== Example: Security Configuration
|
||||
==== Example: Security Configuration
|
||||
|
||||
Apache Kafka 0.9 supports secure connections between client and brokers.
|
||||
To take advantage of this feature, follow the guidelines in the https://kafka.apache.org/090/documentation.html#security_configclients[Apache Kafka Documentation] as well as the Kafka 0.9 https://docs.confluent.io/2.0.0/kafka/security.html[security guidelines from the Confluent documentation].
|
||||
@@ -577,7 +577,7 @@ When using Kerberos, follow the instructions in the https://kafka.apache.org/090
|
||||
Spring Cloud Stream supports passing JAAS configuration information to the application by using a JAAS configuration file and using Spring Boot properties.
|
||||
|
||||
[[using-jaas-configuration-files]]
|
||||
====== Using JAAS Configuration Files
|
||||
===== Using JAAS Configuration Files
|
||||
|
||||
The JAAS and (optionally) krb5 file locations can be set for Spring Cloud Stream applications by using system properties.
|
||||
The following example shows how to launch a Spring Cloud Stream application with SASL and Kerberos by using a JAAS configuration file:
|
||||
@@ -591,7 +591,7 @@ The following example shows how to launch a Spring Cloud Stream application with
|
||||
----
|
||||
|
||||
[[using-spring-boot-properties]]
|
||||
====== Using Spring Boot Properties
|
||||
===== Using Spring Boot Properties
|
||||
|
||||
As an alternative to having a JAAS configuration file, Spring Cloud Stream provides a mechanism for setting up the JAAS configuration for Spring Cloud Stream applications by using Spring Boot properties.
|
||||
|
||||
@@ -648,7 +648,7 @@ Consequently, relying on Spring Cloud Stream to create/modify topics may fail.
|
||||
In secure environments, we strongly recommend creating topics and managing ACLs administratively by using Kafka tooling.
|
||||
|
||||
[[multi-binder-configuration-and-jaas]]
|
||||
====== Multi-binder configuration and JAAS
|
||||
===== Multi-binder configuration and JAAS
|
||||
|
||||
When connecting to multiple clusters in which each one requires separate JAAS configuration, then set the JAAS configuration using the property `sasl.jaas.config`.
|
||||
When this property is present in the application, it takes precedence over the other strategies mentioned above.
|
||||
@@ -690,7 +690,7 @@ Note that both the Kafka clusters, and the `sasl.jaas.config` values for each of
|
||||
See this https://github.com/spring-cloud/spring-cloud-stream-samples/tree/main/multi-binder-samples/kafka-multi-binder-jaas[sample application] for more details on how to setup and run such an application.
|
||||
|
||||
[[pause-resume]]
|
||||
===== Example: Pausing and Resuming the Consumer
|
||||
==== Example: Pausing and Resuming the Consumer
|
||||
|
||||
If you wish to suspend consumption but not cause a partition rebalance, you can pause and resume the consumer.
|
||||
This is facilitated by managing the binding lifecycle as shown in **Binding visualization and control** in the Spring Cloud Stream documentation, using `State.PAUSED` and `State.RESUMED`.
|
||||
@@ -699,7 +699,7 @@ To resume, you can use an `ApplicationListener` (or `@EventListener` method) to
|
||||
The frequency at which events are published is controlled by the `idleEventInterval` property.
|
||||
|
||||
[[kafka-transactional-binder]]
|
||||
=== Transactional Binder
|
||||
== Transactional Binder
|
||||
|
||||
Enable transactions by setting `spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix` to a non-empty value, e.g. `tx-`.
|
||||
When used in a processor application, the consumer starts the transaction; any records sent on the consumer thread participate in the same transaction.
|
||||
@@ -753,7 +753,7 @@ If you wish to synchronize producer-only transactions with those from some other
|
||||
IMPORTANT: If you deploy multiple instances of your application, each instance needs a unique `transactionIdPrefix`.
|
||||
|
||||
[[kafka-error-channels]]
|
||||
=== Error Channels
|
||||
== Error Channels
|
||||
|
||||
Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination and can also be configured to send async producer send failures to an error channel.
|
||||
See https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/current/reference/html/spring-cloud-stream.html#spring-cloud-stream-overview-error-handling[this section on error handling] for more information.
|
||||
@@ -767,7 +767,7 @@ There is no automatic handling of producer exceptions (such as sending to a <<ka
|
||||
You can consume these exceptions with your own Spring Integration flow.
|
||||
|
||||
[[kafka-metrics]]
|
||||
=== Kafka Metrics
|
||||
== Kafka Metrics
|
||||
|
||||
Kafka binder module exposes the following metrics:
|
||||
|
||||
@@ -795,7 +795,7 @@ class NoOpBindingMeters {
|
||||
More details on how to suppress meters selectively can be found https://micrometer.io/docs/concepts#_meter_filters[here].
|
||||
|
||||
[[kafka-tombstones]]
|
||||
=== Tombstone Records (null record values)
|
||||
== Tombstone Records (null record values)
|
||||
|
||||
When using compacted topics, a record with a `null` value (also called a tombstone record) represents the deletion of a key.
|
||||
To receive such messages in a Spring Cloud Stream function, you can use the following strategy.
|
||||
@@ -820,7 +820,7 @@ public Function<Message<Person>, String> myFunction() {
|
||||
====
|
||||
|
||||
[[rebalance-listener]]
|
||||
=== Using a KafkaBindingRebalanceListener
|
||||
== Using a KafkaBindingRebalanceListener
|
||||
|
||||
Applications may wish to seek topics/partitions to arbitrary offsets when the partitions are initially assigned, or perform other operations on the consumer.
|
||||
Starting with version 2.1, if you provide a single `KafkaBindingRebalanceListener` bean in the application context, it will be wired into all Kafka consumer bindings.
|
||||
@@ -871,7 +871,7 @@ public interface KafkaBindingRebalanceListener {
|
||||
You cannot set the `resetOffsets` consumer property to `true` when you provide a rebalance listener.
|
||||
|
||||
[[retry-and-dlq-processing]]
|
||||
=== Retry and Dead Letter Processing
|
||||
== Retry and Dead Letter Processing
|
||||
|
||||
By default, when you configure retry (e.g. `maxAttemts`) and `enableDlq` in a consumer binding, these functions are performed within the binder, with no participation by the listener container or Kafka consumer.
|
||||
|
||||
@@ -974,7 +974,7 @@ public BinderCustomizer binderCustomizer(ListenerContainerWithDlqAndRetryCustomi
|
||||
====
|
||||
|
||||
[[consumer-producer-config-customizer]]
|
||||
=== Customizing Consumer and Producer configuration
|
||||
== Customizing Consumer and Producer configuration
|
||||
|
||||
If you want advanced customization of consumer and producer configuration that is used for creating `ConsumerFactory` and `ProducerFactory` in Kafka,
|
||||
you can implement the following customizers.
|
||||
@@ -989,7 +989,7 @@ When the binder discovers that these customizers are available as beans, it will
|
||||
Both of these interfaces also provide access to both the binding and destination names so that they can be accessed while customizing producer and consumer properties.
|
||||
|
||||
[[admin-client-config-customization]]
|
||||
=== Customizing AdminClient Configuration
|
||||
== Customizing AdminClient Configuration
|
||||
|
||||
As with consumer and producer config customization above, applications can also customize the configuration for admin clients by providing an `AdminClientConfigCustomizer`.
|
||||
AdminClientConfigCustomizer's configure method provides access to the admin client properties, using which you can define further customization.
|
||||
@@ -1006,7 +1006,7 @@ public AdminClientConfigCustomizer adminClientConfigCustomizer() {
|
||||
```
|
||||
|
||||
[[custom-kafka-binder-health-indicator]]
|
||||
=== Custom Kafka Binder Health Indicator
|
||||
== Custom Kafka Binder Health Indicator
|
||||
|
||||
Kafka binder activates a default health indicator when Spring Boot actuator is on the classpath.
|
||||
This health indicator checks the health of the binder and any communication issues with the Kafka broker.
|
||||
@@ -1030,7 +1030,7 @@ public KafkaBinderHealth kafkaBinderHealthIndicator() {
|
||||
```
|
||||
|
||||
[[custom-kafka-binder-health-indicator-example]]
|
||||
=== Custom kafka Binder Health Indicator Example
|
||||
== Custom kafka Binder Health Indicator Example
|
||||
|
||||
Here is the pseudo-code for writing a custom Kafka binder HealthIndicator.
|
||||
In this example, we try to override the binder provided Kafka HealthIndicator by specifically checking first for cluster connectivity and then followed by topic-related issues.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[[partitioning-with-the-kafka-binder]]
|
||||
=== Partitioning with the Kafka Binder
|
||||
= Partitioning with the Kafka Binder
|
||||
|
||||
Apache Kafka supports topic partitioning natively.
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
[[tips-tricks-and-recipes]]
|
||||
== Tips, Tricks and Recipes
|
||||
= Tips, Tricks and Recipes
|
||||
|
||||
[[simple-dlq-with-kafka]]
|
||||
=== Simple DLQ with Kafka
|
||||
== Simple DLQ with Kafka
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
As a developer, I want to write a consumer application that processes records from a Kafka topic.
|
||||
However, if some error occurs in processing, I don't want the application to stop completely.
|
||||
Instead, I want to send the record in error to a DLT (Dead-Letter-Topic) and then continue processing new records.
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
The solution for this problem is to use the DLQ feature in Spring Cloud Stream.
|
||||
For the purposes of this discussion, let us assume that the following is our processor function.
|
||||
@@ -85,15 +85,15 @@ spring.cloud.stream:
|
||||
```
|
||||
|
||||
[[dlq-with-advanced-retry-options]]
|
||||
=== DLQ with Advanced Retry Options
|
||||
== DLQ with Advanced Retry Options
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
This is similar to the recipe above, but as a developer I would like to configure the way retries are handled.
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
If you followed the above recipe, then you get the default retry options built into the Kafka binder when the processing encounters an error.
|
||||
|
||||
@@ -132,17 +132,17 @@ spring.cloud.stream.bindings.processData-in-0.consumer.retry-template-name=<your
|
||||
```
|
||||
|
||||
[[handling-deserialization-errors-with-dlq]]
|
||||
=== Handling Deserialization errors with DLQ
|
||||
== Handling Deserialization errors with DLQ
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
I have a processor that encounters a deserialization exception in Kafka consumer.
|
||||
I would expect that the Spring Cloud Stream DLQ mechanism will catch that scenario, but it does not.
|
||||
How can I handle this?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
The normal DLQ mechanism offered by Spring Cloud Stream will not help when Kafka consumer throws an irrecoverable deserialization exception.
|
||||
This is because, this exception happens even before the consumer's `poll()` method returns.
|
||||
@@ -249,16 +249,16 @@ Keep in mind that none of the dlq properties above are relevant for the discussi
|
||||
They are purely meant for addressing any application level errors only.
|
||||
|
||||
[[basic-offset-management-in-kafka-binder]]
|
||||
=== Basic offset management in Kafka binder
|
||||
== Basic offset management in Kafka binder
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
I want to write a Spring Cloud Stream Kafka consumer application and not sure about how it manages Kafka consumer offsets.
|
||||
Can you explain?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
We encourage you read the https://docs.spring.io/spring-cloud-stream-binder-kafka/docs/current/reference/html/spring-cloud-stream-binder-kafka.html#reset-offsets[docs] section on this to get a thorough understanding on it.
|
||||
|
||||
@@ -285,16 +285,16 @@ Then make sure you provide the `startOffset` value (either `earliest` or `latest
|
||||
When you do that and then start the consumer application, each time you start, it starts as if this is starting for the first time and ignore any committed offsets for the partition.
|
||||
|
||||
[[seeking-to-arbitrary-offsets-in-kafka]]
|
||||
=== Seeking to arbitrary offsets in Kafka
|
||||
== Seeking to arbitrary offsets in Kafka
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
Using Kafka binder, I know that it can set the offset to either `earliest` or `latest`, but I have a requirement to seek the offset to something in the middle, an arbitrary offset.
|
||||
Is there a way to achieve this using Spring Cloud Stream Kafka binder?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
Previously we saw how Kafka binder allows you to tackle basic offset management.
|
||||
By default, the binder does not allow you to rewind to an arbitrary offset, at least through the mechanism we saw in that recipe.
|
||||
@@ -377,7 +377,7 @@ Real world use cases are much more complex than this and you need to adjust acco
|
||||
When consumer `seek` fails, it may throw some runtime exceptions and you need to decide what to do in those cases.
|
||||
|
||||
[[what-if-we-start-a-second-consumer-with-the-same-group-id?]]
|
||||
==== What if we start a second consumer with the same group id?
|
||||
=== What if we start a second consumer with the same group id?
|
||||
|
||||
When we add a second consumer, a rebalance will occur and some partitions will be moved around.
|
||||
Let's say that the new consumer gets partitions `2` and `3`.
|
||||
@@ -388,16 +388,16 @@ However, for this consumer it was simply a rebalance event and not considered as
|
||||
Thus, it will not re-seek to the given offsets because of the conditional check on the `initial` argument.
|
||||
|
||||
[[how-do-i-manually-acknowledge-using-kafka-binder?]]
|
||||
=== How do I manually acknowledge using Kafka binder?
|
||||
== How do I manually acknowledge using Kafka binder?
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
Using Kafka binder, I want to manually acknowledge messages in my consumer.
|
||||
How do I do that?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
By default, Kafka binder delegates to the default commit settings in Spring for Apache Kafka project.
|
||||
The default `ackMode` in Spring Kafka is `batch`.
|
||||
@@ -427,15 +427,15 @@ public Consumer<Message<String>> myConsumer() {
|
||||
Then you set the property `spring.cloud.stream.kafka.bindings.myConsumer-in-0.consumer.ackMode` to `MANUAL` or `MANUAL_IMMEDIATE`.
|
||||
|
||||
[[how-do-i-override-the-default-binding-names-in-spring-cloud-stream?]]
|
||||
=== How do I override the default binding names in Spring Cloud Stream?
|
||||
== How do I override the default binding names in Spring Cloud Stream?
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
Spring Cloud Stream creates default bindings based on the function definition and signature, but how do I override these to more domain friendly names?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
Assume that following is your function signature.
|
||||
|
||||
@@ -491,15 +491,15 @@ You can easily do that by simply setting these three properties
|
||||
Once you do that, it overrides the default binding names and any properties that you want to set on them must be on these new binding names.
|
||||
|
||||
[[how-do-i-send-a-message-key-as-part-of-my-record?]]
|
||||
=== How do I send a message key as part of my record?
|
||||
== How do I send a message key as part of my record?
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
I need to send a key along with the payload of the record, is there a way to do that in Spring Cloud Stream?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
It is often necessary that you want to send associative data structure like a map as the record with a key and value.
|
||||
Spring Cloud Stream allows you to do that in a straightforward manner.
|
||||
@@ -528,17 +528,17 @@ Please note that we use the binding name `supplier-out-0` since that is our func
|
||||
Then, we use this new key when we produce the message.
|
||||
|
||||
[[how-do-i-use-native-serializer-and-deserializer-instead-of-message-conversion-done-by-spring-cloud-stream?]]
|
||||
=== How do I use native serializer and deserializer instead of message conversion done by Spring Cloud Stream?
|
||||
== How do I use native serializer and deserializer instead of message conversion done by Spring Cloud Stream?
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
Instead of using the message converters in Spring Cloud Stream, I want to use native Serializer and Deserializer in Kafka.
|
||||
By default, Spring Cloud Stream takes care of this conversion using its internal built-in message converters.
|
||||
How can I bypass this and delegate the responsibility to Kafka?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
This is really easy to do.
|
||||
|
||||
@@ -585,17 +585,17 @@ spring.cloud.stream.kafka.bindings.<binding-name>.consumer.useNativeDecoding: tr
|
||||
However, in the case of Kafka binder, this is unnecessary, as by the time it reaches the binder, Kafka already deserializes them using the configured deserializers.
|
||||
|
||||
[[explain-how-offset-resetting-work-in-kafka-streams-binder]]
|
||||
=== Explain how offset resetting work in Kafka Streams binder
|
||||
== Explain how offset resetting work in Kafka Streams binder
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
By default, Kafka Streams binder always starts from the earliest offset for a new consumer.
|
||||
Sometimes, it is beneficial or required by the application to start from the latest offset.
|
||||
Kafka Streams binder allows you to do that.
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
Before we look at the solution, let us look at the following scenario.
|
||||
|
||||
@@ -623,15 +623,15 @@ If you want only one binding to start from the `latest` offset and the other to
|
||||
Keep in mind that, once there are committed offsets, these setting are *not* honored and the committed offsets take precedence.
|
||||
|
||||
[[keeping-track-of-successful-sending-of-records-producing-in-kafka]]
|
||||
=== Keeping track of successful sending of records (producing) in Kafka
|
||||
== Keeping track of successful sending of records (producing) in Kafka
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
I have a Kafka producer application and I want to keep track of all my successful sendings.
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
Let us assume that we have this following supplier in the application.
|
||||
|
||||
@@ -673,15 +673,15 @@ In the `handle` method, the payload is what got sent to Kafka and the message he
|
||||
Its value is a `RecordMetadata` that contains information about topic partition, current offset etc.
|
||||
|
||||
[[adding-custom-header-mapper-in-kafka]]
|
||||
=== Adding custom header mapper in Kafka
|
||||
== Adding custom header mapper in Kafka
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
I have a Kafka producer application that sets some headers, but they are missing in the consumer application. Why is that?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
Under normal circumstances, this should be fine.
|
||||
|
||||
@@ -751,7 +751,7 @@ public KafkaHeaderMapper kafkaBinderHeaderMapper() {
|
||||
That will properly populate the `foo` header from the producer to consumer.
|
||||
|
||||
[[special-note-on-the-id-header]]
|
||||
==== Special note on the id header
|
||||
=== Special note on the id header
|
||||
|
||||
In Spring Cloud Stream, the `id` header is a special header, but some applications may want to have special custom id headers - something like `custom-id` or `ID` or `Id`.
|
||||
The first one (`custom-id`) will propagate without any custom header mapper from producer to consumer.
|
||||
@@ -792,17 +792,17 @@ public KafkaHeaderMapper kafkaBinderHeaderMapper1() {
|
||||
By doing this, both `id` and `Id` headers will be available from the producer to the consumer side.
|
||||
|
||||
[[producing-to-multiple-topics-in-transaction]]
|
||||
=== Producing to multiple topics in transaction
|
||||
== Producing to multiple topics in transaction
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
How do I produce transactional messages to multiple Kafka topics?
|
||||
|
||||
For more context, see this https://stackoverflow.com/questions/68928091/dlq-bounded-retry-and-eos-when-producing-to-multiple-topics-using-spring-cloud[StackOverflow question].
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
Use transactional support in Kafka binder for transactions and then provide an `AfterRollbackProcessor`.
|
||||
In order to produce to multiple topics, use `StreamBridge` API.
|
||||
@@ -844,7 +844,7 @@ DefaultAfterRollbackProcessor rollbackProcessor(KafkaTemplate<byte[], byte[]> te
|
||||
```
|
||||
|
||||
[[required-configuration]]
|
||||
==== Required Configuration
|
||||
=== Required Configuration
|
||||
|
||||
```
|
||||
spring.cloud.stream.kafka.binder.transaction.transaction-id-prefix: tx-
|
||||
@@ -882,15 +882,15 @@ If you are using Spring Cloud Stream to test it by adding more consumer function
|
||||
This https://stackoverflow.com/questions/68941306/spring-cloud-stream-database-transaction-does-not-roll-back[StackOverflow thread] is also related to this discussion.
|
||||
|
||||
[[pitfalls-to-avoid-when-running-multiple-pollable-consumers]]
|
||||
=== Pitfalls to avoid when running multiple pollable consumers
|
||||
== Pitfalls to avoid when running multiple pollable consumers
|
||||
|
||||
[[problem-statement]]
|
||||
==== Problem Statement
|
||||
=== Problem Statement
|
||||
|
||||
How can I run multiple instances of the pollable consumers and generate unique `client.id` for each instance?
|
||||
|
||||
[[solution]]
|
||||
==== Solution
|
||||
=== Solution
|
||||
|
||||
Assuming that I have the following definition:
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[[a-brief-history-of-spring-s-data-integration-journey]]
|
||||
=== A Brief History of Spring's Data Integration Journey
|
||||
= A Brief History of Spring's Data Integration Journey
|
||||
|
||||
Spring's journey on Data Integration started with https://projects.spring.io/spring-integration/[Spring Integration]. With its programming model, it provided a consistent developer experience to build applications that can embrace http://www.enterpriseintegrationpatterns.com/[Enterprise Integration Patterns] to connect with external systems such as, databases, message brokers, and among others.
|
||||
|
||||
@@ -18,7 +18,7 @@ With Spring Cloud Stream, developers can:
|
||||
- and many more. . .
|
||||
|
||||
[[quick-start]]
|
||||
=== Quick Start
|
||||
= Quick Start
|
||||
|
||||
You can try Spring Cloud Stream in less than 5 min even before you jump into any details by following this three-step guide.
|
||||
|
||||
@@ -34,7 +34,7 @@ The three steps are as follows:
|
||||
. <<spring-cloud-stream-preface-adding-message-handler>>
|
||||
|
||||
[[spring-cloud-stream-preface-creating-sample-application]]
|
||||
==== Creating a Sample Application by Using Spring Initializr
|
||||
== Creating a Sample Application by Using Spring Initializr
|
||||
To get started, visit the https://start.spring.io[Spring Initializr]. From there, you can generate our `LoggingConsumer` application. To do so:
|
||||
|
||||
. In the *Dependencies* section, start typing `stream`.
|
||||
@@ -68,7 +68,7 @@ TIP: We encourage you to explore the many possibilities available in the Spring
|
||||
It lets you create many different kinds of Spring applications.
|
||||
|
||||
[[spring-cloud-stream-preface-importing-project]]
|
||||
==== Importing the Project into Your IDE
|
||||
== Importing the Project into Your IDE
|
||||
|
||||
Now you can import the project into your IDE.
|
||||
Keep in mind that, depending on the IDE, you may need to follow a specific import procedure.
|
||||
@@ -81,7 +81,7 @@ It is already a valid Spring Boot application.
|
||||
However, it does not do anything, so we want to add some code.
|
||||
|
||||
[[spring-cloud-stream-preface-adding-message-handler]]
|
||||
==== Adding a Message Handler, Building, and Running
|
||||
== Adding a Message Handler, Building, and Running
|
||||
|
||||
Modify the `com.example.loggingconsumer.LoggingConsumerApplication` class to look as follows:
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[[rabbit-dlq-processing]]
|
||||
== Dead-Letter Queue Processing
|
||||
= Dead-Letter Queue Processing
|
||||
|
||||
Because you cannot anticipate how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them.
|
||||
If the reason for the dead-lettering is transient, you may wish to route the messages back to the original queue.
|
||||
@@ -13,7 +13,7 @@ You could also use `RabbitTemplate.receive()` in a batch process.
|
||||
The examples assume the original destination is `so8400in` and the consumer group is `so8400`.
|
||||
|
||||
[[non-partitioned-destinations]]
|
||||
=== Non-Partitioned Destinations
|
||||
== Non-Partitioned Destinations
|
||||
|
||||
The first two examples are for when the destination is *not* partitioned:
|
||||
|
||||
@@ -126,12 +126,12 @@ public class ReRouteDlqApplication {
|
||||
----
|
||||
|
||||
[[partitioned-destinations]]
|
||||
=== Partitioned Destinations
|
||||
== Partitioned Destinations
|
||||
|
||||
With partitioned destinations, there is one DLQ for all partitions. We determine the original queue from the headers.
|
||||
|
||||
[[republishtodlq=false]]
|
||||
==== `republishToDlq=false`
|
||||
=== `republishToDlq=false`
|
||||
|
||||
When `republishToDlq` is `false`, RabbitMQ publishes the message to the DLX/DLQ with an `x-death` header containing information about the original destination, as shown in the following example:
|
||||
|
||||
@@ -189,7 +189,7 @@ public class ReRouteDlqApplication {
|
||||
----
|
||||
|
||||
[[republishtodlq=true]]
|
||||
==== `republishToDlq=true`
|
||||
=== `republishToDlq=true`
|
||||
|
||||
When `republishToDlq` is `true`, the republishing recoverer adds the original exchange and routing key to headers, as shown in the following example:
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ It contains information about its design, usage and configuration options, as we
|
||||
--
|
||||
|
||||
[[usage]]
|
||||
== Usage
|
||||
= Usage
|
||||
|
||||
To use the RabbitMQ binder, you can add it to your Spring Cloud Stream application, by using the following Maven coordinates:
|
||||
|
||||
@@ -28,7 +28,7 @@ Alternatively, you can use the Spring Cloud Stream RabbitMQ Starter, as follows:
|
||||
----
|
||||
|
||||
[[rabbitmq-binder-overview]]
|
||||
== RabbitMQ Binder Overview
|
||||
= RabbitMQ Binder Overview
|
||||
|
||||
The following simplified diagram shows how the RabbitMQ binder operates:
|
||||
|
||||
@@ -77,14 +77,14 @@ Starting with version 2.0, the `RabbitMessageChannelBinder` sets the `RabbitTemp
|
||||
NOTE: Currently, a `multiplex` consumer (a single consumer listening to multiple queues) is only supported for message-driven consumers; polled consumers can only retrieve messages from a single queue.
|
||||
|
||||
[[configuration-options]]
|
||||
== Configuration Options
|
||||
= Configuration Options
|
||||
|
||||
This section contains settings specific to the RabbitMQ Binder and bound channels.
|
||||
|
||||
For general binding configuration options and properties, see the https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/current/reference/html/spring-cloud-stream.html#_configuration_options[Spring Cloud Stream core documentation].
|
||||
|
||||
[[rabbit-binder-properties]]
|
||||
=== RabbitMQ Binder Properties
|
||||
== RabbitMQ Binder Properties
|
||||
|
||||
By default, the RabbitMQ binder uses Spring Boot's `ConnectionFactory`.
|
||||
Conseuqently, it supports all Spring Boot configuration options for RabbitMQ.
|
||||
@@ -121,7 +121,7 @@ The name is this prefix followed by `#n`, where `n` increments each time a new c
|
||||
Default: none (Spring AMQP default).
|
||||
|
||||
[[rabbitmq-consumer-properties]]
|
||||
=== RabbitMQ Consumer Properties
|
||||
== RabbitMQ Consumer Properties
|
||||
|
||||
The following properties are available for Rabbit consumers only and must be prefixed with `spring.cloud.stream.rabbit.bindings.<channelName>.consumer.`.
|
||||
|
||||
@@ -419,7 +419,7 @@ Not supported when the `containerType` is `direct`.
|
||||
Default: `1`.
|
||||
|
||||
[[rabbitmq-stream-consumer]]
|
||||
=== Initial Consumer Support for the RabbitMQ Stream Plugin
|
||||
== Initial Consumer Support for the RabbitMQ Stream Plugin
|
||||
|
||||
Basic support for the https://rabbitmq.com/stream.html[RabbitMQ Stream Plugin] is now provided.
|
||||
To enable this feature, you must add the `spring-rabbit-stream` jar to the class path - it must be the same version as `spring-amqp` and `spring-rabbit`.
|
||||
@@ -473,7 +473,7 @@ public Consumer<Message<?>> input() {
|
||||
Refer to the https://rabbitmq.github.io/rabbitmq-stream-java-client/stable/htmlsingle/[RabbitMQ Stream Java Client documentation] for information about configuring the environment and consumer builder.
|
||||
|
||||
[[rabbitmq-super-stream-consumer]]
|
||||
==== Consumer Support for the RabbitMQ Super Streams
|
||||
=== Consumer Support for the RabbitMQ Super Streams
|
||||
|
||||
See https://blog.rabbitmq.com/posts/2022/07/rabbitmq-3-11-feature-preview-super-streams[Super Streams] for information about super streams.
|
||||
|
||||
@@ -507,14 +507,14 @@ The framework will create a super stream named `super`, with 9 partitions.
|
||||
Up to 3 instances of this application can be deployed.
|
||||
|
||||
[[advanced-listener-container-configuration]]
|
||||
=== Advanced Listener Container Configuration
|
||||
== Advanced Listener Container Configuration
|
||||
|
||||
To set listener container properties that are not exposed as binder or binding properties, add a single bean of type `ListenerContainerCustomizer` to the application context.
|
||||
The binder and binding properties will be set and then the customizer will be called.
|
||||
The customizer (`configure()` method) is provided with the queue name as well as the consumer group as arguments.
|
||||
|
||||
[[advanced-queue/exchange/binding-configuration]]
|
||||
=== Advanced Queue/Exchange/Binding Configuration
|
||||
== Advanced Queue/Exchange/Binding Configuration
|
||||
|
||||
From time to time, the RabbitMQ team add new features that are enabled by setting some argument when declaring, for example, a queue.
|
||||
Generally, such features are enabled in the binder by adding appropriate properties, but this may not be immediately available in a current version.
|
||||
@@ -522,18 +522,18 @@ Starting with version 3.0.1, you can now add `DeclarableCustomizer` bean(s) to t
|
||||
This allows you to add arguments that are not currently directly supported by the binder.
|
||||
|
||||
[[rabbit-receiving-batch]]
|
||||
=== Receiving Batched Messages
|
||||
== Receiving Batched Messages
|
||||
|
||||
With the RabbitMQ binder, there are two types of batches handled by consumer bindings:
|
||||
|
||||
[[batches-created-by-producers]]
|
||||
==== Batches Created by Producers
|
||||
=== Batches Created by Producers
|
||||
|
||||
Normally, if a producer binding has `batch-enabled=true` (see <<rabbit-prod-props>>), or a message is created by a `BatchingRabbitTemplate`, elements of the batch are returned as individual calls to the listener method.
|
||||
Starting with version 3.0, any such batch can be presented as a `List<?>` to the listener method if `spring.cloud.stream.bindings.<name>.consumer.batch-mode` is set to `true`.
|
||||
|
||||
[[consumer-side-batching]]
|
||||
==== Consumer-side Batching
|
||||
=== Consumer-side Batching
|
||||
|
||||
Starting with version 3.1, the consumer can be configured to assemble multiple inbound messages into a batch which is presented to the application as a `List<?>` of converted payloads.
|
||||
The following simple application demonstrates how to use this technique:
|
||||
@@ -709,7 +709,7 @@ Thing [field=value2] myHeader=headerValue2
|
||||
====
|
||||
|
||||
[[rabbit-prod-props]]
|
||||
=== Rabbit Producer Properties
|
||||
== Rabbit Producer Properties
|
||||
|
||||
The following properties are available for Rabbit producers only and must be prefixed with `spring.cloud.stream.rabbit.bindings.<channelName>.producer.`.
|
||||
|
||||
@@ -1022,7 +1022,7 @@ NOTE: In the case of RabbitMQ, content type headers can be set by external appli
|
||||
Spring Cloud Stream supports them as part of an extended internal protocol used for any type of transport -- including transports, such as Kafka (prior to 0.11), that do not natively support headers.
|
||||
|
||||
[[publisher-confirms]]
|
||||
=== Publisher Confirms
|
||||
== Publisher Confirms
|
||||
|
||||
There are two mechanisms to get the result of publishing a message; in each case, the connection factory must have `publisherConfirmType` set `ConfirmType.CORRELATED`.
|
||||
The "legacy" mechanism is to set the `confirmAckChannel` to the bean name of a message channel from which you can retrieve the confirmations asynchronously; negative acks are sent to the error channel (if enabled) - see <<rabbit-error-channels>>.
|
||||
@@ -1139,7 +1139,7 @@ IMPORTANT: The correlation data must be provided with a unique `id` so that the
|
||||
You cannot set both `useConfirmHeader` and `confirmAckChannel` but you can still receive returned messages in the error channel when `useConfirmHeader` is true, but using the correlation header is more convenient.
|
||||
|
||||
[[rabbitmq-stream-producer]]
|
||||
=== Initial Producer Support for the RabbitMQ Stream Plugin
|
||||
== Initial Producer Support for the RabbitMQ Stream Plugin
|
||||
|
||||
Basic support for the https://rabbitmq.com/stream.html[RabbitMQ Stream Plugin] is now provided.
|
||||
To enable this feature, you must add the `spring-rabbit-stream` jar to the class path - it must be the same version as `spring-amqp` and `spring-rabbit`.
|
||||
@@ -1169,7 +1169,7 @@ ProducerMessageHandlerCustomizer<MessageHandler> handlerCustomizer() {
|
||||
Refer to the https://rabbitmq.github.io/rabbitmq-stream-java-client/stable/htmlsingle/[RabbitMQ Stream Java Client documentation] for information about configuring the environment and producer builder.
|
||||
|
||||
[[rabbitmq-super-stream-producer]]
|
||||
==== Producer Support for the RabbitMQ Super Streams
|
||||
=== Producer Support for the RabbitMQ Super Streams
|
||||
|
||||
See https://blog.rabbitmq.com/posts/2022/07/rabbitmq-3-11-feature-preview-super-streams[Super Streams] for information about super streams.
|
||||
|
||||
@@ -1207,7 +1207,7 @@ spring.cloud.stream.rabbit.bindings.output.producer.declare-exchange=false
|
||||
When using the stream client, if you set a `confirmAckChannel`, a copy of a successfully sent message will be sent to that channel.
|
||||
|
||||
[[using-existing-queues/exchanges]]
|
||||
== Using Existing Queues/Exchanges
|
||||
= Using Existing Queues/Exchanges
|
||||
|
||||
By default, the binder will automatically provision a topic exchange with the name being derived from the value of the destination binding property `<prefix><destination>`.
|
||||
The destination defaults to the binding name, if not provided.
|
||||
@@ -1237,7 +1237,7 @@ Refer to the property documentation above for more information.
|
||||
There are similar properties used when declaring a dead-letter exchange/queue, when `autoBindDlq` is `true`.
|
||||
|
||||
[[retry-with-the-rabbitmq-binder]]
|
||||
== Retry With the RabbitMQ Binder
|
||||
= Retry With the RabbitMQ Binder
|
||||
|
||||
When retry is enabled within the binder, the listener container thread is suspended for any back off periods that are configured.
|
||||
This might be important when strict ordering is required with a single consumer. However, for other use cases, it prevents other messages from being processed on that thread.
|
||||
@@ -1261,7 +1261,7 @@ Fortunately, RabbitMQ provides the `x-death` header, which lets you determine ho
|
||||
To acknowledge a message after giving up, throw an `ImmediateAcknowledgeAmqpException`.
|
||||
|
||||
[[putting-it-all-together]]
|
||||
=== Putting it All Together
|
||||
== Putting it All Together
|
||||
|
||||
The following configuration creates an exchange `myDestination` with queue `myDestination.consumerGroup` bound to a topic exchange with a wildcard routing key `#`:
|
||||
|
||||
@@ -1309,7 +1309,7 @@ public class XDeathApplication {
|
||||
Notice that the count property in the `x-death` header is a `Long`.
|
||||
|
||||
[[rabbit-error-channels]]
|
||||
== Error Channels
|
||||
= Error Channels
|
||||
|
||||
Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination and can also be configured to send async producer send failures to an error channel.
|
||||
See "`<<spring-cloud-stream-overview-error-handling>>`" for more information.
|
||||
@@ -1353,7 +1353,7 @@ There is no automatic handling of these exceptions (such as sending to a <<rabbi
|
||||
You can consume these exceptions with your own Spring Integration flow.
|
||||
|
||||
[[rabbit-binder-health-indicator]]
|
||||
== Rabbit Binder Health Indicator
|
||||
= Rabbit Binder Health Indicator
|
||||
|
||||
The health indicator for Rabbit binder delegates to the one provided from Spring Boot.
|
||||
For more information on this, see https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator.endpoints.health.auto-configured-health-indicators[this].
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[[partitioning-with-the-rabbitmq-binder]]
|
||||
== Partitioning with the RabbitMQ Binder
|
||||
= Partitioning with the RabbitMQ Binder
|
||||
|
||||
RabbitMQ does not support partitioning natively.
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
// ======================================================================================
|
||||
|
||||
[[preface]]
|
||||
== Preface
|
||||
= Preface
|
||||
|
||||
include::preface.adoc[]
|
||||
|
||||
[partintro]
|
||||
@@ -21,7 +22,7 @@ It covers topics such as creating and running stream applications.
|
||||
--
|
||||
|
||||
[[spring-cloud-stream-overview-introducing]]
|
||||
== Introducing Spring Cloud Stream
|
||||
= Introducing Spring Cloud Stream
|
||||
|
||||
Spring Cloud Stream is a framework for building message-driven microservice applications.
|
||||
Spring Cloud Stream builds upon Spring Boot to create standalone, production-grade Spring applications and uses Spring Integration to provide connectivity to message brokers.
|
||||
@@ -72,7 +73,7 @@ class BootTestStreamApplicationTests {
|
||||
----
|
||||
|
||||
[[main-concepts]]
|
||||
== Main Concepts
|
||||
= Main Concepts
|
||||
|
||||
Spring Cloud Stream provides a number of abstractions and primitives that simplify the writing of message-driven microservice applications.
|
||||
This section gives an overview of the following:
|
||||
@@ -85,7 +86,7 @@ This section gives an overview of the following:
|
||||
* <<spring-cloud-stream-overview-binder-api,A pluggable Binder SPI>>
|
||||
|
||||
[[spring-cloud-stream-overview-application-model]]
|
||||
=== Application Model
|
||||
== Application Model
|
||||
|
||||
A Spring Cloud Stream application consists of a middleware-neutral core.
|
||||
The application communicates with the outside world by establishing _bindings_ between destinations
|
||||
@@ -96,13 +97,13 @@ necessary to establish bindings are handled by middleware-specific _Binder_ impl
|
||||
image::SCSt-with-binder.png[width=800,scaledwidth="75%",align="center"]
|
||||
|
||||
[[fat-jar]]
|
||||
==== Fat JAR
|
||||
=== Fat JAR
|
||||
|
||||
Spring Cloud Stream applications can be run in stand-alone mode from your IDE for testing.
|
||||
To run a Spring Cloud Stream application in production, you can create an executable (or "`fat`") JAR by using the standard Spring Boot tooling provided for Maven or Gradle. See the https://docs.spring.io/spring-boot/docs/current/reference/html/howto-build.html#howto-create-an-executable-jar-with-maven[Spring Boot Reference Guide] for more details.
|
||||
|
||||
[[spring-cloud-stream-overview-binder-abstraction]]
|
||||
=== The Binder Abstraction
|
||||
== The Binder Abstraction
|
||||
|
||||
Spring Cloud Stream provides Binder implementations for https://github.com/spring-cloud/spring-cloud-stream-binder-kafka[Kafka] and https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit[Rabbit MQ].
|
||||
The framework also includes a test binder for integration testing of your applications as spring-cloud-stream application. See <<Testing>> section for more details.
|
||||
@@ -125,7 +126,7 @@ For more complex use cases, you can also package multiple binders with your appl
|
||||
|
||||
|
||||
[[spring-cloud-stream-overview-persistent-publish-subscribe-support]]
|
||||
=== Persistent Publish-Subscribe Support
|
||||
== Persistent Publish-Subscribe Support
|
||||
|
||||
Communication between applications follows a publish-subscribe model, where data is broadcast through shared topics.
|
||||
This can be seen in the following figure, which shows a typical deployment for a set of interacting Spring Cloud Stream applications.
|
||||
@@ -146,7 +147,7 @@ While the concept of publish-subscribe messaging is not new, Spring Cloud Stream
|
||||
By using native middleware support, Spring Cloud Stream also simplifies use of the publish-subscribe model across different platforms.
|
||||
|
||||
[[consumer-groups]]
|
||||
=== Consumer Groups
|
||||
== Consumer Groups
|
||||
While the publish-subscribe model makes it easy to connect applications through shared topics, the ability to scale up by creating multiple instances of a given application is equally important.
|
||||
When doing so, different instances of an application are placed in a competing consumer relationship, where only one of the instances is expected to handle a given message.
|
||||
|
||||
@@ -162,7 +163,7 @@ All groups that subscribe to a given destination receive a copy of published dat
|
||||
By default, when a group is not specified, Spring Cloud Stream assigns the application to an anonymous and independent single-member consumer group that is in a publish-subscribe relationship with all other consumer groups.
|
||||
|
||||
[[consumer-types]]
|
||||
=== Consumer Types
|
||||
== Consumer Types
|
||||
|
||||
Two types of consumer are supported:
|
||||
|
||||
@@ -175,7 +176,7 @@ When you wish to control the rate at which messages are processed, you might wan
|
||||
// TODO This needs more description. A sentence parallel to the last sentence of the preceding paragraph would help.
|
||||
|
||||
[[durability]]
|
||||
==== Durability
|
||||
=== Durability
|
||||
|
||||
Consistent with the opinionated application model of Spring Cloud Stream, consumer group subscriptions are durable.
|
||||
That is, a binder implementation ensures that group subscriptions are persistent and that, once at least one subscription for a group has been created, the group receives messages, even if they are sent while all applications in the group are stopped.
|
||||
@@ -191,7 +192,7 @@ When scaling up a Spring Cloud Stream application, you must specify a consumer g
|
||||
Doing so prevents the application's instances from receiving duplicate messages (unless that behavior is desired, which is unusual).
|
||||
|
||||
[[partitioning]]
|
||||
=== Partitioning Support
|
||||
== Partitioning Support
|
||||
|
||||
Spring Cloud Stream provides support for partitioning data between multiple instances of a given application.
|
||||
In a partitioned scenario, the physical communication medium (such as the broker topic) is viewed as being structured into multiple partitions.
|
||||
@@ -209,7 +210,7 @@ For example, in the time-windowed average calculation example, it is important t
|
||||
NOTE: To set up a partitioned processing scenario, you must configure both the data-producing and the data-consuming ends.
|
||||
|
||||
[[programming-model]]
|
||||
== Programming Model
|
||||
= Programming Model
|
||||
|
||||
To understand the programming model, you should be familiar with the following core concepts:
|
||||
|
||||
@@ -220,7 +221,7 @@ To understand the programming model, you should be familiar with the following c
|
||||
image::SCSt-overview.png[width=800,scaledwidth="75%",align="center"]
|
||||
|
||||
[[destination-binders]]
|
||||
=== Destination Binders
|
||||
== Destination Binders
|
||||
|
||||
Destination Binders are extension components of Spring Cloud Stream responsible for providing the necessary configuration and implementation to facilitate
|
||||
integration with external messaging systems.
|
||||
@@ -234,7 +235,7 @@ While it is out of scope of this section to discuss all of the available binder
|
||||
_Binding_ as a concept, does require special attention. The next section discusses it in detail.
|
||||
|
||||
[[bindings]]
|
||||
=== Bindings
|
||||
== Bindings
|
||||
|
||||
As stated earlier, _Bindings_ provide a bridge between the external messaging system (e.g., queue, topic etc.) and application-provided _Producers_ and _Consumers_.
|
||||
|
||||
@@ -268,7 +269,7 @@ binding of to destinations exposed by the provided binder following certain nami
|
||||
rules to avoid extra configuration.
|
||||
|
||||
[[binding-and-binding-names]]
|
||||
==== Binding and Binding names
|
||||
=== Binding and Binding names
|
||||
|
||||
Binding is an abstraction that represents a bridge between sources and targets exposed by the binder and user code,
|
||||
This abstraction has a name and while we try to do our best to limit configuration required to run spring-cloud-stream applications,
|
||||
@@ -282,7 +283,7 @@ NOTE: If your binding name has special characters, such as the `.` character, yo
|
||||
For example `spring.cloud.stream.bindings."[my.output.binding.key]".destination`.
|
||||
|
||||
[[functional-binding-names]]
|
||||
===== Functional binding names
|
||||
==== Functional binding names
|
||||
|
||||
Unlike the explicit naming required by annotation-based support (legacy) used in the previous versions of spring-cloud-stream, the functional
|
||||
programming model defaults to a simple convention when it comes to binding names, thus greatly simplifying application configuration.
|
||||
@@ -345,7 +346,7 @@ where you are clearly correlating the input of `uppercase` function to `sample-t
|
||||
For more on properties and other configuration options please see <<Configuration Options>> section.
|
||||
|
||||
[[explicit-binding-creation]]
|
||||
===== Explicit binding creation
|
||||
==== Explicit binding creation
|
||||
|
||||
In the previous section we explained how bindings are created implicitly driven by the names of `Function`, `Supplier` or `Consumer` beans provided by your application.
|
||||
However, there are times when you may need to create binding explicitly where bindings are not tied to any function. This is typically done to
|
||||
@@ -380,7 +381,7 @@ As you can see we have declared two input bindings and two output bindings while
|
||||
|
||||
|
||||
[[producing-and-consuming-messages]]
|
||||
=== Producing and Consuming Messages
|
||||
== Producing and Consuming Messages
|
||||
|
||||
You can write a Spring Cloud Stream application by simply writing functions and exposing them as `@Bean` s.
|
||||
You can also use Spring Integration annotations based configuration or
|
||||
@@ -388,10 +389,10 @@ Spring Cloud Stream annotation based configuration, although starting with sprin
|
||||
we recommend using functional implementations.
|
||||
|
||||
[[spring_cloud_function]]
|
||||
==== Spring Cloud Function support
|
||||
=== Spring Cloud Function support
|
||||
|
||||
[[overview]]
|
||||
===== Overview
|
||||
==== Overview
|
||||
|
||||
Since Spring Cloud Stream v2.1, another alternative for defining _stream handlers_ and _sources_ is to use build-in
|
||||
support for https://cloud.spring.io/spring-cloud-function/[Spring Cloud Function] where they can be expressed as beans of
|
||||
@@ -458,7 +459,7 @@ public static class SinkFromConsumer {
|
||||
----
|
||||
|
||||
[[suppliers-sources]]
|
||||
===== Suppliers (Sources)
|
||||
==== Suppliers (Sources)
|
||||
|
||||
`Function` and `Consumer` are pretty straightforward when it comes to how their invocation is triggered. They are triggered based
|
||||
on data (events) sent to the destination they are bound to. In other words, they are classic event-driven components.
|
||||
@@ -545,7 +546,7 @@ he desired behavior you can set it to `false` at which point such supplier will
|
||||
the produced Flux without splitting it.
|
||||
|
||||
[[supplier-threading]]
|
||||
====== Supplier & threading
|
||||
===== Supplier & threading
|
||||
|
||||
NOTE: As you have learned by now, unlike `Function` and `Consumer`, which are triggered by an event (they have input data), `Supplier` does not have
|
||||
any input and thus triggered by a different mechanism - _poller_, which may have an unpredictable threading mechanism. And while the details of the
|
||||
@@ -556,7 +557,7 @@ For those cases we have another mechanism via `StreamBridge`, where user has mor
|
||||
in <<Sending arbitrary data to an output (e.g. Foreign event-driven sources)>> section.
|
||||
|
||||
[[consumer-reactive]]
|
||||
===== Consumer (Reactive)
|
||||
==== Consumer (Reactive)
|
||||
|
||||
Reactive `Consumer` is a little bit special because it has a void return type, leaving framework with no reference to subscribe to.
|
||||
Most likely you will not need to write `Consumer<Flux<?>>`, and instead write it as a `Function<Flux<?>, Mono<Void>>` invoking `then`
|
||||
@@ -582,7 +583,7 @@ so this limitation can only be addressed by either making your consumer reactive
|
||||
|
||||
|
||||
[[polling-configuration-properties]]
|
||||
====== Polling Configuration Properties
|
||||
===== Polling Configuration Properties
|
||||
|
||||
The following properties are exposed by Spring Cloud Stream and are prefixed with the `spring.integration.poller.`:
|
||||
|
||||
@@ -615,7 +616,7 @@ Default: MILLISECONDS.
|
||||
For example `--spring.integration.poller.fixed-delay=2000` sets the poller interval to poll every two seconds.
|
||||
|
||||
[[per-binding-polling-configuration]]
|
||||
====== Per-binding polling configuration
|
||||
===== Per-binding polling configuration
|
||||
|
||||
The previous section shows how to configure a single default poller that will be applied to all bindings. While it fits well with the model of microservices spring-cloud-stream designed for where each microservice represents a single component (e.g., Supplier) and thus default poller configuration is enough, there are edge cases where
|
||||
you may have several components that require different polling configurations
|
||||
@@ -624,7 +625,7 @@ For such cases please use per-binding way of configuring poller. For example, as
|
||||
binding using `spring.cloud.stream.bindings.supply-out-0.producer.poller..` prefix (e.g., `spring.cloud.stream.bindings.supply-out-0.producer.poller.fixed-delay=2000`).
|
||||
|
||||
[[sending-arbitrary-data-to-an-output-e-g-foreign-event-driven-sources]]
|
||||
===== Sending arbitrary data to an output (e.g. Foreign event-driven sources)
|
||||
==== Sending arbitrary data to an output (e.g. Foreign event-driven sources)
|
||||
|
||||
There are cases where the actual source of data may be coming from the external (foreign) system that is not a binder. For example, the
|
||||
source of the data may be a classic REST endpoint. How do we bridge such source with the functional mechanism used by spring-cloud-stream?
|
||||
@@ -673,7 +674,7 @@ will go through the same routine when sending output as if it was from any Funct
|
||||
of consistency as with functions. This means the output type conversion, partitioning etc are honored as if it was from the output produced by functions.
|
||||
|
||||
[[streambridge-and-dynamic-destinations]]
|
||||
====== StreamBridge and Dynamic Destinations
|
||||
===== StreamBridge and Dynamic Destinations
|
||||
|
||||
`StreamBridge` can also be used for cases when output destination(s) are not known ahead of time similar to the use cases
|
||||
described in <<Routing FROM Consumer>> section.
|
||||
@@ -750,13 +751,13 @@ By showing two examples we want to emphasize the approach will work with any typ
|
||||
NOTE: If you are using the Solace PubSub+ binder, Spring Cloud Stream has reserved the `scst_targetDestination` header (retrievable via BinderHeaders.TARGET_DESTINATION), which allows for messages to be redirected from their bindings' configured destination to the target destination specified by this header. This allows for the binder to manage the resources necessary to publish to dynamic destinations, relieving the framework from having to do so, and avoids the caching issues mentioned in the previous Note. More info https://github.com/SolaceProducts/solace-spring-cloud/tree/master/solace-spring-cloud-starters/solace-spring-cloud-stream-starter#dynamic-producer-destinations[here].
|
||||
|
||||
[[output-content-type-with-streambridge]]
|
||||
====== Output Content Type with StreamBridge
|
||||
===== Output Content Type with StreamBridge
|
||||
|
||||
You can also provide specific content type if necessary with the following method signature `public boolean send(String bindingName, Object data, MimeType outputContentType)`.
|
||||
Or if you send data as a `Message`, its content type will be honored.
|
||||
|
||||
[[using-specific-binder-type-with-streambridge]]
|
||||
====== Using specific binder type with StreamBridge
|
||||
===== Using specific binder type with StreamBridge
|
||||
|
||||
Spring Cloud Stream supports multiple binder scenarios. For example you may be receiving data from Kafka and sending it to RabbitMQ.
|
||||
|
||||
@@ -778,7 +779,7 @@ NOTE: For cases where `spring.cloud.stream.output-bindings` property is used or
|
||||
argument will have no effect.
|
||||
|
||||
[[using-channel-interceptors-with-streambridge]]
|
||||
====== Using channel interceptors with StreamBridge
|
||||
===== Using channel interceptors with StreamBridge
|
||||
|
||||
Since `StreamBridge` uses a `MessageChannel` to establish the output binding, you can activate channel interceptors when sending data through `StreamBridge`.
|
||||
It is up to the application to decide which channel interceptors to apply on `StreamBridge`.
|
||||
@@ -844,7 +845,7 @@ With this approach, the application gets the ability to decide which interceptor
|
||||
NOTE: `StreamBridge` provides a contract through the `StreamOperations` interface that contains all the `send` methods of `StreamBridge`. Therefore, applications may choose to autowire using `StreamOperations`. This is handy when it comes to unit testing code that uses `StreamBridge` by providing a mock or similar mechanisms for the `StreamOperations` interface.
|
||||
|
||||
[[reactive-functions-support]]
|
||||
===== Reactive Functions support
|
||||
==== Reactive Functions support
|
||||
|
||||
|
||||
Since _Spring Cloud Function_ is build on top of https://projectreactor.io/[Project Reactor] there isn't much you need to do
|
||||
@@ -883,7 +884,7 @@ Therefore, with reactive functions you must rely on the richness of the reactive
|
||||
====
|
||||
|
||||
[[functional-composition]]
|
||||
===== Functional Composition
|
||||
==== Functional Composition
|
||||
|
||||
Using functional programming model you can also benefit from functional composition where you can dynamically compose complex handlers from a set of simple functions.
|
||||
As an example let's add the following function bean to the application defined above
|
||||
@@ -914,7 +915,7 @@ with the following property `spring.cloud.stream.function.bindings.toUpperCase|w
|
||||
other configuration properties to refer to that binding name (e.g., `spring.cloud.stream.bindings.quotedUpperCaseInput.destination=myDestination`).
|
||||
|
||||
[[functional-composition-and-cross-cutting-concerns]]
|
||||
====== Functional Composition and Cross-cutting Concerns
|
||||
===== Functional Composition and Cross-cutting Concerns
|
||||
|
||||
Function composition effectively allows you to address complexity by breaking it down
|
||||
to a set of simple and individually manageable/testable components that could still be
|
||||
@@ -966,7 +967,7 @@ so the other function - `echo` - can benefit form it. The `echo` function stays
|
||||
You can also see the usage of `spring.cloud.stream.function.bindings` property to simplify composed binding name.
|
||||
|
||||
[[functions-with-multiple-input-and-output-arguments]]
|
||||
===== Functions with multiple input and output arguments
|
||||
==== Functions with multiple input and output arguments
|
||||
|
||||
Starting with version 3.0 spring-cloud-stream provides support for functions that
|
||||
have multiple inputs and/or multiple outputs (return values). What does this actually mean and
|
||||
@@ -1085,7 +1086,7 @@ public void testSingleInputMultiOutput() {
|
||||
----
|
||||
|
||||
[[multiple-functions-in-a-single-application]]
|
||||
===== Multiple functions in a single application
|
||||
==== Multiple functions in a single application
|
||||
|
||||
There may also be a need for grouping several message handlers in a single application. You would do so by
|
||||
defining several functions.
|
||||
@@ -1143,7 +1144,7 @@ public void testMultipleFunctions() {
|
||||
----
|
||||
|
||||
[[batch-consumers]]
|
||||
===== Batch Consumers
|
||||
==== Batch Consumers
|
||||
|
||||
When using a `MessageChannelBinder` that supports batch listeners, and the feature is enabled for the consumer binding, you can set `spring.cloud.stream.bindings.<binding-name>.consumer.batch-mode` to `true` to enable the
|
||||
entire batch of messages to be passed to the function in a `List`.
|
||||
@@ -1157,7 +1158,7 @@ public Function<List<Person>, Person> findFirstPerson() {
|
||||
----
|
||||
|
||||
[[batch-producers]]
|
||||
===== Batch Producers
|
||||
==== Batch Producers
|
||||
|
||||
You can also use the concept of batching on the producer side by returning a collection of Messages which effectively provides an
|
||||
inverse effect where each message in the collection will be sent individually by the binder.
|
||||
@@ -1182,7 +1183,7 @@ public Function<String, List<Message<String>>> batch() {
|
||||
Each message in the returned list will be sent individually resulting in four messages sent to output destination.
|
||||
|
||||
[[spring-integration-flow-as-functions]]
|
||||
===== Spring Integration flow as functions
|
||||
==== Spring Integration flow as functions
|
||||
When you implement a function, you may have complex requirements that fit the category
|
||||
of https://www.enterpriseintegrationpatterns.com[Enterprise Integration Patterns] (EIP). These are best handled by using a
|
||||
framework such as https://spring.io/projects/spring-integration[Spring Integration] (SI), which is a reference implementation of EIP.
|
||||
@@ -1231,10 +1232,10 @@ into various patterns you can apply by merging the best of Spring Integration an
|
||||
|
||||
|
||||
[[spring-cloud-streams-overview-using-polled-consumers]]
|
||||
==== Using Polled Consumers
|
||||
=== Using Polled Consumers
|
||||
|
||||
[[overview]]
|
||||
===== Overview
|
||||
==== Overview
|
||||
|
||||
When using polled consumers, you poll the `PollableMessageSource` on demand.
|
||||
To define binding for polled consumer you need to provide `spring.cloud.stream.pollable-source` property.
|
||||
@@ -1342,7 +1343,7 @@ boolean result = pollableSource.poll(received -> {
|
||||
|
||||
|
||||
[[polled-errors]]
|
||||
===== Handling Errors
|
||||
==== Handling Errors
|
||||
|
||||
By default, an error channel is configured for the pollable source; if the callback throws an exception, an `ErrorMessage` is sent to the error channel (`<destination>.<group>.errors`); this error channel is also bridged to the global Spring Integration `errorChannel`.
|
||||
|
||||
@@ -1353,7 +1354,7 @@ If the service activator throws a `RequeueCurrentMessageException`, the message
|
||||
If the listener throws a `RequeueCurrentMessageException` directly, the message will be requeued, as discussed above, and will not be sent to the error channels.
|
||||
|
||||
[[event-routing]]
|
||||
=== Event Routing
|
||||
== Event Routing
|
||||
|
||||
Event Routing, in the context of Spring Cloud Stream, is the ability to either
|
||||
_a) route events to a particular event subscriber_ or
|
||||
@@ -1361,7 +1362,7 @@ _b) route events produced by an event subscriber to a particular destination_.
|
||||
Here we'll refer to it as route ‘TO’ and route ‘FROM’.
|
||||
|
||||
[[routing-to-consumer]]
|
||||
==== Routing TO Consumer
|
||||
=== Routing TO Consumer
|
||||
Routing can be achieved by relying on `RoutingFunction` available in Spring Cloud Function 3.0. All you need to do is enable it via
|
||||
`--spring.cloud.stream.function.routing.enabled=true` application property or provide `spring.cloud.function.routing-expression` property.
|
||||
Once enabled `RoutingFunction` will be bound to input destination
|
||||
@@ -1375,7 +1376,7 @@ Instruction could be provided with individual messages as well as application pr
|
||||
Here are couple of samples:
|
||||
|
||||
[[using-message-headers]]
|
||||
===== Using message headers
|
||||
==== Using message headers
|
||||
[source,java]
|
||||
----
|
||||
@SpringBootApplication
|
||||
@@ -1412,7 +1413,7 @@ setting `spring.cloud.function.routing-expression` header to value `T(java.lang.
|
||||
Also, for SpEL, the _root object_ of the evaluation context is `Message` so you can do evaluation on individual headers (or message) as well `....routing-expression=headers['type']`
|
||||
|
||||
[[using-application-properties]]
|
||||
===== Using application properties
|
||||
==== Using application properties
|
||||
|
||||
The `spring.cloud.function.routing-expression` and/or `spring.cloud.function.definition`
|
||||
can be passed as application properties (e.g., `spring.cloud.function.routing-expression=headers['type']`.
|
||||
@@ -1441,7 +1442,7 @@ IMPORTANT: Passing instructions via application properties is especially importa
|
||||
function is only invoked once to pass the Publisher, so access to the individual items is limited.
|
||||
|
||||
[[routing-function-and-output-binding]]
|
||||
===== Routing Function and output binding
|
||||
==== Routing Function and output binding
|
||||
|
||||
`RoutingFunction` is a `Function` and as such treated no differently than any other function. Well. . . almost.
|
||||
|
||||
@@ -1458,14 +1459,14 @@ the output, the output binding for the `RoutingFunction` will be create dynamica
|
||||
with regards to bindings (having both input and output bindings).
|
||||
|
||||
[[routing-from-consumer]]
|
||||
==== Routing FROM Consumer
|
||||
=== Routing FROM Consumer
|
||||
|
||||
Aside from static destinations, Spring Cloud Stream lets applications send messages to dynamically bound destinations.
|
||||
This is useful, for example, when the target destination needs to be determined at runtime.
|
||||
Applications can do so in one of two ways.
|
||||
|
||||
[[spring-cloud-stream-sendto-destination]]
|
||||
===== spring.cloud.stream.sendto.destination
|
||||
==== spring.cloud.stream.sendto.destination
|
||||
|
||||
You can also delegate to the framework to dynamically resolve the output destination by specifying `spring.cloud.stream.sendto.destination` header
|
||||
set to the name of the destination to be resolved.
|
||||
@@ -1523,7 +1524,7 @@ NOTE: If you need to support dynamic destinations with multiple binder types, us
|
||||
Also, please see <<Using StreamBridge>> section to see how yet another option (StreamBridge) can be utilized for similar cases.
|
||||
|
||||
[[post-processing-after-sending-message]]
|
||||
=== Post processing (after sending message)
|
||||
== Post processing (after sending message)
|
||||
|
||||
Once function is invoked, its result is sent by the framework to a target destination which effectively completes function invocation cycle.
|
||||
|
||||
@@ -1599,7 +1600,7 @@ the post processing functionality in this case will be invoked right after invoc
|
||||
which is before the function invocation cycle is complete.
|
||||
|
||||
[[spring-cloud-stream-overview-error-handling]]
|
||||
=== Error Handling
|
||||
== Error Handling
|
||||
|
||||
In this section we'll explain the general idea behind error handling mechanisms provided by the framework.
|
||||
We'll be using Rabbit binder as an example, since individual binders define different set
|
||||
@@ -1636,7 +1637,7 @@ public Function<Flux<String>, Flux<String>> uppercase() {
|
||||
----
|
||||
|
||||
[[drop-failed-messages]]
|
||||
==== Drop Failed Messages
|
||||
=== Drop Failed Messages
|
||||
|
||||
By default, the system provides error handlers. The first error handler will simply log error message. The second error handler is binder specific error handler
|
||||
which is responsible for handling error message in the context of a specific messaging system (e.g., send to DLQ). But since no additional error handling configuration was provided (in this current scenario) this handler will not do anything. So essentially after being logged, the message will be dropped.
|
||||
@@ -1644,7 +1645,7 @@ which is responsible for handling error message in the context of a specific mes
|
||||
While acceptable in some cases, for most cases, it is not, and we need some recovery mechanism to avoid message loss.
|
||||
|
||||
[[handle-error-messages]]
|
||||
==== Handle Error Messages
|
||||
=== Handle Error Messages
|
||||
|
||||
In the previous section we mentioned that by default messages that resulted in error are effectively logged and dropped. The framework also exposes mechanism for you
|
||||
to provide custom error handler (i.e., to send notification or write to database, etc). You can do so by adding `Consumer` that is specifically designed to accept `ErrorMessage` which aside form all the information about the error (e.g., stack trace etc) contains the original message (the one that triggered the error).
|
||||
@@ -1683,7 +1684,7 @@ If you want to have a single error handler for all function beans, you can use t
|
||||
|
||||
|
||||
[[dlq-dead-letter-queue]]
|
||||
==== DLQ - Dead Letter Queue
|
||||
=== DLQ - Dead Letter Queue
|
||||
|
||||
Perhaps the most common mechanism, DLQ allows failed messages to be sent to a special destination: the _Dead Letter Queue_.
|
||||
|
||||
@@ -1749,7 +1750,7 @@ You can also facilitate immediate dispatch to DLQ (without re-tries) by setting
|
||||
----
|
||||
|
||||
[[retry-template]]
|
||||
==== Retry Template
|
||||
=== Retry Template
|
||||
|
||||
In this section we cover configuration properties relevant to configuration of retry capabilities.
|
||||
|
||||
@@ -1810,13 +1811,13 @@ spring.cloud.stream.bindings.<foo>.consumer.retry-template-name=<your-retry-temp
|
||||
|
||||
|
||||
[[spring-cloud-stream-overview-binders]]
|
||||
== Binders
|
||||
= Binders
|
||||
|
||||
Spring Cloud Stream provides a Binder abstraction for use in connecting to physical destinations at the external middleware.
|
||||
This section provides information about the main concepts behind the Binder SPI, its main components, and implementation-specific details.
|
||||
|
||||
[[producers-and-consumers]]
|
||||
=== Producers and Consumers
|
||||
== Producers and Consumers
|
||||
|
||||
The following image shows the general relationship of producers and consumers:
|
||||
|
||||
@@ -1834,7 +1835,7 @@ Each group that is represented by consumer bindings for a given destination rece
|
||||
If there are multiple consumer instances bound with the same group name, then messages are load-balanced across those consumer instances so that each message sent by a producer is consumed by only a single consumer instance within each group (that is, it follows normal queueing semantics).
|
||||
|
||||
[[spring-cloud-stream-overview-binder-api]]
|
||||
=== Binder SPI
|
||||
== Binder SPI
|
||||
|
||||
The Binder SPI consists of a number of interfaces, out-of-the box utility classes, and discovery strategies that provide a pluggable mechanism for connecting to external middleware.
|
||||
|
||||
@@ -1872,13 +1873,13 @@ in details, with an example, a set of steps necessary to implement a custom bind
|
||||
The steps are also highlighted in the `<<spring-cloud-stream-overview-custom-binder-impl>>` section.
|
||||
|
||||
[[binder-detection]]
|
||||
=== Binder Detection
|
||||
== Binder Detection
|
||||
|
||||
Spring Cloud Stream relies on implementations of the Binder SPI to perform the task of connecting (binding) user code to message brokers.
|
||||
Each Binder implementation typically connects to one type of messaging system.
|
||||
|
||||
[[classpath-detection]]
|
||||
==== Classpath Detection
|
||||
=== Classpath Detection
|
||||
|
||||
By default, Spring Cloud Stream relies on Spring Boot's auto-configuration to configure the binding process.
|
||||
If a single Binder implementation is found on the classpath, Spring Cloud Stream automatically uses it.
|
||||
@@ -1895,7 +1896,7 @@ For example, a Spring Cloud Stream project that aims to bind only to RabbitMQ ca
|
||||
For the specific Maven coordinates of other binder dependencies, see the documentation of that binder implementation.
|
||||
|
||||
[[multiple-binders]]
|
||||
=== Multiple Binders on the Classpath
|
||||
== Multiple Binders on the Classpath
|
||||
|
||||
When multiple binders are present on the classpath, the application must indicate which binder is to be used for each destination binding.
|
||||
Each binder configuration contains a `META-INF/spring.binders` file, which is a simple properties file, as shown in the following example:
|
||||
@@ -1919,7 +1920,7 @@ spring.cloud.stream.bindings.output.binder=rabbit
|
||||
----
|
||||
|
||||
[[multiple-systems]]
|
||||
=== Connecting to Multiple Systems
|
||||
== Connecting to Multiple Systems
|
||||
|
||||
By default, binders share the application's Spring Boot auto-configuration, so that one instance of each binder found on the classpath is created.
|
||||
If your application should connect to more than one broker of the same type, you can specify multiple binder configurations, each with different environment settings.
|
||||
@@ -1982,7 +1983,7 @@ environment:
|
||||
----
|
||||
|
||||
[[binder-customizer]]
|
||||
=== Customizing binders in multi binder applications
|
||||
== Customizing binders in multi binder applications
|
||||
|
||||
When an application has multiple binders in it and wants to customize the binders, then that can be achieved by providing a `BinderCustomizer` implementation.
|
||||
In the case of applications with a single binder, this special customizer is not necessary since the binder context can access the customization beans directly.
|
||||
@@ -2014,11 +2015,11 @@ public BinderCustomizer binderCustomizer() {
|
||||
Note that, when there are more than one instance of the same type of the binder, the binder name can be used to filter customization.
|
||||
|
||||
[[binding_visualization_control]]
|
||||
=== Binding visualization and control
|
||||
== Binding visualization and control
|
||||
Spring Cloud Stream supports visualization and control of the Bindings through Actuator endpoints as well as programmatic way.
|
||||
|
||||
[[programmatic-way]]
|
||||
==== Programmatic way
|
||||
=== Programmatic way
|
||||
|
||||
Since version 3.1 we expose `org.springframework.cloud.stream.binding.BindingsLifecycleController` which is registered as bean and once
|
||||
injected could be used to control the lifecycle of individual bindings
|
||||
@@ -2038,7 +2039,7 @@ assertThat(binding.isRunning()).isFalse();
|
||||
----
|
||||
|
||||
[[actuator]]
|
||||
==== 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:
|
||||
|
||||
@@ -2097,7 +2098,7 @@ NOTE: `PAUSED` and `RESUMED` work only when the corresponding binder and its und
|
||||
Currently, only Kafka and [Solace](https://github.com/SolaceProducts/solace-spring-cloud/tree/master/solace-spring-cloud-starters/solace-spring-cloud-stream-starter#consumer-bindings-pauseresume) binders supports the `PAUSED` and `RESUMED` states.
|
||||
|
||||
[[binder-configuration-properties]]
|
||||
=== Binder Configuration Properties
|
||||
== Binder Configuration Properties
|
||||
|
||||
The following properties are available when customizing binder configurations. These properties exposed via `org.springframework.cloud.stream.config.BinderProperties`
|
||||
|
||||
@@ -2125,7 +2126,7 @@ This setting allows adding binder configurations without interfering with the de
|
||||
Default: `true`.
|
||||
|
||||
[[spring-cloud-stream-overview-custom-binder-impl]]
|
||||
=== Implementing Custom Binders
|
||||
== Implementing Custom Binders
|
||||
|
||||
In order to implement a custom `Binder`, all you need is to:
|
||||
|
||||
@@ -2372,7 +2373,7 @@ com.example.springcloudstreamcustombinder.config.FileMessageBinderConfiguration
|
||||
----
|
||||
|
||||
[[configuration-options]]
|
||||
== Configuration Options
|
||||
= Configuration Options
|
||||
|
||||
Spring Cloud Stream supports general configuration options as well as configuration for bindings and binders.
|
||||
Some binders let additional binding properties support middleware-specific features.
|
||||
@@ -2381,7 +2382,7 @@ Configuration options can be provided to Spring Cloud Stream applications throug
|
||||
This includes application arguments, environment variables, and YAML or .properties files.
|
||||
|
||||
[[binding-service-properties]]
|
||||
=== Binding Service Properties
|
||||
== Binding Service Properties
|
||||
|
||||
These properties are exposed via `org.springframework.cloud.stream.config.BindingServiceProperties`
|
||||
|
||||
@@ -2423,7 +2424,7 @@ Set it to zero to treat such conditions as fatal, preventing the application fro
|
||||
Default: `30`
|
||||
|
||||
[[binding-properties]]
|
||||
=== Binding Properties
|
||||
== Binding Properties
|
||||
|
||||
Binding properties are supplied by using the format of `spring.cloud.stream.bindings.<bindingName>.<property>=<value>`.
|
||||
The `<bindingName>` represents the name of the binding being configured.
|
||||
@@ -2444,7 +2445,7 @@ and `spring.cloud.stream.default.<producer|consumer>.<property>=<value>` for com
|
||||
When it comes to avoiding repetitions for extended binding properties, this format should be used - `spring.cloud.stream.<binder-type>.default.<producer|consumer>.<property>=<value>`.
|
||||
|
||||
[[common-binding-properties]]
|
||||
==== Common Binding Properties
|
||||
=== Common Binding Properties
|
||||
|
||||
These properties are exposed via `org.springframework.cloud.stream.config.BindingProperties`
|
||||
|
||||
@@ -2476,7 +2477,7 @@ See `<<multiple-binders>>` for details.
|
||||
Default: `null` (the default binder is used, if it exists).
|
||||
|
||||
[[consumer-properties]]
|
||||
==== Consumer Properties
|
||||
=== Consumer Properties
|
||||
|
||||
These properties are exposed via `org.springframework.cloud.stream.binder.ConsumerProperties`
|
||||
|
||||
@@ -2563,7 +2564,7 @@ When set to true, the underlying binder will natively multiplex destinations on
|
||||
Default: `false`.
|
||||
|
||||
[[advanced-consumer-configuration]]
|
||||
==== Advanced Consumer Configuration
|
||||
=== Advanced Consumer Configuration
|
||||
|
||||
For advanced configuration of the underlying message listener container for message-driven consumers, add a single `ListenerContainerCustomizer` bean to the application context.
|
||||
It will be invoked after the above properties have been applied and can be used to set additional properties.
|
||||
@@ -2587,7 +2588,7 @@ public MessageSourceCustomizer<AmqpMessageSource> sourceCustomizer() {
|
||||
====
|
||||
|
||||
[[producer-properties]]
|
||||
==== Producer Properties
|
||||
=== Producer Properties
|
||||
|
||||
These properties are exposed via `org.springframework.cloud.stream.binder.ProducerProperties`
|
||||
|
||||
@@ -2658,7 +2659,7 @@ Default: false.
|
||||
|
||||
|
||||
[[advanced-producer-configuration]]
|
||||
==== Advanced Producer Configuration
|
||||
=== Advanced Producer Configuration
|
||||
|
||||
In some cases Producer Properties are not enough to properly configure a producing MessageHandler in the binder, or may be you prefer a programmatic approach
|
||||
while configuring such producing MessageHandler. Regardless of the reason, spring-cloud-stream provides `ProducerMessageHandlerCustomizer` to accomplish it.
|
||||
@@ -2687,7 +2688,7 @@ All you need to do is provide implementation of this strategy and configure it a
|
||||
====
|
||||
|
||||
[[content-type-management]]
|
||||
== Content Type Negotiation
|
||||
= Content Type Negotiation
|
||||
|
||||
Data transformation is one of the core features of any message-driven microservice architecture. Given that, in Spring Cloud Stream, such data
|
||||
is represented as a Spring `Message`, a message may have to be transformed to a desired shape or size before reaching its destination. This is required for two reasons:
|
||||
@@ -2703,7 +2704,7 @@ In Spring Cloud Stream, message transformation is accomplished with an `org.spri
|
||||
NOTE: As a supplement to the details to follow, you may also want to read the following https://spring.io/blog/2018/02/26/spring-cloud-stream-2-0-content-type-negotiation-and-transformation[blog post].
|
||||
|
||||
[[mechanics]]
|
||||
=== Mechanics
|
||||
== Mechanics
|
||||
|
||||
To better understand the mechanics and the necessity behind content-type negotiation, we take a look at a very simple use case by using the following message handler as an example:
|
||||
|
||||
@@ -2749,7 +2750,7 @@ You can always opt out of returning a `Message` from the handler method where yo
|
||||
If there is an internal pipeline, the `Message` is sent to the next handler by going through the same process of conversion. However, if there is no internal pipeline or you have reached the end of it, the `Message` is sent back to the output destination.
|
||||
|
||||
[[content-type-versus-argument-type]]
|
||||
==== 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.
|
||||
The logic for selecting the appropriate `MessageConverter` resides with the argument resolvers (`HandlerMethodArgumentResolvers`), which trigger right before the invocation of the user-defined handler method (which is when the actual argument type is known to the framework).
|
||||
@@ -2771,7 +2772,7 @@ Remember that the `contentType` is complementary to the target type.
|
||||
If you wish, you can provide a hint, which `MessageConverter` may or may not take into consideration.
|
||||
|
||||
[[message-converters]]
|
||||
==== Message Converters
|
||||
=== Message Converters
|
||||
|
||||
`MessageConverters` define two methods:
|
||||
|
||||
@@ -2802,7 +2803,7 @@ Message<byte[]> toMessage(Object payload, @Nullable MessageHeaders headers);
|
||||
----
|
||||
|
||||
[[provided-messageconverters]]
|
||||
=== Provided MessageConverters
|
||||
== Provided MessageConverters
|
||||
|
||||
As mentioned earlier, the framework already provides a stack of `MessageConverters` to handle most common use cases.
|
||||
The following list describes the provided `MessageConverters`, in order of precedence (the first `MessageConverter` that works is used):
|
||||
@@ -2817,7 +2818,7 @@ However, most likely, you found some uncommon case (such as a custom `contentTyp
|
||||
does not know how to convert. If that is the case, you can add custom `MessageConverter`. See <<spring-cloud-stream-overview-user-defined-message-converters>>.
|
||||
|
||||
[[spring-cloud-stream-overview-user-defined-message-converters]]
|
||||
=== User-defined Message Converters
|
||||
== User-defined Message Converters
|
||||
|
||||
Spring Cloud Stream exposes a mechanism to define and register additional `MessageConverter` s.
|
||||
To use it, implement `org.springframework.messaging.converter.MessageConverter`, configure it as a `@Bean`.
|
||||
@@ -2861,7 +2862,7 @@ public class MyCustomMessageConverter extends AbstractMessageConverter {
|
||||
----
|
||||
|
||||
[[inter-application-communication]]
|
||||
== Inter-Application Communication
|
||||
= Inter-Application Communication
|
||||
|
||||
Spring Cloud Stream enables communication between applications. Inter-application communication is a complex issue spanning several concerns, as described in the following topics:
|
||||
|
||||
@@ -2870,7 +2871,7 @@ Spring Cloud Stream enables communication between applications. Inter-applicatio
|
||||
* `<<spring-cloud-stream-overview-partitioning>>`
|
||||
|
||||
[[spring-cloud-stream-overview-connecting-multiple-application-instances]]
|
||||
=== Connecting Multiple Application Instances
|
||||
== Connecting Multiple Application Instances
|
||||
|
||||
While Spring Cloud Stream makes it easy for individual Spring Boot applications to connect to messaging systems, the typical scenario for Spring Cloud Stream is the creation of multi-application pipelines, where microservice applications send data to each other.
|
||||
You can achieve this scenario by correlating the input and output destinations of "`adjacent`" applications.
|
||||
@@ -2890,7 +2891,7 @@ spring.cloud.stream.bindings.input.destination=ticktock
|
||||
----
|
||||
|
||||
[[spring-cloud-stream-overview-instance-index-instance-count]]
|
||||
=== Instance Index and Instance Count
|
||||
== Instance Index and Instance Count
|
||||
|
||||
When scaling up Spring Cloud Stream applications, each instance can receive information about how many other instances of the same application exist and what its own instance index is.
|
||||
Spring Cloud Stream does this through the `spring.cloud.stream.instanceCount` and `spring.cloud.stream.instanceIndex` properties.
|
||||
@@ -2902,7 +2903,7 @@ By default, `spring.cloud.stream.instanceCount` is `1`, and `spring.cloud.stream
|
||||
In a scaled-up scenario, correct configuration of these two properties is important for addressing partitioning behavior (see below) in general, and the two properties are always required by certain binders (for example, the Kafka binder) in order to ensure that data are split correctly across multiple consumer instances.
|
||||
|
||||
[[spring-cloud-stream-overview-partitioning]]
|
||||
=== Partitioning
|
||||
== Partitioning
|
||||
|
||||
Partitioning in Spring Cloud Stream consists of two tasks:
|
||||
|
||||
@@ -2910,7 +2911,7 @@ Partitioning in Spring Cloud Stream consists of two tasks:
|
||||
* `<<spring-cloud-stream-overview-configuring-input-bindings-partitioning>>`
|
||||
|
||||
[[spring-cloud-stream-overview-configuring-output-bindings-partitioning]]
|
||||
==== Configuring Output Bindings for Partitioning
|
||||
=== Configuring Output Bindings for Partitioning
|
||||
|
||||
You can configure an output binding to send partitioned data by setting one and only one of its `partitionKeyExpression` or `partitionKeyExtractorName` properties, as well as its `partitionCount` property.
|
||||
|
||||
@@ -2962,7 +2963,7 @@ NOTE: In previous versions of Spring Cloud Stream you could specify the implemen
|
||||
Since version 3.0, this property is removed.
|
||||
|
||||
[[spring-cloud-stream-overview-configuring-input-bindings-partitioning]]
|
||||
==== Configuring Input Bindings for Partitioning
|
||||
=== Configuring Input Bindings for Partitioning
|
||||
|
||||
An input binding (with the binding name `uppercase-in-0`) is configured to receive partitioned data by setting its `partitioned`
|
||||
property, as well as the `instanceIndex` and `instanceCount` properties on the application itself, as shown in the following example:
|
||||
@@ -2987,20 +2988,20 @@ When a binder configuration requires them, it is important to set both values co
|
||||
While a scenario in which using multiple instances for partitioned data processing may be complex to set up in a standalone case, Spring Cloud Dataflow can simplify the process significantly by populating both the input and output values correctly and by letting you rely on the runtime infrastructure to provide information about the instance index and instance count.
|
||||
|
||||
[[testing]]
|
||||
== Testing
|
||||
= Testing
|
||||
|
||||
Spring Cloud Stream provides support for testing your microservice applications without connecting to a messaging system.
|
||||
|
||||
|
||||
[[spring_integration_test_binder]]
|
||||
=== Spring Integration Test Binder
|
||||
== Spring Integration Test Binder
|
||||
|
||||
Spring Cloud Stream comes with a test binder which you can use for testing the various application components without requiring an actual real-world binder implementation or a message broker.
|
||||
|
||||
This test binder acts as a bridge between _unit_ and _integration_ testing and is based on https://spring.io/projects/spring-integration[Spring Integration] framework as an in-JVM message broker essentially giving you the best of both worlds - a real binder without the networking.
|
||||
|
||||
[[test-binder-configuration]]
|
||||
==== Test Binder configuration
|
||||
=== Test Binder configuration
|
||||
To enable Spring Integration test binder, all you need is to add it as a dependency.
|
||||
|
||||
***Add required dependencies***
|
||||
@@ -3024,7 +3025,7 @@ testImplementation("org.springframework.cloud:spring-cloud-stream-test-binder")
|
||||
----
|
||||
|
||||
[[test-binder-usage]]
|
||||
==== Test Binder usage
|
||||
=== Test Binder usage
|
||||
|
||||
Now you can test your microservice as a simple unit test
|
||||
|
||||
@@ -3167,7 +3168,7 @@ public void testMultipleFunctions() {
|
||||
|
||||
|
||||
[[test-binder-and-pollablemessagesource]]
|
||||
==== Test Binder and PollableMessageSource
|
||||
=== Test Binder and PollableMessageSource
|
||||
Spring Integration Test Binder also allows you to write tests when working with `PollableMessageSource` (see <<Using Polled Consumers>> for more details).
|
||||
|
||||
The important thing that needs to be understood though is that polling is not event-driven, and that `PollableMessageSource` is a strategy which exposes operation to produce (poll for) a Message (singular).
|
||||
@@ -3250,7 +3251,7 @@ NOTE: DO NOT name this bean `messageSource` as it is going to be in conflict wit
|
||||
provided by Spring Boot for unrelated reasons.
|
||||
|
||||
[[special-note-on-mixing-test-binder-and-regular-middleware-binder-for-testing]]
|
||||
==== Special Note on Mixing Test Binder and Regular Middleware Binder for Testing
|
||||
=== Special Note on Mixing Test Binder and Regular Middleware Binder for Testing
|
||||
|
||||
The Spring Integration based test binder is provided for testing the application without involving an actual middleware based binder such as the Kafka or RabbitMQ binder.
|
||||
As described in the sections above, the test binder helps you to verify the application behavior quickly by relying on the in-memory Spring Integration channels.
|
||||
@@ -3259,7 +3260,7 @@ In other words, you cannot mix both the test binder and a regular middleware bin
|
||||
After testing the application with the test binder, if you want to continue doing further integration tests using the actual middleware binder, it is recommended to add those tests that use the actual binder in a separate module so that those tests can make the proper connection to the actual middleware rather than relying on the in-memory channels provided by the test binder.
|
||||
|
||||
[[health-indicator]]
|
||||
== Health Indicator
|
||||
= Health Indicator
|
||||
|
||||
Spring Cloud Stream provides a health indicator for binders.
|
||||
It is registered under the name `binders` and can be enabled or disabled by setting the `management.health.binders.enabled` property.
|
||||
@@ -3293,19 +3294,19 @@ The top level application health check status will be reported as `DOWN`.
|
||||
In this situation, you can simply remove the dependency for kafka binder from your application since you are not using it.
|
||||
|
||||
[[samples]]
|
||||
== Samples
|
||||
= Samples
|
||||
|
||||
For Spring Cloud Stream samples, see the https://github.com/spring-cloud/spring-cloud-stream-samples[spring-cloud-stream-samples] repository on GitHub.
|
||||
|
||||
[[deploying-stream-applications-on-cloudfoundry]]
|
||||
=== Deploying Stream Applications on CloudFoundry
|
||||
== Deploying Stream Applications on CloudFoundry
|
||||
|
||||
On CloudFoundry, services are usually exposed through a special environment variable called https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES[VCAP_SERVICES].
|
||||
|
||||
When configuring your binder connections, you can use the values from an environment variable as explained on the http://docs.spring.io/spring-cloud-dataflow-server-cloudfoundry/docs/current-SNAPSHOT/reference/htmlsingle/#getting-started-ups[dataflow Cloud Foundry Server] docs.
|
||||
|
||||
[[binder-implementations]]
|
||||
== Binder Implementations
|
||||
= Binder Implementations
|
||||
|
||||
The following is the list of available binder implementations
|
||||
|
||||
|
||||
Reference in New Issue
Block a user