Sync docs from master to gh-pages

This commit is contained in:
buildmaster
2018-12-12 19:08:39 +00:00
parent 8d032cc516
commit e6f32a61ed
9 changed files with 43 additions and 38 deletions

View File

@@ -1,3 +1,3 @@
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>16.&nbsp;Binder Implementations</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-stream.html" title="Spring Cloud Stream Reference Guide"><link rel="up" href="multi__preface.html" title="Part&nbsp;I.&nbsp;Preface"><link rel="prev" href="multi__samples.html" title="15.&nbsp;Samples"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">16.&nbsp;Binder Implementations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__samples.html">Prev</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;I.&nbsp;Preface</th><td width="20%" align="right">&nbsp;</td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_binder_implementations" href="#_binder_implementations"></a>16.&nbsp;Binder Implementations</h2></div></div></div><p>The following is the list of available binder implementations</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">[RabbitMQ](<a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-rabbit/" target="_top">https://cloud.spring.io/spring-cloud-stream-binder-rabbit/</a>)</li><li class="listitem">[Apache Kafka](<a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-kafka/" target="_top">https://cloud.spring.io/spring-cloud-stream-binder-kafka/</a>)</li><li class="listitem">[Amazon Kinesis](<a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis" target="_top">https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis</a>)</li><li class="listitem">[Google PubSub <span class="emphasis"><em>(partner maintained)</em></span>](<a class="link" href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder" target="_top">https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder</a>)</li><li class="listitem">[Solace PubSub+ <span class="emphasis"><em>(partner maintained)</em></span>](<a class="link" href="https://github.com/SolaceProducts/spring-cloud-stream-binder-solace" target="_top">https://github.com/SolaceProducts/spring-cloud-stream-binder-solace</a>)</li><li class="listitem">[Azure Event Hubs <span class="emphasis"><em>(partner maintained)</em></span>](<a class="link" href="https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder" target="_top">https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder</a>)</li></ul></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__samples.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="multi__preface.html">Up</a></td><td width="40%" align="right">&nbsp;</td></tr><tr><td width="40%" align="left" valign="top">15.&nbsp;Samples&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-stream.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;</td></tr></table></div></body></html>
<title>16.&nbsp;Binder Implementations</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-stream.html" title="Spring Cloud Stream Reference Guide"><link rel="up" href="multi__preface.html" title="Part&nbsp;I.&nbsp;Preface"><link rel="prev" href="multi__samples.html" title="15.&nbsp;Samples"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">16.&nbsp;Binder Implementations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__samples.html">Prev</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;I.&nbsp;Preface</th><td width="20%" align="right">&nbsp;</td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_binder_implementations" href="#_binder_implementations"></a>16.&nbsp;Binder Implementations</h2></div></div></div><p>The following is the list of available binder implementations</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-rabbit/" target="_top">RabbitMQ</a></li><li class="listitem"><a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-kafka/" target="_top">Apache Kafka</a></li><li class="listitem"><a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis" target="_top">Amazon Kinesis</a></li><li class="listitem"><a class="link" href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder" target="_top">Google PubSub <span class="emphasis"><em>(partner maintained)</em></span></a></li><li class="listitem"><a class="link" href="https://github.com/SolaceProducts/spring-cloud-stream-binder-solace" target="_top">Solace PubSub+ <span class="emphasis"><em>(partner maintained)</em></span></a></li><li class="listitem"><a class="link" href="https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder" target="_top">Azure Event Hubs <span class="emphasis"><em>(partner maintained)</em></span></a></li></ul></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__samples.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="multi__preface.html">Up</a></td><td width="40%" align="right">&nbsp;</td></tr><tr><td width="40%" align="left" valign="top">15.&nbsp;Samples&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-stream.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;</td></tr></table></div></body></html>

View File

@@ -56,7 +56,7 @@ When this configuration is being used, the outbound message marshalling is not b
When native encoding is used, it is the responsibility of the consumer to use an appropriate decoder (for example, the Kafka consumer value de-serializer) to deserialize the inbound message.
Also, when native encoding and decoding is used, the <code class="literal">headerMode=embeddedHeaders</code> property is ignored and headers are not embedded in the message.
See the consumer property <code class="literal">useNativeDecoding</code>.</p><p class="simpara">Default: <code class="literal">false</code>.</p></dd><dt><span class="term">errorChannelEnabled</span></dt><dd><p class="simpara">When set to <code class="literal">true</code>, if the binder supports asynchroous send results, send failures are sent to an error channel for the destination.
See <span class="quote">&#8220;<span class="quote"><a class="xref" href="">???</a></span>&#8221;</span> for more information.</p><p class="simpara">Default: <code class="literal">false</code>.</p></dd></dl></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="dynamicdestination" href="#dynamicdestination"></a>8.3&nbsp;Using Dynamically Bound Destinations</h2></div></div></div><p>Besides the channels defined by using <code class="literal">@EnableBinding</code>, Spring Cloud Stream lets applications send messages to dynamically bound destinations.
See <code class="literal"><a class="xref" href="multi__programming_model.html#spring-cloud-stream-overview-error-handling" title="6.4&nbsp;Error Handling">Section&nbsp;6.4, &#8220;Error Handling&#8221;</a></code> for more information.</p><p class="simpara">Default: <code class="literal">false</code>.</p></dd></dl></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="dynamicdestination" href="#dynamicdestination"></a>8.3&nbsp;Using Dynamically Bound Destinations</h2></div></div></div><p>Besides the channels defined by using <code class="literal">@EnableBinding</code>, 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 by using the <code class="literal">BinderAwareChannelResolver</code> bean, registered automatically by the <code class="literal">@EnableBinding</code> annotation.</p><p>The 'spring.cloud.stream.dynamicDestinations' property can be used for restricting the dynamic destination names to a known set (whitelisting).
If this property is not set, any destination can be bound dynamically.</p><p>The <code class="literal">BinderAwareChannelResolver</code> can be used directly, as shown in the following example of a REST controller using a path variable to decide the target channel:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@EnableBinding</span></em>

View File

@@ -3,7 +3,7 @@
<title>5.&nbsp;Main Concepts</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-stream.html" title="Spring Cloud Stream Reference Guide"><link rel="up" href="multi__preface.html" title="Part&nbsp;I.&nbsp;Preface"><link rel="prev" href="multi_spring-cloud-stream-overview-introducing.html" title="4.&nbsp;Introducing Spring Cloud Stream"><link rel="next" href="multi__programming_model.html" title="6.&nbsp;Programming Model"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">5.&nbsp;Main Concepts</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-stream-overview-introducing.html">Prev</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;I.&nbsp;Preface</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="multi__programming_model.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_main_concepts" href="#_main_concepts"></a>5.&nbsp;Main Concepts</h2></div></div></div><p>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:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="link" href="multi__main_concepts.html#spring-cloud-stream-overview-application-model" title="5.1&nbsp;Application Model">Spring Cloud Stream&#8217;s application model</a></li><li class="listitem"><a class="xref" href="multi__main_concepts.html#spring-cloud-stream-overview-binder-abstraction" title="5.2&nbsp;The Binder Abstraction">Section&nbsp;5.2, &#8220;The Binder Abstraction&#8221;</a></li><li class="listitem"><a class="link" href="multi__main_concepts.html#spring-cloud-stream-overview-persistent-publish-subscribe-support" title="5.3&nbsp;Persistent Publish-Subscribe Support">Persistent publish-subscribe support</a></li><li class="listitem"><a class="link" href="multi__main_concepts.html#consumer-groups" title="5.4&nbsp;Consumer Groups">Consumer group support</a></li><li class="listitem"><a class="link" href="multi__main_concepts.html#partitioning" title="5.6&nbsp;Partitioning Support">Partitioning support</a></li><li class="listitem"><a class="link" href="multi_spring-cloud-stream-overview-binders.html#spring-cloud-stream-overview-binder-api" title="7.2&nbsp;Binder SPI">A pluggable Binder SPI</a></li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-overview-application-model" href="#spring-cloud-stream-overview-application-model"></a>5.1&nbsp;Application Model</h2></div></div></div><p>A Spring Cloud Stream application consists of a middleware-neutral core.
The application communicates with the outside world through input and output channels injected into it by Spring Cloud Stream.
Channels are connected to external brokers through middleware-specific Binder implementations.</p><div class="figure"><a name="d0e728" href="#d0e728"></a><p class="title"><b>Figure&nbsp;5.1.&nbsp;Spring Cloud Stream Application</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-with-binder.png" align="middle" alt="SCSt with binder"></div></div></div><br class="figure-break"><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_fat_jar" href="#_fat_jar"></a>5.1.1&nbsp;Fat JAR</h3></div></div></div><p>Spring Cloud Stream applications can be run in stand-alone mode from your IDE for testing.
Channels are connected to external brokers through middleware-specific Binder implementations.</p><div class="figure"><a name="d0e729" href="#d0e729"></a><p class="title"><b>Figure&nbsp;5.1.&nbsp;Spring Cloud Stream Application</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-with-binder.png" align="middle" alt="SCSt with binder"></div></div></div><br class="figure-break"><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_fat_jar" href="#_fat_jar"></a>5.1.1&nbsp;Fat JAR</h3></div></div></div><p>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 <span class="quote">&#8220;<span class="quote">fat</span>&#8221;</span>) JAR by using the standard Spring Boot tooling provided for Maven or Gradle. See the <a class="link" href="https://docs.spring.io/spring-boot/docs/current/reference/html/howto-build.html#howto-create-an-executable-jar-with-maven" target="_top">Spring Boot Reference Guide</a> for more details.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-overview-binder-abstraction" href="#spring-cloud-stream-overview-binder-abstraction"></a>5.2&nbsp;The Binder Abstraction</h2></div></div></div><p>Spring Cloud Stream provides Binder implementations for <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-kafka" target="_top">Kafka</a> and <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit" target="_top">Rabbit MQ</a>.
Spring Cloud Stream also includes a <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream/blob/master/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestSupportBinder.java" target="_top">TestSupportBinder</a>, which leaves a channel unmodified so that tests can interact with channels directly and reliably assert on what is received.
You can also use the extensible API to write your own Binder.</p><p>Spring Cloud Stream uses Spring Boot for configuration, and the Binder abstraction makes it possible for a Spring Cloud Stream application to be flexible in how it connects to middleware.
@@ -13,7 +13,7 @@ In the sink example from the <a class="xref" href="multi_spring-cloud-stream-ove
You can use different types of middleware with the same code.
To do so, include a different binder at build time.
For more complex use cases, you can also package multiple binders with your application and have it choose the binder( and even whether to use different binders for different channels) at runtime.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-overview-persistent-publish-subscribe-support" href="#spring-cloud-stream-overview-persistent-publish-subscribe-support"></a>5.3&nbsp;Persistent Publish-Subscribe Support</h2></div></div></div><p>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.</p><div class="figure"><a name="d0e791" href="#d0e791"></a><p class="title"><b>Figure&nbsp;5.2.&nbsp;Spring Cloud Stream Publish-Subscribe</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-sensors.png" align="middle" alt="SCSt sensors"></div></div></div><br class="figure-break"><p>Data reported by sensors to an HTTP endpoint is sent to a common destination named <code class="literal">raw-sensor-data</code>.
This can be seen in the following figure, which shows a typical deployment for a set of interacting Spring Cloud Stream applications.</p><div class="figure"><a name="d0e792" href="#d0e792"></a><p class="title"><b>Figure&nbsp;5.2.&nbsp;Spring Cloud Stream Publish-Subscribe</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-sensors.png" align="middle" alt="SCSt sensors"></div></div></div><br class="figure-break"><p>Data reported by sensors to an HTTP endpoint is sent to a common destination named <code class="literal">raw-sensor-data</code>.
From the destination, it is independently processed by a microservice application that computes time-windowed averages and by another microservice application that ingests the raw data into HDFS (Hadoop Distributed File System).
In order to process the data, both applications declare the topic as their input at runtime.</p><p>The publish-subscribe communication model reduces the complexity of both the producer and the consumer and lets new applications be added to the topology without disruption of the existing flow.
For example, downstream from the average-calculating application, you can add an application that calculates the highest temperature values for display and monitoring.
@@ -23,7 +23,7 @@ By using native middleware support, Spring Cloud Stream also simplifies use of t
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.</p><p>Spring Cloud Stream models this behavior through the concept of a consumer group.
(Spring Cloud Stream consumer groups are similar to and inspired by Kafka consumer groups.)
Each consumer binding can use the <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group</code> property to specify a group name.
For the consumers shown in the following figure, this property would be set as <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=hdfsWrite</code> or <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=average</code>.</p><div class="figure"><a name="d0e825" href="#d0e825"></a><p class="title"><b>Figure&nbsp;5.3.&nbsp;Spring Cloud Stream Consumer Groups</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-groups.png" align="middle" alt="SCSt groups"></div></div></div><br class="figure-break"><p>All groups that subscribe to a given destination receive a copy of published data, but only one member of each group receives a given message from that destination.
For the consumers shown in the following figure, this property would be set as <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=hdfsWrite</code> or <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=average</code>.</p><div class="figure"><a name="d0e826" href="#d0e826"></a><p class="title"><b>Figure&nbsp;5.3.&nbsp;Spring Cloud Stream Consumer Groups</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-groups.png" align="middle" alt="SCSt groups"></div></div></div><br class="figure-break"><p>All groups that subscribe to a given destination receive a copy of published data, but only one member of each group receives a given message from that destination.
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.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="consumer-types" href="#consumer-types"></a>5.5&nbsp;Consumer Types</h2></div></div></div><p>Two types of consumer are supported:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">Message-driven (sometimes referred to as Asynchronous)</li><li class="listitem">Polled (sometimes referred to as Synchronous)</li></ul></div><p>Prior to version 2.0, only asynchronous consumers were supported. A message is delivered as soon as it is available and a thread is available to process it.</p><p>When you wish to control the rate at which messages are processed, you might want to use a synchronous consumer.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="durability" href="#durability"></a>5.5.1&nbsp;Durability</h3></div></div></div><p>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.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Anonymous subscriptions are non-durable by nature.
For some binder implementations (such as RabbitMQ), it is possible to have non-durable group subscriptions.</p></td></tr></table></div><p>In general, it is preferable to always specify a consumer group when binding an application to a given destination.
@@ -31,5 +31,5 @@ When scaling up a Spring Cloud Stream application, you must specify a consumer g
Doing so prevents the application&#8217;s instances from receiving duplicate messages (unless that behavior is desired, which is unusual).</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="partitioning" href="#partitioning"></a>5.6&nbsp;Partitioning Support</h2></div></div></div><p>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.
One or more producer application instances send data to multiple consumer application instances and ensure that data identified by common characteristics are processed by the same consumer instance.</p><p>Spring Cloud Stream provides a common abstraction for implementing partitioned processing use cases in a uniform fashion.
Partitioning can thus be used whether the broker itself is naturally partitioned (for example, Kafka) or not (for example, RabbitMQ).</p><div class="figure"><a name="d0e869" href="#d0e869"></a><p class="title"><b>Figure&nbsp;5.4.&nbsp;Spring Cloud Stream Partitioning</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-partitioning.png" align="middle" alt="SCSt partitioning"></div></div></div><br class="figure-break"><p>Partitioning is a critical concept in stateful processing, where it is critical (for either performance or consistency reasons) to ensure that all related data is processed together.
Partitioning can thus be used whether the broker itself is naturally partitioned (for example, Kafka) or not (for example, RabbitMQ).</p><div class="figure"><a name="d0e870" href="#d0e870"></a><p class="title"><b>Figure&nbsp;5.4.&nbsp;Spring Cloud Stream Partitioning</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-partitioning.png" align="middle" alt="SCSt partitioning"></div></div></div><br class="figure-break"><p>Partitioning is a critical concept in stateful processing, where it is critical (for either performance or consistency reasons) to ensure that all related data is processed together.
For example, in the time-windowed average calculation example, it is important that all measurements from any given sensor are processed by the same application instance.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>To set up a partitioned processing scenario, you must configure both the data-producing and the data-consuming ends.</p></td></tr></table></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-stream-overview-introducing.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="multi__preface.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="multi__programming_model.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.&nbsp;Introducing Spring Cloud Stream&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-stream.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;6.&nbsp;Programming Model</td></tr></table></div></body></html>

View File

@@ -224,7 +224,8 @@ Consider the following example of a polled consumer:</p><pre class="programlisti
}
};
}</pre><p>The <code class="literal">PollableMessageSource.poll()</code> method takes a <code class="literal">MessageHandler</code> argument (often a lambda expression, as shown here).
It returns <code class="literal">true</code> if the message was received and successfully processed.</p><p>As with message-driven consumers, if the <code class="literal">MessageHandler</code> throws an exception, messages are published to error channels, as discussed in <span class="quote">&#8220;<span class="quote"><a class="xref" href="">???</a></span>&#8221;</span>.</p><p>Normally, the <code class="literal">poll()</code> method acknowledges the message when the <code class="literal">MessageHandler</code> exits.
It returns <code class="literal">true</code> if the message was received and successfully processed.</p><p>As with message-driven consumers, if the <code class="literal">MessageHandler</code> throws an exception, messages are published to error channels,
as discussed in <code class="literal"><a class="xref" href="multi__programming_model.html#spring-cloud-stream-overview-error-handling" title="6.4&nbsp;Error Handling">Section&nbsp;6.4, &#8220;Error Handling&#8221;</a></code>.</p><p>Normally, the <code class="literal">poll()</code> method acknowledges the message when the <code class="literal">MessageHandler</code> exits.
If the method exits abnormally, the message is rejected (not re-queued), but see <a class="xref" href="multi__programming_model.html#polled-errors" title="Handling Errors">the section called &#8220;Handling Errors&#8221;</a>.
You can override that behavior by taking responsibility for the acknowledgment, as shown in the following example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> ApplicationRunner poller(PollableMessageSource dest1In, MessageChannel dest2Out) {
@@ -250,7 +251,7 @@ If the service activator throws a <code class="literal">RequeueCurrentMessageExc
The error handling comes in two flavors:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="strong"><strong>application:</strong></span> The error handling is done within the application (custom error handler).</li><li class="listitem"><span class="strong"><strong>system:</strong></span> The error handling is delegated to the binder (re-queue, DL, and others). Note that the techniques are dependent on binder implementation and the
capability of the underlying messaging middleware.</li></ul></div><p>Spring Cloud Stream uses the <a class="link" href="https://github.com/spring-projects/spring-retry" target="_top">Spring Retry</a> library to facilitate successful message processing. See <a class="xref" href="multi__programming_model.html#_retry_template" title="6.4.3&nbsp;Retry Template">Section&nbsp;6.4.3, &#8220;Retry Template&#8221;</a> for more details.
However, when all fails, the exceptions thrown by the message handlers are propagated back to the binder. At that point, binder invokes custom error handler or communicates
the error back to the messaging system (re-queue, DLQ, and others).</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_application_error_handling" href="#_application_error_handling"></a>6.4.1&nbsp;Application Error Handling</h3></div></div></div><p>There are two types of application-level error handling. Errors can be handled at each binding subscription or a global handler can handle all the binding subscription errors. Let&#8217;s review the details.</p><div class="figure"><a name="d0e1506" href="#d0e1506"></a><p class="title"><b>Figure&nbsp;6.1.&nbsp;A Spring Cloud Stream Sink Application with Custom and Global Error Handlers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/custom_vs_global_error_channels.png" align="middle" alt="custom vs global error channels"></div></div></div><br class="figure-break"><p>For each input binding, Spring Cloud Stream creates a dedicated error channel with the following semantics <code class="literal">&lt;destinationName&gt;.errors</code>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The <code class="literal">&lt;destinationName&gt;</code> consists of the name of the binding (such as <code class="literal">input</code>) and the name of the group (such as <code class="literal">myGroup</code>).</p></td></tr></table></div><p>Consider the following:</p><pre class="programlisting">spring.cloud.stream.bindings.input.group=myGroup</pre><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@StreamListener(Sink.INPUT)</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// destination name 'input.myGroup'</span>
the error back to the messaging system (re-queue, DLQ, and others).</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_application_error_handling" href="#_application_error_handling"></a>6.4.1&nbsp;Application Error Handling</h3></div></div></div><p>There are two types of application-level error handling. Errors can be handled at each binding subscription or a global handler can handle all the binding subscription errors. Let&#8217;s review the details.</p><div class="figure"><a name="d0e1507" href="#d0e1507"></a><p class="title"><b>Figure&nbsp;6.1.&nbsp;A Spring Cloud Stream Sink Application with Custom and Global Error Handlers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/custom_vs_global_error_channels.png" align="middle" alt="custom vs global error channels"></div></div></div><br class="figure-break"><p>For each input binding, Spring Cloud Stream creates a dedicated error channel with the following semantics <code class="literal">&lt;destinationName&gt;.errors</code>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The <code class="literal">&lt;destinationName&gt;</code> consists of the name of the binding (such as <code class="literal">input</code>) and the name of the group (such as <code class="literal">myGroup</code>).</p></td></tr></table></div><p>Consider the following:</p><pre class="programlisting">spring.cloud.stream.bindings.input.group=myGroup</pre><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@StreamListener(Sink.INPUT)</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// destination name 'input.myGroup'</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> handle(Person value) {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throw</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RuntimeException(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"BOOM!"</span>);
}

View File

@@ -8,7 +8,7 @@ When the <span class="quote">&#8220;<span class="quote">Cloud Stream</span>&#822
We recommend using the one you have already installed or feel more comfortable with installing and running.
Also, as you can see from the Initilaizer screen, there are a few other options you can choose.
For example, you can choose Gradle as your build tool instead of Maven (the default).</p></li><li class="listitem"><p class="simpara">In the <span class="strong"><strong>Artifact</strong></span> field, type 'logging-consumer'.</p><p class="simpara">The value of the <span class="strong"><strong>Artifact</strong></span> field becomes the application name.
If you chose RabbitMQ for the middleware, your Spring Initializr should now be as follows:</p><div class="informalfigure"><div class="mediaobject"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/spring-initializr.png" alt="Spring Initializr"></div></div></li><li class="listitem"><p class="simpara">Click the <span class="strong"><strong>Generate Project</strong></span> button.</p><p class="simpara">Doing so downloads the zipped version of the generated project to your hard drive.</p></li><li class="listitem">Unzip the file into the folder you want to use as your project directory.</li></ol></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>We encourage you to explore the many possibilities available in the Spring Initializr.
If you chose RabbitMQ for the middleware, your Spring Initializr should now be as follows:</p></li></ol></div><div class="informalfigure"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/spring-initializr.png" align="middle" alt="spring initializr"></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara">Click the <span class="strong"><strong>Generate Project</strong></span> button.</p><p class="simpara">Doing so downloads the zipped version of the generated project to your hard drive.</p></li><li class="listitem">Unzip the file into the folder you want to use as your project directory.</li></ol></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>We encourage you to explore the many possibilities available in the Spring Initializr.
It lets you create many different kinds of Spring applications.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-preface-importing-project" href="#spring-cloud-stream-preface-importing-project"></a>2.2&nbsp;Importing the Project into Your IDE</h2></div></div></div><p>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.
For example, depending on how the project was generated (Maven or Gradle), you may need to follow specific import procedure (for example, in Eclipse or STS, you need to use File &#8594; Import &#8594; Maven &#8594; Existing Maven Project).</p><p>Once imported, the project must have no errors of any kind. Also, <code class="literal">src/main/java</code> should contain <code class="literal">com.example.loggingconsumer.LoggingConsumerApplication</code>.</p><p>Technically, at this point, you can run the application&#8217;s main class.

View File

@@ -79,10 +79,10 @@ If you want to use the Confluent schema registry, you need to create a bean of t
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> client;
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The ConfluentSchemaRegistryClient is tested against Confluent platform version 4.0.0.</p></td></tr></table></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_schema_registration_and_resolution" href="#_schema_registration_and_resolution"></a>10.6&nbsp;Schema Registration and Resolution</h2></div></div></div><p>To better understand how Spring Cloud Stream registers and resolves new schemas and its use of Avro schema comparison features, we provide two separate subsections:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="quote">&#8220;<span class="quote"><a class="xref" href="multi_schema-evolution.html#spring-cloud-stream-overview-schema-registration-process" title="10.6.1&nbsp;Schema Registration Process (Serialization)">Section&nbsp;10.6.1, &#8220;Schema Registration Process (Serialization)&#8221;</a></span>&#8221;</span></li><li class="listitem"><span class="quote">&#8220;<span class="quote"><a class="xref" href="multi_schema-evolution.html#spring-cloud-stream-overview-schema-resolution-process" title="10.6.2&nbsp;Schema Resolution Process (Deserialization)">Section&nbsp;10.6.2, &#8220;Schema Resolution Process (Deserialization)&#8221;</a></span>&#8221;</span></li></ul></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-stream-overview-schema-registration-process" href="#spring-cloud-stream-overview-schema-registration-process"></a>10.6.1&nbsp;Schema Registration Process (Serialization)</h3></div></div></div><p>The first part of the registration process is extracting a schema from the payload that is being sent over a channel.
Avro types such as <code class="literal">SpecificRecord</code> or <code class="literal">GenericRecord</code> already contain a schema, which can be retrieved immediately from the instance.
In the case of POJOs, a schema is inferred if the <code class="literal">spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled</code> property is set to <code class="literal">true</code> (the default).</p><div class="figure"><a name="d0e4089" href="#d0e4089"></a><p class="title"><b>Figure&nbsp;10.1.&nbsp;Schema Writer Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_resolution.png" align="middle" alt="schema resolution"></div></div></div><br class="figure-break"><p>Ones a schema is obtained, the converter loads its metadata (version) from the remote server.
In the case of POJOs, a schema is inferred if the <code class="literal">spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled</code> property is set to <code class="literal">true</code> (the default).</p><div class="figure"><a name="d0e4090" href="#d0e4090"></a><p class="title"><b>Figure&nbsp;10.1.&nbsp;Schema Writer Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_resolution.png" align="middle" alt="schema resolution"></div></div></div><br class="figure-break"><p>Ones a schema is obtained, the converter loads its metadata (version) from the remote server.
First, it queries a local cache. If no result is found, it submits the data to the server, which replies with versioning information.
The converter always caches the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.</p><div class="figure"><a name="d0e4100" href="#d0e4100"></a><p class="title"><b>Figure&nbsp;10.2.&nbsp;Schema Registration Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/registration.png" align="middle" alt="registration"></div></div></div><br class="figure-break"><p>With the schema version information, the converter sets the <code class="literal">contentType</code> header of the message to carry the version information&#8201;&#8212;&#8201;for example: <code class="literal">application/vnd.user.v1+avro</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-stream-overview-schema-resolution-process" href="#spring-cloud-stream-overview-schema-resolution-process"></a>10.6.2&nbsp;Schema Resolution Process (Deserialization)</h3></div></div></div><p>When reading messages that contain version information (that is, a <code class="literal">contentType</code> header with a scheme like the one described under <span class="quote">&#8220;<span class="quote"><a class="xref" href="multi_schema-evolution.html#spring-cloud-stream-overview-schema-registration-process" title="10.6.1&nbsp;Schema Registration Process (Serialization)">Section&nbsp;10.6.1, &#8220;Schema Registration Process (Serialization)&#8221;</a></span>&#8221;</span>), the converter queries the Schema server to fetch the writer schema of the message.
Once it has found the correct schema of the incoming message, it retrieves the reader schema and, by using Avro&#8217;s schema resolution support, reads it into the reader definition (setting defaults and any missing properties).</p><div class="figure"><a name="d0e4128" href="#d0e4128"></a><p class="title"><b>Figure&nbsp;10.3.&nbsp;Schema Reading Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_reading.png" align="middle" alt="schema reading"></div></div></div><br class="figure-break"><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>You should understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application).
The converter always caches the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.</p><div class="figure"><a name="d0e4101" href="#d0e4101"></a><p class="title"><b>Figure&nbsp;10.2.&nbsp;Schema Registration Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/registration.png" align="middle" alt="registration"></div></div></div><br class="figure-break"><p>With the schema version information, the converter sets the <code class="literal">contentType</code> header of the message to carry the version information&#8201;&#8212;&#8201;for example: <code class="literal">application/vnd.user.v1+avro</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-stream-overview-schema-resolution-process" href="#spring-cloud-stream-overview-schema-resolution-process"></a>10.6.2&nbsp;Schema Resolution Process (Deserialization)</h3></div></div></div><p>When reading messages that contain version information (that is, a <code class="literal">contentType</code> header with a scheme like the one described under <span class="quote">&#8220;<span class="quote"><a class="xref" href="multi_schema-evolution.html#spring-cloud-stream-overview-schema-registration-process" title="10.6.1&nbsp;Schema Registration Process (Serialization)">Section&nbsp;10.6.1, &#8220;Schema Registration Process (Serialization)&#8221;</a></span>&#8221;</span>), the converter queries the Schema server to fetch the writer schema of the message.
Once it has found the correct schema of the incoming message, it retrieves the reader schema and, by using Avro&#8217;s schema resolution support, reads it into the reader definition (setting defaults and any missing properties).</p><div class="figure"><a name="d0e4129" href="#d0e4129"></a><p class="title"><b>Figure&nbsp;10.3.&nbsp;Schema Reading Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_reading.png" align="middle" alt="schema reading"></div></div></div><br class="figure-break"><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>You should understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application).
We suggest taking a moment to read <a class="link" href="https://avro.apache.org/docs/1.7.6/spec.html" target="_top">the Avro terminology</a> and understand the process.
Spring Cloud Stream always fetches the writer schema to determine how to read a message.
If you want to get Avro&#8217;s schema evolution support working, you need to make sure that a <code class="literal">readerSchema</code> was properly set for your application.</p></td></tr></table></div></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_content-type-management.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="multi__preface.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="multi__inter_application_communication.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.&nbsp;Content Type Negotiation&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-stream.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;11.&nbsp;Inter-Application Communication</td></tr></table></div></body></html>

View File

@@ -1,7 +1,7 @@
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>7.&nbsp;Binders</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-stream.html" title="Spring Cloud Stream Reference Guide"><link rel="up" href="multi__preface.html" title="Part&nbsp;I.&nbsp;Preface"><link rel="prev" href="multi__programming_model.html" title="6.&nbsp;Programming Model"><link rel="next" href="multi__configuration_options.html" title="8.&nbsp;Configuration Options"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">7.&nbsp;Binders</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__programming_model.html">Prev</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;I.&nbsp;Preface</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="multi__configuration_options.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="spring-cloud-stream-overview-binders" href="#spring-cloud-stream-overview-binders"></a>7.&nbsp;Binders</h2></div></div></div><p>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.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_producers_and_consumers" href="#_producers_and_consumers"></a>7.1&nbsp;Producers and Consumers</h2></div></div></div><p>The following image shows the general relationship of producers and consumers:</p><div class="figure"><a name="d0e2037" href="#d0e2037"></a><p class="title"><b>Figure&nbsp;7.1.&nbsp;Producers and Consumers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/producers-consumers.png" align="middle" alt="producers consumers"></div></div></div><br class="figure-break"><p>A producer is any component that sends messages to a channel.
This section provides information about the main concepts behind the Binder SPI, its main components, and implementation-specific details.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_producers_and_consumers" href="#_producers_and_consumers"></a>7.1&nbsp;Producers and Consumers</h2></div></div></div><p>The following image shows the general relationship of producers and consumers:</p><div class="figure"><a name="d0e2038" href="#d0e2038"></a><p class="title"><b>Figure&nbsp;7.1.&nbsp;Producers and Consumers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/producers-consumers.png" align="middle" alt="producers consumers"></div></div></div><br class="figure-break"><p>A producer is any component that sends messages to a channel.
The channel can be bound to an external message broker with a <code class="literal">Binder</code> implementation for that broker.
When invoking the <code class="literal">bindProducer()</code> method, the first parameter is the name of the destination within the broker, the second parameter is the local channel instance to which the producer sends messages, and the third parameter contains properties (such as a partition key expression) to be used within the adapter that is created for that channel.</p><p>A consumer is any component that receives messages from a channel.
As with a producer, the consumer&#8217;s channel can be bound to an external message broker.

View File

@@ -14,7 +14,7 @@ When the <span class="quote">&#8220;<span class="quote">Cloud Stream</span>&#822
We recommend using the one you have already installed or feel more comfortable with installing and running.
Also, as you can see from the Initilaizer screen, there are a few other options you can choose.
For example, you can choose Gradle as your build tool instead of Maven (the default).</p></li><li class="listitem"><p class="simpara">In the <span class="strong"><strong>Artifact</strong></span> field, type 'logging-consumer'.</p><p class="simpara">The value of the <span class="strong"><strong>Artifact</strong></span> field becomes the application name.
If you chose RabbitMQ for the middleware, your Spring Initializr should now be as follows:</p><div class="informalfigure"><div class="mediaobject"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/spring-initializr.png" alt="Spring Initializr"></div></div></li><li class="listitem"><p class="simpara">Click the <span class="strong"><strong>Generate Project</strong></span> button.</p><p class="simpara">Doing so downloads the zipped version of the generated project to your hard drive.</p></li><li class="listitem">Unzip the file into the folder you want to use as your project directory.</li></ol></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>We encourage you to explore the many possibilities available in the Spring Initializr.
If you chose RabbitMQ for the middleware, your Spring Initializr should now be as follows:</p></li></ol></div><div class="informalfigure"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/spring-initializr.png" align="middle" alt="spring initializr"></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara">Click the <span class="strong"><strong>Generate Project</strong></span> button.</p><p class="simpara">Doing so downloads the zipped version of the generated project to your hard drive.</p></li><li class="listitem">Unzip the file into the folder you want to use as your project directory.</li></ol></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>We encourage you to explore the many possibilities available in the Spring Initializr.
It lets you create many different kinds of Spring applications.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-preface-importing-project" href="#spring-cloud-stream-preface-importing-project"></a>2.2&nbsp;Importing the Project into Your IDE</h2></div></div></div><p>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.
For example, depending on how the project was generated (Maven or Gradle), you may need to follow specific import procedure (for example, in Eclipse or STS, you need to use File &#8594; Import &#8594; Maven &#8594; Existing Maven Project).</p><p>Once imported, the project must have no errors of any kind. Also, <code class="literal">src/main/java</code> should contain <code class="literal">com.example.loggingconsumer.LoggingConsumerApplication</code>.</p><p>Technically, at this point, you can run the application&#8217;s main class.
@@ -127,7 +127,7 @@ You can use this in the application by autowiring it, as shown in the following
}</pre></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_main_concepts" href="#_main_concepts"></a>5.&nbsp;Main Concepts</h2></div></div></div><p>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:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="link" href="#spring-cloud-stream-overview-application-model" title="5.1&nbsp;Application Model">Spring Cloud Stream&#8217;s application model</a></li><li class="listitem"><a class="xref" href="#spring-cloud-stream-overview-binder-abstraction" title="5.2&nbsp;The Binder Abstraction">Section&nbsp;5.2, &#8220;The Binder Abstraction&#8221;</a></li><li class="listitem"><a class="link" href="#spring-cloud-stream-overview-persistent-publish-subscribe-support" title="5.3&nbsp;Persistent Publish-Subscribe Support">Persistent publish-subscribe support</a></li><li class="listitem"><a class="link" href="#consumer-groups" title="5.4&nbsp;Consumer Groups">Consumer group support</a></li><li class="listitem"><a class="link" href="#partitioning" title="5.6&nbsp;Partitioning Support">Partitioning support</a></li><li class="listitem"><a class="link" href="#spring-cloud-stream-overview-binder-api" title="7.2&nbsp;Binder SPI">A pluggable Binder SPI</a></li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-overview-application-model" href="#spring-cloud-stream-overview-application-model"></a>5.1&nbsp;Application Model</h2></div></div></div><p>A Spring Cloud Stream application consists of a middleware-neutral core.
The application communicates with the outside world through input and output channels injected into it by Spring Cloud Stream.
Channels are connected to external brokers through middleware-specific Binder implementations.</p><div class="figure"><a name="d0e728" href="#d0e728"></a><p class="title"><b>Figure&nbsp;5.1.&nbsp;Spring Cloud Stream Application</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-with-binder.png" align="middle" alt="SCSt with binder"></div></div></div><br class="figure-break"><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_fat_jar" href="#_fat_jar"></a>5.1.1&nbsp;Fat JAR</h3></div></div></div><p>Spring Cloud Stream applications can be run in stand-alone mode from your IDE for testing.
Channels are connected to external brokers through middleware-specific Binder implementations.</p><div class="figure"><a name="d0e729" href="#d0e729"></a><p class="title"><b>Figure&nbsp;5.1.&nbsp;Spring Cloud Stream Application</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-with-binder.png" align="middle" alt="SCSt with binder"></div></div></div><br class="figure-break"><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_fat_jar" href="#_fat_jar"></a>5.1.1&nbsp;Fat JAR</h3></div></div></div><p>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 <span class="quote">&#8220;<span class="quote">fat</span>&#8221;</span>) JAR by using the standard Spring Boot tooling provided for Maven or Gradle. See the <a class="link" href="https://docs.spring.io/spring-boot/docs/current/reference/html/howto-build.html#howto-create-an-executable-jar-with-maven" target="_top">Spring Boot Reference Guide</a> for more details.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-overview-binder-abstraction" href="#spring-cloud-stream-overview-binder-abstraction"></a>5.2&nbsp;The Binder Abstraction</h2></div></div></div><p>Spring Cloud Stream provides Binder implementations for <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-kafka" target="_top">Kafka</a> and <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit" target="_top">Rabbit MQ</a>.
Spring Cloud Stream also includes a <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream/blob/master/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestSupportBinder.java" target="_top">TestSupportBinder</a>, which leaves a channel unmodified so that tests can interact with channels directly and reliably assert on what is received.
You can also use the extensible API to write your own Binder.</p><p>Spring Cloud Stream uses Spring Boot for configuration, and the Binder abstraction makes it possible for a Spring Cloud Stream application to be flexible in how it connects to middleware.
@@ -137,7 +137,7 @@ In the sink example from the <a class="xref" href="#spring-cloud-stream-overview
You can use different types of middleware with the same code.
To do so, include a different binder at build time.
For more complex use cases, you can also package multiple binders with your application and have it choose the binder( and even whether to use different binders for different channels) at runtime.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-overview-persistent-publish-subscribe-support" href="#spring-cloud-stream-overview-persistent-publish-subscribe-support"></a>5.3&nbsp;Persistent Publish-Subscribe Support</h2></div></div></div><p>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.</p><div class="figure"><a name="d0e791" href="#d0e791"></a><p class="title"><b>Figure&nbsp;5.2.&nbsp;Spring Cloud Stream Publish-Subscribe</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-sensors.png" align="middle" alt="SCSt sensors"></div></div></div><br class="figure-break"><p>Data reported by sensors to an HTTP endpoint is sent to a common destination named <code class="literal">raw-sensor-data</code>.
This can be seen in the following figure, which shows a typical deployment for a set of interacting Spring Cloud Stream applications.</p><div class="figure"><a name="d0e792" href="#d0e792"></a><p class="title"><b>Figure&nbsp;5.2.&nbsp;Spring Cloud Stream Publish-Subscribe</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-sensors.png" align="middle" alt="SCSt sensors"></div></div></div><br class="figure-break"><p>Data reported by sensors to an HTTP endpoint is sent to a common destination named <code class="literal">raw-sensor-data</code>.
From the destination, it is independently processed by a microservice application that computes time-windowed averages and by another microservice application that ingests the raw data into HDFS (Hadoop Distributed File System).
In order to process the data, both applications declare the topic as their input at runtime.</p><p>The publish-subscribe communication model reduces the complexity of both the producer and the consumer and lets new applications be added to the topology without disruption of the existing flow.
For example, downstream from the average-calculating application, you can add an application that calculates the highest temperature values for display and monitoring.
@@ -147,7 +147,7 @@ By using native middleware support, Spring Cloud Stream also simplifies use of t
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.</p><p>Spring Cloud Stream models this behavior through the concept of a consumer group.
(Spring Cloud Stream consumer groups are similar to and inspired by Kafka consumer groups.)
Each consumer binding can use the <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group</code> property to specify a group name.
For the consumers shown in the following figure, this property would be set as <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=hdfsWrite</code> or <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=average</code>.</p><div class="figure"><a name="d0e825" href="#d0e825"></a><p class="title"><b>Figure&nbsp;5.3.&nbsp;Spring Cloud Stream Consumer Groups</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-groups.png" align="middle" alt="SCSt groups"></div></div></div><br class="figure-break"><p>All groups that subscribe to a given destination receive a copy of published data, but only one member of each group receives a given message from that destination.
For the consumers shown in the following figure, this property would be set as <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=hdfsWrite</code> or <code class="literal">spring.cloud.stream.bindings.&lt;channelName&gt;.group=average</code>.</p><div class="figure"><a name="d0e826" href="#d0e826"></a><p class="title"><b>Figure&nbsp;5.3.&nbsp;Spring Cloud Stream Consumer Groups</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-groups.png" align="middle" alt="SCSt groups"></div></div></div><br class="figure-break"><p>All groups that subscribe to a given destination receive a copy of published data, but only one member of each group receives a given message from that destination.
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.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="consumer-types" href="#consumer-types"></a>5.5&nbsp;Consumer Types</h2></div></div></div><p>Two types of consumer are supported:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">Message-driven (sometimes referred to as Asynchronous)</li><li class="listitem">Polled (sometimes referred to as Synchronous)</li></ul></div><p>Prior to version 2.0, only asynchronous consumers were supported. A message is delivered as soon as it is available and a thread is available to process it.</p><p>When you wish to control the rate at which messages are processed, you might want to use a synchronous consumer.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="durability" href="#durability"></a>5.5.1&nbsp;Durability</h3></div></div></div><p>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.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Anonymous subscriptions are non-durable by nature.
For some binder implementations (such as RabbitMQ), it is possible to have non-durable group subscriptions.</p></td></tr></table></div><p>In general, it is preferable to always specify a consumer group when binding an application to a given destination.
@@ -155,7 +155,7 @@ When scaling up a Spring Cloud Stream application, you must specify a consumer g
Doing so prevents the application&#8217;s instances from receiving duplicate messages (unless that behavior is desired, which is unusual).</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="partitioning" href="#partitioning"></a>5.6&nbsp;Partitioning Support</h2></div></div></div><p>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.
One or more producer application instances send data to multiple consumer application instances and ensure that data identified by common characteristics are processed by the same consumer instance.</p><p>Spring Cloud Stream provides a common abstraction for implementing partitioned processing use cases in a uniform fashion.
Partitioning can thus be used whether the broker itself is naturally partitioned (for example, Kafka) or not (for example, RabbitMQ).</p><div class="figure"><a name="d0e869" href="#d0e869"></a><p class="title"><b>Figure&nbsp;5.4.&nbsp;Spring Cloud Stream Partitioning</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-partitioning.png" align="middle" alt="SCSt partitioning"></div></div></div><br class="figure-break"><p>Partitioning is a critical concept in stateful processing, where it is critical (for either performance or consistency reasons) to ensure that all related data is processed together.
Partitioning can thus be used whether the broker itself is naturally partitioned (for example, Kafka) or not (for example, RabbitMQ).</p><div class="figure"><a name="d0e870" href="#d0e870"></a><p class="title"><b>Figure&nbsp;5.4.&nbsp;Spring Cloud Stream Partitioning</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-partitioning.png" align="middle" alt="SCSt partitioning"></div></div></div><br class="figure-break"><p>Partitioning is a critical concept in stateful processing, where it is critical (for either performance or consistency reasons) to ensure that all related data is processed together.
For example, in the time-windowed average calculation example, it is important that all measurements from any given sensor are processed by the same application instance.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>To set up a partitioned processing scenario, you must configure both the data-producing and the data-consuming ends.</p></td></tr></table></div></div></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_programming_model" href="#_programming_model"></a>6.&nbsp;Programming Model</h2></div></div></div><p>To understand the programming model, you should be familiar with the following core concepts:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="strong"><strong>Destination Binders:</strong></span> Components responsible to provide integration with the external messaging systems.</li><li class="listitem"><span class="strong"><strong>Destination Bindings:</strong></span> Bridge between the external messaging systems and application provided <span class="emphasis"><em>Producers</em></span> and <span class="emphasis"><em>Consumers</em></span> of messages (created by the Destination Binders).</li><li class="listitem"><span class="strong"><strong>Message:</strong></span> The canonical data structure used by producers and consumers to communicate with Destination Binders (and thus other applications via external messaging systems).</li></ul></div><div class="informalfigure"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/SCSt-overview.png" align="middle" alt="SCSt overview"></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_destination_binders" href="#_destination_binders"></a>6.1&nbsp;Destination Binders</h2></div></div></div><p>Destination Binders are extension components of Spring Cloud Stream responsible for providing the necessary configuration and implementation to facilitate
integration with external messaging systems.
This integration is responsible for connectivity, delegation, and routing of messages to and from producers and consumers, data type conversion,
@@ -380,7 +380,8 @@ Consider the following example of a polled consumer:</p><pre class="programlisti
}
};
}</pre><p>The <code class="literal">PollableMessageSource.poll()</code> method takes a <code class="literal">MessageHandler</code> argument (often a lambda expression, as shown here).
It returns <code class="literal">true</code> if the message was received and successfully processed.</p><p>As with message-driven consumers, if the <code class="literal">MessageHandler</code> throws an exception, messages are published to error channels, as discussed in <span class="quote">&#8220;<span class="quote"><a class="xref" href="#">???</a></span>&#8221;</span>.</p><p>Normally, the <code class="literal">poll()</code> method acknowledges the message when the <code class="literal">MessageHandler</code> exits.
It returns <code class="literal">true</code> if the message was received and successfully processed.</p><p>As with message-driven consumers, if the <code class="literal">MessageHandler</code> throws an exception, messages are published to error channels,
as discussed in <code class="literal"><a class="xref" href="#spring-cloud-stream-overview-error-handling" title="6.4&nbsp;Error Handling">Section&nbsp;6.4, &#8220;Error Handling&#8221;</a></code>.</p><p>Normally, the <code class="literal">poll()</code> method acknowledges the message when the <code class="literal">MessageHandler</code> exits.
If the method exits abnormally, the message is rejected (not re-queued), but see <a class="xref" href="#polled-errors" title="Handling Errors">the section called &#8220;Handling Errors&#8221;</a>.
You can override that behavior by taking responsibility for the acknowledgment, as shown in the following example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> ApplicationRunner poller(PollableMessageSource dest1In, MessageChannel dest2Out) {
@@ -406,7 +407,7 @@ If the service activator throws a <code class="literal">RequeueCurrentMessageExc
The error handling comes in two flavors:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="strong"><strong>application:</strong></span> The error handling is done within the application (custom error handler).</li><li class="listitem"><span class="strong"><strong>system:</strong></span> The error handling is delegated to the binder (re-queue, DL, and others). Note that the techniques are dependent on binder implementation and the
capability of the underlying messaging middleware.</li></ul></div><p>Spring Cloud Stream uses the <a class="link" href="https://github.com/spring-projects/spring-retry" target="_top">Spring Retry</a> library to facilitate successful message processing. See <a class="xref" href="#_retry_template" title="6.4.3&nbsp;Retry Template">Section&nbsp;6.4.3, &#8220;Retry Template&#8221;</a> for more details.
However, when all fails, the exceptions thrown by the message handlers are propagated back to the binder. At that point, binder invokes custom error handler or communicates
the error back to the messaging system (re-queue, DLQ, and others).</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_application_error_handling" href="#_application_error_handling"></a>6.4.1&nbsp;Application Error Handling</h3></div></div></div><p>There are two types of application-level error handling. Errors can be handled at each binding subscription or a global handler can handle all the binding subscription errors. Let&#8217;s review the details.</p><div class="figure"><a name="d0e1506" href="#d0e1506"></a><p class="title"><b>Figure&nbsp;6.1.&nbsp;A Spring Cloud Stream Sink Application with Custom and Global Error Handlers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/custom_vs_global_error_channels.png" align="middle" alt="custom vs global error channels"></div></div></div><br class="figure-break"><p>For each input binding, Spring Cloud Stream creates a dedicated error channel with the following semantics <code class="literal">&lt;destinationName&gt;.errors</code>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The <code class="literal">&lt;destinationName&gt;</code> consists of the name of the binding (such as <code class="literal">input</code>) and the name of the group (such as <code class="literal">myGroup</code>).</p></td></tr></table></div><p>Consider the following:</p><pre class="programlisting">spring.cloud.stream.bindings.input.group=myGroup</pre><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@StreamListener(Sink.INPUT)</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// destination name 'input.myGroup'</span>
the error back to the messaging system (re-queue, DLQ, and others).</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_application_error_handling" href="#_application_error_handling"></a>6.4.1&nbsp;Application Error Handling</h3></div></div></div><p>There are two types of application-level error handling. Errors can be handled at each binding subscription or a global handler can handle all the binding subscription errors. Let&#8217;s review the details.</p><div class="figure"><a name="d0e1507" href="#d0e1507"></a><p class="title"><b>Figure&nbsp;6.1.&nbsp;A Spring Cloud Stream Sink Application with Custom and Global Error Handlers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/custom_vs_global_error_channels.png" align="middle" alt="custom vs global error channels"></div></div></div><br class="figure-break"><p>For each input binding, Spring Cloud Stream creates a dedicated error channel with the following semantics <code class="literal">&lt;destinationName&gt;.errors</code>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The <code class="literal">&lt;destinationName&gt;</code> consists of the name of the binding (such as <code class="literal">input</code>) and the name of the group (such as <code class="literal">myGroup</code>).</p></td></tr></table></div><p>Consider the following:</p><pre class="programlisting">spring.cloud.stream.bindings.input.group=myGroup</pre><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@StreamListener(Sink.INPUT)</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// destination name 'input.myGroup'</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> handle(Person value) {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throw</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RuntimeException(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"BOOM!"</span>);
}
@@ -549,7 +550,7 @@ The <code class="literal">Publisher</code> in the following example still uses R
.toReactivePublisher();
}
}</pre></div></div></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="spring-cloud-stream-overview-binders" href="#spring-cloud-stream-overview-binders"></a>7.&nbsp;Binders</h2></div></div></div><p>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.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_producers_and_consumers" href="#_producers_and_consumers"></a>7.1&nbsp;Producers and Consumers</h2></div></div></div><p>The following image shows the general relationship of producers and consumers:</p><div class="figure"><a name="d0e2037" href="#d0e2037"></a><p class="title"><b>Figure&nbsp;7.1.&nbsp;Producers and Consumers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/producers-consumers.png" align="middle" alt="producers consumers"></div></div></div><br class="figure-break"><p>A producer is any component that sends messages to a channel.
This section provides information about the main concepts behind the Binder SPI, its main components, and implementation-specific details.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_producers_and_consumers" href="#_producers_and_consumers"></a>7.1&nbsp;Producers and Consumers</h2></div></div></div><p>The following image shows the general relationship of producers and consumers:</p><div class="figure"><a name="d0e2038" href="#d0e2038"></a><p class="title"><b>Figure&nbsp;7.1.&nbsp;Producers and Consumers</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/producers-consumers.png" align="middle" alt="producers consumers"></div></div></div><br class="figure-break"><p>A producer is any component that sends messages to a channel.
The channel can be bound to an external message broker with a <code class="literal">Binder</code> implementation for that broker.
When invoking the <code class="literal">bindProducer()</code> method, the first parameter is the name of the destination within the broker, the second parameter is the local channel instance to which the producer sends messages, and the third parameter contains properties (such as a partition key expression) to be used within the adapter that is created for that channel.</p><p>A consumer is any component that receives messages from a channel.
As with a producer, the consumer&#8217;s channel can be bound to an external message broker.
@@ -677,7 +678,7 @@ When this configuration is being used, the outbound message marshalling is not b
When native encoding is used, it is the responsibility of the consumer to use an appropriate decoder (for example, the Kafka consumer value de-serializer) to deserialize the inbound message.
Also, when native encoding and decoding is used, the <code class="literal">headerMode=embeddedHeaders</code> property is ignored and headers are not embedded in the message.
See the consumer property <code class="literal">useNativeDecoding</code>.</p><p class="simpara">Default: <code class="literal">false</code>.</p></dd><dt><span class="term">errorChannelEnabled</span></dt><dd><p class="simpara">When set to <code class="literal">true</code>, if the binder supports asynchroous send results, send failures are sent to an error channel for the destination.
See <span class="quote">&#8220;<span class="quote"><a class="xref" href="#">???</a></span>&#8221;</span> for more information.</p><p class="simpara">Default: <code class="literal">false</code>.</p></dd></dl></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="dynamicdestination" href="#dynamicdestination"></a>8.3&nbsp;Using Dynamically Bound Destinations</h2></div></div></div><p>Besides the channels defined by using <code class="literal">@EnableBinding</code>, Spring Cloud Stream lets applications send messages to dynamically bound destinations.
See <code class="literal"><a class="xref" href="#spring-cloud-stream-overview-error-handling" title="6.4&nbsp;Error Handling">Section&nbsp;6.4, &#8220;Error Handling&#8221;</a></code> for more information.</p><p class="simpara">Default: <code class="literal">false</code>.</p></dd></dl></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="dynamicdestination" href="#dynamicdestination"></a>8.3&nbsp;Using Dynamically Bound Destinations</h2></div></div></div><p>Besides the channels defined by using <code class="literal">@EnableBinding</code>, 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 by using the <code class="literal">BinderAwareChannelResolver</code> bean, registered automatically by the <code class="literal">@EnableBinding</code> annotation.</p><p>The 'spring.cloud.stream.dynamicDestinations' property can be used for restricting the dynamic destination names to a known set (whitelisting).
If this property is not set, any destination can be bound dynamically.</p><p>The <code class="literal">BinderAwareChannelResolver</code> can be used directly, as shown in the following example of a REST controller using a path variable to decide the target channel:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@EnableBinding</span></em>
@@ -899,10 +900,10 @@ If you want to use the Confluent schema registry, you need to create a bean of t
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> client;
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The ConfluentSchemaRegistryClient is tested against Confluent platform version 4.0.0.</p></td></tr></table></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_schema_registration_and_resolution" href="#_schema_registration_and_resolution"></a>10.6&nbsp;Schema Registration and Resolution</h2></div></div></div><p>To better understand how Spring Cloud Stream registers and resolves new schemas and its use of Avro schema comparison features, we provide two separate subsections:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="quote">&#8220;<span class="quote"><a class="xref" href="#spring-cloud-stream-overview-schema-registration-process" title="10.6.1&nbsp;Schema Registration Process (Serialization)">Section&nbsp;10.6.1, &#8220;Schema Registration Process (Serialization)&#8221;</a></span>&#8221;</span></li><li class="listitem"><span class="quote">&#8220;<span class="quote"><a class="xref" href="#spring-cloud-stream-overview-schema-resolution-process" title="10.6.2&nbsp;Schema Resolution Process (Deserialization)">Section&nbsp;10.6.2, &#8220;Schema Resolution Process (Deserialization)&#8221;</a></span>&#8221;</span></li></ul></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-stream-overview-schema-registration-process" href="#spring-cloud-stream-overview-schema-registration-process"></a>10.6.1&nbsp;Schema Registration Process (Serialization)</h3></div></div></div><p>The first part of the registration process is extracting a schema from the payload that is being sent over a channel.
Avro types such as <code class="literal">SpecificRecord</code> or <code class="literal">GenericRecord</code> already contain a schema, which can be retrieved immediately from the instance.
In the case of POJOs, a schema is inferred if the <code class="literal">spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled</code> property is set to <code class="literal">true</code> (the default).</p><div class="figure"><a name="d0e4089" href="#d0e4089"></a><p class="title"><b>Figure&nbsp;10.1.&nbsp;Schema Writer Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_resolution.png" align="middle" alt="schema resolution"></div></div></div><br class="figure-break"><p>Ones a schema is obtained, the converter loads its metadata (version) from the remote server.
In the case of POJOs, a schema is inferred if the <code class="literal">spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled</code> property is set to <code class="literal">true</code> (the default).</p><div class="figure"><a name="d0e4090" href="#d0e4090"></a><p class="title"><b>Figure&nbsp;10.1.&nbsp;Schema Writer Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_resolution.png" align="middle" alt="schema resolution"></div></div></div><br class="figure-break"><p>Ones a schema is obtained, the converter loads its metadata (version) from the remote server.
First, it queries a local cache. If no result is found, it submits the data to the server, which replies with versioning information.
The converter always caches the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.</p><div class="figure"><a name="d0e4100" href="#d0e4100"></a><p class="title"><b>Figure&nbsp;10.2.&nbsp;Schema Registration Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/registration.png" align="middle" alt="registration"></div></div></div><br class="figure-break"><p>With the schema version information, the converter sets the <code class="literal">contentType</code> header of the message to carry the version information&#8201;&#8212;&#8201;for example: <code class="literal">application/vnd.user.v1+avro</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-stream-overview-schema-resolution-process" href="#spring-cloud-stream-overview-schema-resolution-process"></a>10.6.2&nbsp;Schema Resolution Process (Deserialization)</h3></div></div></div><p>When reading messages that contain version information (that is, a <code class="literal">contentType</code> header with a scheme like the one described under <span class="quote">&#8220;<span class="quote"><a class="xref" href="#spring-cloud-stream-overview-schema-registration-process" title="10.6.1&nbsp;Schema Registration Process (Serialization)">Section&nbsp;10.6.1, &#8220;Schema Registration Process (Serialization)&#8221;</a></span>&#8221;</span>), the converter queries the Schema server to fetch the writer schema of the message.
Once it has found the correct schema of the incoming message, it retrieves the reader schema and, by using Avro&#8217;s schema resolution support, reads it into the reader definition (setting defaults and any missing properties).</p><div class="figure"><a name="d0e4128" href="#d0e4128"></a><p class="title"><b>Figure&nbsp;10.3.&nbsp;Schema Reading Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_reading.png" align="middle" alt="schema reading"></div></div></div><br class="figure-break"><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>You should understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application).
The converter always caches the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.</p><div class="figure"><a name="d0e4101" href="#d0e4101"></a><p class="title"><b>Figure&nbsp;10.2.&nbsp;Schema Registration Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/registration.png" align="middle" alt="registration"></div></div></div><br class="figure-break"><p>With the schema version information, the converter sets the <code class="literal">contentType</code> header of the message to carry the version information&#8201;&#8212;&#8201;for example: <code class="literal">application/vnd.user.v1+avro</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-stream-overview-schema-resolution-process" href="#spring-cloud-stream-overview-schema-resolution-process"></a>10.6.2&nbsp;Schema Resolution Process (Deserialization)</h3></div></div></div><p>When reading messages that contain version information (that is, a <code class="literal">contentType</code> header with a scheme like the one described under <span class="quote">&#8220;<span class="quote"><a class="xref" href="#spring-cloud-stream-overview-schema-registration-process" title="10.6.1&nbsp;Schema Registration Process (Serialization)">Section&nbsp;10.6.1, &#8220;Schema Registration Process (Serialization)&#8221;</a></span>&#8221;</span>), the converter queries the Schema server to fetch the writer schema of the message.
Once it has found the correct schema of the incoming message, it retrieves the reader schema and, by using Avro&#8217;s schema resolution support, reads it into the reader definition (setting defaults and any missing properties).</p><div class="figure"><a name="d0e4129" href="#d0e4129"></a><p class="title"><b>Figure&nbsp;10.3.&nbsp;Schema Reading Resolution Process</b></p><div class="figure-contents"><div class="mediaobject" align="center"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/schema_reading.png" align="middle" alt="schema reading"></div></div></div><br class="figure-break"><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>You should understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application).
We suggest taking a moment to read <a class="link" href="https://avro.apache.org/docs/1.7.6/spec.html" target="_top">the Avro terminology</a> and understand the process.
Spring Cloud Stream always fetches the writer schema to determine how to read a message.
If you want to get Avro&#8217;s schema evolution support working, you need to make sure that a <code class="literal">readerSchema</code> was properly set for your application.</p></td></tr></table></div></div></div></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_inter_application_communication" href="#_inter_application_communication"></a>11.&nbsp;Inter-Application Communication</h2></div></div></div><p>Spring Cloud Stream enables communication between applications. Inter-application communication is a complex issue spanning several concerns, as described in the following topics:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="quote">&#8220;<span class="quote"><a class="xref" href="#spring-cloud-stream-overview-connecting-multiple-application-instances" title="11.1&nbsp;Connecting Multiple Application Instances">Section&nbsp;11.1, &#8220;Connecting Multiple Application Instances&#8221;</a></span>&#8221;</span></li><li class="listitem"><span class="quote">&#8220;<span class="quote"><a class="xref" href="#spring-cloud-stream-overview-instance-index-instance-count" title="11.2&nbsp;Instance Index and Instance Count">Section&nbsp;11.2, &#8220;Instance Index and Instance Count&#8221;</a></span>&#8221;</span></li><li class="listitem"><span class="quote">&#8220;<span class="quote"><a class="xref" href="#spring-cloud-stream-overview-partitioning" title="11.3&nbsp;Partitioning">Section&nbsp;11.3, &#8220;Partitioning&#8221;</a></span>&#8221;</span></li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-stream-overview-connecting-multiple-application-instances" href="#spring-cloud-stream-overview-connecting-multiple-application-instances"></a>11.1&nbsp;Connecting Multiple Application Instances</h2></div></div></div><p>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.
@@ -1048,4 +1049,4 @@ For example, specifying <code class="literal">spring.integration.*</code> captur
}
]
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Given that the format of the Metric message has slightly changed after migrating to Micrometer, the published message will also have
a <code class="literal">STREAM_CLOUD_STREAM_VERSION</code> header set to <code class="literal">2.x</code> to help distinguish between Metric messages from the older versions of the Spring Cloud Stream.</p></td></tr></table></div></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_samples" href="#_samples"></a>15.&nbsp;Samples</h2></div></div></div><p>For Spring Cloud Stream samples, see the <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-samples" target="_top">spring-cloud-stream-samples</a> repository on GitHub.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_deploying_stream_applications_on_cloudfoundry" href="#_deploying_stream_applications_on_cloudfoundry"></a>15.1&nbsp;Deploying Stream Applications on CloudFoundry</h2></div></div></div><p>On CloudFoundry, services are usually exposed through a special environment variable called <a class="link" href="https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES" target="_top">VCAP_SERVICES</a>.</p><p>When configuring your binder connections, you can use the values from an environment variable as explained on the <a class="link" href="http://docs.spring.io/spring-cloud-dataflow-server-cloudfoundry/docs/current-SNAPSHOT/reference/htmlsingle/#getting-started-ups" target="_top">dataflow Cloud Foundry Server</a> docs.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_binder_implementations" href="#_binder_implementations"></a>16.&nbsp;Binder Implementations</h2></div></div></div><p>The following is the list of available binder implementations</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">[RabbitMQ](<a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-rabbit/" target="_top">https://cloud.spring.io/spring-cloud-stream-binder-rabbit/</a>)</li><li class="listitem">[Apache Kafka](<a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-kafka/" target="_top">https://cloud.spring.io/spring-cloud-stream-binder-kafka/</a>)</li><li class="listitem">[Amazon Kinesis](<a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis" target="_top">https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis</a>)</li><li class="listitem">[Google PubSub <span class="emphasis"><em>(partner maintained)</em></span>](<a class="link" href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder" target="_top">https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder</a>)</li><li class="listitem">[Solace PubSub+ <span class="emphasis"><em>(partner maintained)</em></span>](<a class="link" href="https://github.com/SolaceProducts/spring-cloud-stream-binder-solace" target="_top">https://github.com/SolaceProducts/spring-cloud-stream-binder-solace</a>)</li><li class="listitem">[Azure Event Hubs <span class="emphasis"><em>(partner maintained)</em></span>](<a class="link" href="https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder" target="_top">https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder</a>)</li></ul></div></div></div></div></body></html>
a <code class="literal">STREAM_CLOUD_STREAM_VERSION</code> header set to <code class="literal">2.x</code> to help distinguish between Metric messages from the older versions of the Spring Cloud Stream.</p></td></tr></table></div></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_samples" href="#_samples"></a>15.&nbsp;Samples</h2></div></div></div><p>For Spring Cloud Stream samples, see the <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-samples" target="_top">spring-cloud-stream-samples</a> repository on GitHub.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_deploying_stream_applications_on_cloudfoundry" href="#_deploying_stream_applications_on_cloudfoundry"></a>15.1&nbsp;Deploying Stream Applications on CloudFoundry</h2></div></div></div><p>On CloudFoundry, services are usually exposed through a special environment variable called <a class="link" href="https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES" target="_top">VCAP_SERVICES</a>.</p><p>When configuring your binder connections, you can use the values from an environment variable as explained on the <a class="link" href="http://docs.spring.io/spring-cloud-dataflow-server-cloudfoundry/docs/current-SNAPSHOT/reference/htmlsingle/#getting-started-ups" target="_top">dataflow Cloud Foundry Server</a> docs.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_binder_implementations" href="#_binder_implementations"></a>16.&nbsp;Binder Implementations</h2></div></div></div><p>The following is the list of available binder implementations</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-rabbit/" target="_top">RabbitMQ</a></li><li class="listitem"><a class="link" href="https://cloud.spring.io/spring-cloud-stream-binder-kafka/" target="_top">Apache Kafka</a></li><li class="listitem"><a class="link" href="https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis" target="_top">Amazon Kinesis</a></li><li class="listitem"><a class="link" href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder" target="_top">Google PubSub <span class="emphasis"><em>(partner maintained)</em></span></a></li><li class="listitem"><a class="link" href="https://github.com/SolaceProducts/spring-cloud-stream-binder-solace" target="_top">Solace PubSub+ <span class="emphasis"><em>(partner maintained)</em></span></a></li><li class="listitem"><a class="link" href="https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder" target="_top">Azure Event Hubs <span class="emphasis"><em>(partner maintained)</em></span></a></li></ul></div></div></div></div></body></html>

View File

@@ -4,7 +4,7 @@
<book xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
<info>
<title>Spring Cloud Stream Reference Guide</title>
<date>2018-11-16</date>
<date>2018-12-12</date>
<authorgroup>
<author>
<personname>
@@ -172,15 +172,17 @@ For example, you can choose Gradle as your build tool instead of Maven (the defa
<simpara>In the <emphasis role="strong">Artifact</emphasis> field, type 'logging-consumer'.</simpara>
<simpara>The value of the <emphasis role="strong">Artifact</emphasis> field becomes the application name.
If you chose RabbitMQ for the middleware, your Spring Initializr should now be as follows:</simpara>
</listitem>
</orderedlist>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/spring-initializr.png"/>
<imagedata fileref="https://raw.githubusercontent.com/spring-cloud/spring-cloud-stream/master/docs/src/main/asciidoc/images/spring-initializr.png" align="center"/>
</imageobject>
<textobject><phrase>Spring Initializr</phrase></textobject>
<textobject><phrase>spring initializr</phrase></textobject>
</mediaobject>
</informalfigure>
</listitem>
<orderedlist numeration="arabic">
<listitem>
<simpara>Click the <emphasis role="strong">Generate Project</emphasis> button.</simpara>
<simpara>Doing so downloads the zipped version of the generated project to your hard drive.</simpara>
@@ -993,7 +995,8 @@ public ApplicationRunner poller(PollableMessageSource destIn, MessageChannel des
}</programlisting>
<simpara>The <literal>PollableMessageSource.poll()</literal> method takes a <literal>MessageHandler</literal> argument (often a lambda expression, as shown here).
It returns <literal>true</literal> if the message was received and successfully processed.</simpara>
<simpara>As with message-driven consumers, if the <literal>MessageHandler</literal> throws an exception, messages are published to error channels, as discussed in <quote><xref linkend="binder-error-channels"/></quote>.</simpara>
<simpara>As with message-driven consumers, if the <literal>MessageHandler</literal> throws an exception, messages are published to error channels,
as discussed in <literal><xref linkend="spring-cloud-stream-overview-error-handling"/></literal>.</simpara>
<simpara>Normally, the <literal>poll()</literal> method acknowledges the message when the <literal>MessageHandler</literal> exits.
If the method exits abnormally, the message is rejected (not re-queued), but see <xref linkend="polled-errors"/>.
You can override that behavior by taking responsibility for the acknowledgment, as shown in the following example:</simpara>
@@ -1884,7 +1887,7 @@ See the consumer property <literal>useNativeDecoding</literal>.</simpara>
<term>errorChannelEnabled</term>
<listitem>
<simpara>When set to <literal>true</literal>, if the binder supports asynchroous send results, send failures are sent to an error channel for the destination.
See <quote><xref linkend="binder-error-channels"/></quote> for more information.</simpara>
See <literal><xref linkend="spring-cloud-stream-overview-error-handling"/></literal> for more information.</simpara>
<simpara>Default: <literal>false</literal>.</simpara>
</listitem>
</varlistentry>
@@ -2874,22 +2877,22 @@ a <literal>STREAM_CLOUD_STREAM_VERSION</literal> header set to <literal>2.x</lit
<simpara>The following is the list of available binder implementations</simpara>
<itemizedlist>
<listitem>
<simpara>[RabbitMQ](<link xl:href="https://cloud.spring.io/spring-cloud-stream-binder-rabbit/">https://cloud.spring.io/spring-cloud-stream-binder-rabbit/</link>)</simpara>
<simpara><link xl:href="https://cloud.spring.io/spring-cloud-stream-binder-rabbit/">RabbitMQ</link></simpara>
</listitem>
<listitem>
<simpara>[Apache Kafka](<link xl:href="https://cloud.spring.io/spring-cloud-stream-binder-kafka/">https://cloud.spring.io/spring-cloud-stream-binder-kafka/</link>)</simpara>
<simpara><link xl:href="https://cloud.spring.io/spring-cloud-stream-binder-kafka/">Apache Kafka</link></simpara>
</listitem>
<listitem>
<simpara>[Amazon Kinesis](<link xl:href="https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis">https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis</link>)</simpara>
<simpara><link xl:href="https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis">Amazon Kinesis</link></simpara>
</listitem>
<listitem>
<simpara>[Google PubSub <emphasis>(partner maintained)</emphasis>](<link xl:href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder">https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder</link>)</simpara>
<simpara><link xl:href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder">Google PubSub <emphasis>(partner maintained)</emphasis></link></simpara>
</listitem>
<listitem>
<simpara>[Solace PubSub+ <emphasis>(partner maintained)</emphasis>](<link xl:href="https://github.com/SolaceProducts/spring-cloud-stream-binder-solace">https://github.com/SolaceProducts/spring-cloud-stream-binder-solace</link>)</simpara>
<simpara><link xl:href="https://github.com/SolaceProducts/spring-cloud-stream-binder-solace">Solace PubSub+ <emphasis>(partner maintained)</emphasis></link></simpara>
</listitem>
<listitem>
<simpara>[Azure Event Hubs <emphasis>(partner maintained)</emphasis>](<link xl:href="https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder">https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder</link>)</simpara>
<simpara><link xl:href="https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder">Azure Event Hubs <emphasis>(partner maintained)</emphasis></link></simpara>
</listitem>
</itemizedlist>
</chapter>