From d755342e62148dfdd47723d0c16da2a0d92f93c4 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Mon, 19 Nov 2018 14:49:07 +0000 Subject: [PATCH] Sync docs from v2.1.0.RC2 to gh-pages --- .../2.1.0.RC2/Guardfile | 20 + .../2.1.0.RC2/css/highlight.css | 35 + .../2.1.0.RC2/css/manual-multipage.css | 9 + .../2.1.0.RC2/css/manual-singlepage.css | 6 + .../2.1.0.RC2/css/manual.css | 344 ++++++ .../2.1.0.RC2/ghpages.sh | 330 ++++++ .../2.1.0.RC2/images/background.png | Bin 0 -> 18255 bytes .../2.1.0.RC2/images/callouts/1.png | Bin 0 -> 329 bytes .../2.1.0.RC2/images/callouts/2.png | Bin 0 -> 353 bytes .../2.1.0.RC2/images/callouts/3.png | Bin 0 -> 350 bytes .../2.1.0.RC2/images/caution.png | Bin 0 -> 2099 bytes .../2.1.0.RC2/images/important.png | Bin 0 -> 2085 bytes .../2.1.0.RC2/images/kafka-binder.png | Bin 0 -> 9469 bytes .../images/kafka-streams-initializr.png | Bin 0 -> 121574 bytes .../2.1.0.RC2/images/logo.png | Bin 0 -> 4387 bytes .../2.1.0.RC2/images/note.png | Bin 0 -> 2257 bytes .../2.1.0.RC2/images/tip.png | Bin 0 -> 931 bytes .../2.1.0.RC2/images/warning.png | Bin 0 -> 2130 bytes .../2.1.0.RC2/index.html | 117 ++ .../2.1.0.RC2/multi/css/highlight.css | 35 + .../2.1.0.RC2/multi/css/manual-multipage.css | 9 + .../2.1.0.RC2/multi/css/manual-singlepage.css | 6 + .../2.1.0.RC2/multi/css/manual.css | 344 ++++++ .../2.1.0.RC2/multi/images/background.png | Bin 0 -> 18255 bytes .../2.1.0.RC2/multi/images/callouts/1.png | Bin 0 -> 329 bytes .../2.1.0.RC2/multi/images/callouts/2.png | Bin 0 -> 353 bytes .../2.1.0.RC2/multi/images/callouts/3.png | Bin 0 -> 350 bytes .../2.1.0.RC2/multi/images/caution.png | Bin 0 -> 2099 bytes .../2.1.0.RC2/multi/images/important.png | Bin 0 -> 2085 bytes .../2.1.0.RC2/multi/images/logo.png | Bin 0 -> 4387 bytes .../2.1.0.RC2/multi/images/note.png | Bin 0 -> 2257 bytes .../2.1.0.RC2/multi/images/tip.png | Bin 0 -> 931 bytes .../2.1.0.RC2/multi/images/warning.png | Bin 0 -> 2130 bytes .../multi__apache_kafka_binder_overview.html | 8 + .../2.1.0.RC2/multi/multi__appendices.html | 3 + .../multi/multi__configuration_options.html | 147 +++ ...i__partitioning_with_the_kafka_binder.html | 72 ++ .../multi/multi__reference_guide.html | 5 + .../2.1.0.RC2/multi/multi__usage.html | 9 + .../2.1.0.RC2/multi/multi_building.html | 56 + .../multi/multi_kafka-dlq-processing.html | 89 ++ .../multi/multi_kafka-error-channels.html | 5 + .../2.1.0.RC2/multi/multi_kafka-metrics.html | 5 + .../multi/multi_kafka-tombstones.html | 9 + .../multi/multi_rebalance-listener.html | 40 + ...ulti_spring-cloud-stream-binder-kafka.html | 3 + .../2.1.0.RC2/single/css/highlight.css | 35 + .../2.1.0.RC2/single/css/manual-multipage.css | 9 + .../single/css/manual-singlepage.css | 6 + .../2.1.0.RC2/single/css/manual.css | 344 ++++++ .../2.1.0.RC2/single/images/background.png | Bin 0 -> 18255 bytes .../2.1.0.RC2/single/images/callouts/1.png | Bin 0 -> 329 bytes .../2.1.0.RC2/single/images/callouts/2.png | Bin 0 -> 353 bytes .../2.1.0.RC2/single/images/callouts/3.png | Bin 0 -> 350 bytes .../2.1.0.RC2/single/images/caution.png | Bin 0 -> 2099 bytes .../2.1.0.RC2/single/images/important.png | Bin 0 -> 2085 bytes .../2.1.0.RC2/single/images/logo.png | Bin 0 -> 4387 bytes .../2.1.0.RC2/single/images/note.png | Bin 0 -> 2257 bytes .../2.1.0.RC2/single/images/tip.png | Bin 0 -> 931 bytes .../2.1.0.RC2/single/images/warning.png | Bin 0 -> 2130 bytes .../spring-cloud-stream-binder-kafka.html | 415 +++++++ .../spring-cloud-stream-binder-kafka.xml | 1000 +++++++++++++++++ 62 files changed, 3515 insertions(+) create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/Guardfile create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/css/highlight.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-multipage.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-singlepage.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/ghpages.sh create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/background.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/callouts/1.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/callouts/2.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/callouts/3.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/caution.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/important.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/kafka-binder.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/kafka-streams-initializr.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/logo.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/note.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/tip.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/images/warning.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/index.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/highlight.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-multipage.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-singlepage.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/background.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/callouts/1.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/callouts/2.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/callouts/3.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/caution.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/important.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/logo.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/note.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/tip.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/warning.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__apache_kafka_binder_overview.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__appendices.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__configuration_options.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__partitioning_with_the_kafka_binder.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__reference_guide.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__usage.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_building.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-dlq-processing.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-error-channels.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-metrics.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-tombstones.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_rebalance-listener.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_spring-cloud-stream-binder-kafka.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/highlight.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-multipage.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-singlepage.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual.css create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/background.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/callouts/1.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/callouts/2.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/callouts/3.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/caution.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/important.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/logo.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/note.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/tip.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/warning.png create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/single/spring-cloud-stream-binder-kafka.html create mode 100644 spring-cloud-stream-binder-kafka/2.1.0.RC2/spring-cloud-stream-binder-kafka.xml diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/Guardfile b/spring-cloud-stream-binder-kafka/2.1.0.RC2/Guardfile new file mode 100644 index 00000000..bdd4d729 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/Guardfile @@ -0,0 +1,20 @@ +require 'asciidoctor' +require 'erb' + +guard 'shell' do + watch(/.*\.adoc$/) {|m| + Asciidoctor.render_file('index.adoc', \ + :in_place => true, \ + :safe => Asciidoctor::SafeMode::UNSAFE, \ + :attributes=> { \ + 'source-highlighter' => 'prettify', \ + 'icons' => 'font', \ + 'linkcss'=> 'true', \ + 'copycss' => 'true', \ + 'doctype' => 'book'}) + } +end + +guard 'livereload' do + watch(%r{^.+\.(css|js|html)$}) +end diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/highlight.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-multipage.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-singlepage.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/ghpages.sh b/spring-cloud-stream-binder-kafka/2.1.0.RC2/ghpages.sh new file mode 100644 index 00000000..6795216e --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/ghpages.sh @@ -0,0 +1,330 @@ +#!/bin/bash -x + +set -e + +# Set default props like MAVEN_PATH, ROOT_FOLDER etc. +function set_default_props() { + # The script should be executed from the root folder + ROOT_FOLDER=`pwd` + echo "Current folder is ${ROOT_FOLDER}" + + if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then + echo "You're not in the root folder of the project!" + exit 1 + fi + + # Prop that will let commit the changes + COMMIT_CHANGES="no" + MAVEN_PATH=${MAVEN_PATH:-} + echo "Path to Maven is [${MAVEN_PATH}]" + REPO_NAME=${PWD##*/} + echo "Repo name is [${REPO_NAME}]" + SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git} + echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}" +} + +# Check if gh-pages exists and docs have been built +function check_if_anything_to_sync() { + git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'` + + if ! (git remote set-branches --add origin gh-pages && git fetch -q); then + echo "No gh-pages, so not syncing" + exit 0 + fi + + if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then + echo "No gh-pages sources in docs/target/generated-docs, so not syncing" + exit 0 + fi +} + +function retrieve_current_branch() { + # Code getting the name of the current branch. For master we want to publish as we did until now + # http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch + # If there is a branch already passed will reuse it - otherwise will try to find it + CURRENT_BRANCH=${BRANCH} + if [[ -z "${CURRENT_BRANCH}" ]] ; then + CURRENT_BRANCH=$(git symbolic-ref -q HEAD) + CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/} + CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD} + fi + echo "Current branch is [${CURRENT_BRANCH}]" + git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" +} + +# Switches to the provided value of the release version. We always prefix it with `v` +function switch_to_tag() { + git checkout v${VERSION} +} + +# Build the docs if switch is on +function build_docs_if_applicable() { + if [[ "${BUILD}" == "yes" ]] ; then + ./mvnw clean install -P docs -pl docs -DskipTests + fi +} + +# Get the name of the `docs.main` property +# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile +function retrieve_doc_properties() { + MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \ + -Dexec.executable="echo" \ + -Dexec.args='${docs.main}' \ + --non-recursive \ + org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) + echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]" + + + WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"} + WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \ + -Dexec.executable="echo" \ + -Dexec.args="\${${WHITELIST_PROPERTY}}" \ + org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \ + -P docs \ + -pl docs) + echo "Extracted '${WHITELIST_PROPERTY}' from Maven build [${WHITELISTED_BRANCHES_VALUE}]" +} + +# Stash any outstanding changes +function stash_changes() { + git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1") + if [ "$dirty" != "0" ]; then git stash; fi +} + +# Switch to gh-pages branch to sync it with current branch +function add_docs_from_target() { + local DESTINATION_REPO_FOLDER + if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then + DESTINATION_REPO_FOLDER=${ROOT_FOLDER} + elif [[ "${CLONE}" == "yes" ]]; then + mkdir -p ${ROOT_FOLDER}/target + local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static + if [[ ! -e "${clonedStatic}/.git" ]]; then + echo "Cloning Spring Cloud Static to target" + git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages + else + echo "Spring Cloud Static already cloned - will pull changes" + cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages + fi + DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME} + mkdir -p ${DESTINATION_REPO_FOLDER} + else + if [[ ! -e "${DESTINATION}/.git" ]]; then + echo "[${DESTINATION}] is not a git repository" + exit 1 + fi + DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME} + mkdir -p ${DESTINATION_REPO_FOLDER} + echo "Destination was provided [${DESTINATION}]" + fi + cd ${DESTINATION_REPO_FOLDER} + git checkout gh-pages + git pull origin gh-pages + + # Add git branches + ################################################################### + if [[ -z "${VERSION}" ]] ; then + copy_docs_for_current_version + else + copy_docs_for_provided_version + fi + commit_changes_if_applicable +} + + +# Copies the docs by using the retrieved properties from Maven build +function copy_docs_for_current_version() { + if [[ "${CURRENT_BRANCH}" == "master" ]] ; then + echo -e "Current branch is master - will copy the current docs only to the root folder" + for f in docs/target/generated-docs/*; do + file=${f#docs/target/generated-docs/*} + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then + # Not ignored... + cp -rf $f ${ROOT_FOLDER}/ + git add -A ${ROOT_FOLDER}/$file + fi + done + COMMIT_CHANGES="yes" + else + echo -e "Current branch is [${CURRENT_BRANCH}]" + # http://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin + if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then + mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH} + echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder" + for f in docs/target/generated-docs/*; do + file=${f#docs/target/generated-docs/*} + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then + # Not ignored... + # We want users to access 2.0.0.BUILD-SNAPSHOT/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html + if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then + # We don't want to copy the spring-cloud-sleuth.html + # we want it to be converted to index.html + cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html + git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html + else + cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH} + git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file + fi + fi + done + COMMIT_CHANGES="yes" + else + echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in + [docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch." + fi + fi +} + +# Copies the docs by using the explicitly provided version +function copy_docs_for_provided_version() { + local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION} + mkdir -p ${FOLDER} + echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder" + for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do + file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*} + copy_docs_for_branch ${file} ${FOLDER} + done + COMMIT_CHANGES="yes" + CURRENT_BRANCH="v${VERSION}" +} + +# Copies the docs from target to the provided destination +# Params: +# $1 - file from target +# $2 - destination to which copy the files +function copy_docs_for_branch() { + local file=$1 + local destination=$2 + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then + # Not ignored... + # We want users to access 2.0.0.BUILD-SNAPSHOT/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html + if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then + # We don't want to copy the spring-cloud-sleuth.html + # we want it to be converted to index.html + cp -rf $f ${destination}/index.html + git add -A ${destination}/index.html + else + cp -rf $f ${destination} + git add -A ${destination}/$file + fi + fi +} + +function commit_changes_if_applicable() { + if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then + COMMIT_SUCCESSFUL="no" + git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes" + + # Uncomment the following push if you want to auto push to + # the gh-pages branch whenever you commit to master locally. + # This is a little extreme. Use with care! + ################################################################### + if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then + git push origin gh-pages + fi + fi +} + +# Switch back to the previous branch and exit block +function checkout_previous_branch() { + # If -version was provided we need to come back to root project + cd ${ROOT_FOLDER} + git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" + if [ "$dirty" != "0" ]; then git stash pop; fi + exit 0 +} + +# Assert if properties have been properly passed +function assert_properties() { +echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]" +if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi +if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi +if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi +} + +# Prints the usage +function print_usage() { +cat </` +- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will + switch to gh-pages of that repo and copy the generated docs to `docs//` + +USAGE: + +You can use the following options: + +-v|--version - the script will apply the whole procedure for a particular library version +-d|--destination - the root of destination folder where the docs should be copied. You have to use the full path. + E.g. point to spring-cloud-static folder. Can't be used with (-c) +-b|--build - will run the standard build process after checking out the branch +-c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination. + Obviously can't be used with (-d) + +EOF +} + + +# ========================================== +# ____ ____ _____ _____ _____ _______ +# / ____|/ ____| __ \|_ _| __ \__ __| +# | (___ | | | |__) | | | | |__) | | | +# \___ \| | | _ / | | | ___/ | | +# ____) | |____| | \ \ _| |_| | | | +# |_____/ \_____|_| \_\_____|_| |_| +# +# ========================================== + +while [[ $# > 0 ]] +do +key="$1" +case ${key} in + -v|--version) + VERSION="$2" + shift # past argument + ;; + -d|--destination) + DESTINATION="$2" + shift # past argument + ;; + -b|--build) + BUILD="yes" + ;; + -c|--clone) + CLONE="yes" + ;; + -h|--help) + print_usage + exit 0 + ;; + *) + echo "Invalid option: [$1]" + print_usage + exit 1 + ;; +esac +shift # past argument or value +done + +assert_properties +set_default_props +check_if_anything_to_sync +if [[ -z "${VERSION}" ]] ; then + retrieve_current_branch +else + switch_to_tag +fi +build_docs_if_applicable +retrieve_doc_properties +stash_changes +add_docs_from_target +checkout_previous_branch \ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/background.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..15dca6fbe2669fae3609605e49c69cc414f1b6ed GIT binary patch literal 18255 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 EKU&lfD*ylh literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/callouts/1.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/callouts/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d473430b7bec514f7de12f5769fe7c5859e8c5d GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}^nQC}X^4DKU-G|w_t}fLBA)Suv#nrW z!^h2QnY_`l!BOq-UXEX{m2up>JTQkX)2m zTvF+fTUlI^nXH#utd~++ke^qgmzgTe~DWM4ffP81J literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/callouts/2.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/callouts/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5d09341b2f6d2ea2d1d5dad5d980f14b4b05dfd2 GIT binary patch literal 353 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 literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/kafka-binder.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/kafka-binder.png new file mode 100644 index 0000000000000000000000000000000000000000..7c6c4c02018322ef83787be5c91852b13f96d412 GIT binary patch literal 9469 zcmY*fcRbtO_qSSFE!Cw|sVc3VTCsxC(o(Bdt)NzGSBxfhQBMbol2}o-SJkRUVn0PC z_9`)p*fU~}-zWM!-|zSLPhNR_?l|Y3d(OG<^S<|uo{q-Z)10SiXlTwpd~okE4Gk?B z_}|BL68Ke%YDwgECM&W5?C z!VnUB+LMjp-kP3L?yDzvvtD(x&i(xTAd)?^$g8hk%T-I<`>m> zn)`=vIT!@_hN{^y_n~qB%E0Dw`MfbWh>XAL~r6c~+$^ z$Xox737jsgy#hZ#NY9Z{o%*vwoklHnpAO&D!Y2CQ>76zj6l&%boJbL-mdx$nhtc9^ zJCE+eDo8(*AQo?#czdPdokpiOcMpZ`N{dQv;p+!RGa1Lcb!&=bxZsSF#%1LtClrD* z)kVJ_kQbNlAA#x)zjQfw%&gyIO5YY*-QDkau)6rsYBg)4ihU`NrEc7ZvQA%|8v}OP zmy*ty)G#CBKJDCjUSRQsiPz91(XG*y1wwkrDfTZEItnNch>o=mRI<-@6kO^bJ9D)_D9XU5abJs z^?5Kdqq~=U`J8x^saH-_1xfpQi0gD;1k}Vt*V3zfHVeOaS{dn`EKJl_Ak%1o`80Bk zqz9KM0i)h^t9W6Sn$uUl7KuLRoy$^4ZC93W$*O!FQMcrs>Iyh$w5qn721~oDCFbLt&qR5^jozH1prtPL z#;$L7O9YO4VZ@`0hfdOXs9tWNh$XLwpWNsu--OolkI8_Jnhx`v+F~@hY-r^{8ltT0 zy&D&5R94T&&&zg&KqV+m;*pBGc47h6ECl_A+aF@Q|K=g!$~V%HOxv=87K+d7;TaK7 zbp{$z9oHbVrhFqPCf(b#I`VpSoNLR-w9iqT^=U$gTq#zFVXD+eo|gMo@&H$$n)kB) zMpn->e58J8xsD6Pmz>|Sv=(S2;msCu?N*Wd(9zZD&Fq%*U$IQ5sLfbGNq*^rS}gLt z%`S%yLU(NSYwR3~CA*LoW*xPdsiNLooyU>j37o*i^Te_K}VFChr(T;&Fr$#`u4unc?fk%WBoj-E1N>i z-`5frelV41g`ESoHs(^fsj)wwitVrzV|SV1b;;xtb}pyM_I*8+t#A1`U&JMCpl&qP z(rx*#eN3+NExh3lZDLEgnvbq zby?h)ob}i`i(%o~Nx3D3L6x5JwDswyW-rI?07JAla9A`0NhWkBKgo30cXJW_DwA<% zuU4e5CXq7;1u0$F5w_?gfeX9$L3UGsbOy?RmpNx+>!?&@EOSl{COyuA7+Tm41mMmI8jgMmKW z-_USF_Q(|$!r9v0&_jy#;dadlAZ(ghd}<1l5iXB6RHGhWjQj|oWz{mEElP* zve^og?_0cuzCuGdi%Rotvac?ON0(~v%A!%*z(Z@P7{1BJOy;Iy*+&WcCclKYi2jD5*TGKgoa@xRIYjM^7a^sqAo z{elJy8BGq*!%&?hlZfwi7N5jCSUZxfAk~#-2UClP4&61ZQCs_HAx)0lxUVI`=_ryH zHRHq5it+oHeG0JGNmA|)8!>Vtp0sH+m+I`;+~QGnrXXUgs?l#TmM5BGCTH2xTkVXc zgSCZ^93U&ll(-AwORoy>Ke5XPLh%w zquLC~*{u6@7NDkQ9XnFmK;+&5X|%n@Y~<&-bF#ID;`OS|*4gDHhBA@ZNxzswH{ZeMOY|7X2r)?!~1eoG5JeV4%K{!rZCaxPZ6a}e=e_A8;zmbfR zg4|UzGe2)#nyF8A%JZx}tXV@$V~rpV&r1etE_0StNn2|6FaVj99(GYTuq{4nD4?{q z(_aU`1w<}aT-V!Fu5VJJOU$&uo`k@$dBge&jyq{d;?Dwg$aM6}`pn}XkOp$_TPfN6-I`@7A z8+`SYcBC>j-CIXdz1=*r7pJVlJxmMiB^}_C^st48he7676B!u+ZI9K#gpRB?0t~~+$GTi%z7KRvY4Vtkqy>by@t}}^l3VW;xAE%S ziVvubT*r=7#0>lC>)!9*Dga*OKIx;UzVKiF8go)m+D+D|bH|}b{5yV3-VSP2EbC-q zx0e&cD9$Iv$8a3ymnl`Z#*AT=kS}kWjD?~*+@V&=-o48lI^0~mf0mRF08*W^iSV-1 zK7<}+zr$cQr`f_w4=cx{j@5S&Mit9$=W|+BXnQXYS{>m`Eq8PEncYnAthlFr2Lv`c zs&Q?t1D)HF^MCiR@r-?~;dA4sAuhH61}EpGq1ZFuW~u92Jj z+j#{7%<^%zK!ppC*+x4kZ)CmAynkj8DI(T62rCD&_vZ>Qvv(W9kjeUYKs3 zzd~e@NhqG2OID|Wy(gZd&egy+kZYRE($p484+}e!m9y)fa5B)lwtb~#scUa9_xRL@ zVq~qDZ*y1tUOi*&#`4( zR}AOd%OSbg!edis67ootoZr>f- zaLRk-&JR@-a6%B}fs4+?)eg=m4SXm7&#Lo>wuB3o9i#MA9|kzLg`Fd$9Spe7MqWd) zb`|VSTiiTP;2%#)*136=aI_ksJWCU4blb$jqLAl8Vh*y|4Y#HqpOln;l$x4aBq1T8 z+F_3Iw9kN%d`G;Ip4bunF)Qenqw-#2k+m3nmE&ry$t_l>gm+9*?ZIFC;HR{t+vzrk z#akWB^%kcmg5gE>Z_Pf}51(-W>eD=Z@USuK;+xa3Id5b_!s}0h5I2mj|7<63Uxo(j z!JRqph^mb;4+%8YpNgMq_@T2ITj<+W;J7*D~{$jHX|xHl+q5~dl$;8umh z-#3=+(>a9Eeq==~M5(Xh2(+Xz(fEy4mU_gZ7G|C%^_wS5tbAKVW&LpYYWnO02T**uZJySjn zrAxc&w__!dzrh?nNTXr9;h2qY z)2PM>RxmT^G4ApL+`(o9K)bdL7Ko*FcR86ZQleHDaj~rraS5BKi|pbS{1CTy6*~af zXtvdB_fWK_BN?Q;nktuXz{m<3zy-lrxR%LNZ~@<;e=xL4q&rl#JA zl`d;H<5GM{2~>krig&&z+*#K1`A)YaPuZ+ays~xJs4Wuhw-tK_p<7culR^*s*n;rd z{rj`7HfjvxIcySu-3!5x6p*C6;e9Dp}X%;zrkRzoTi;9 z({?p`2YTpBJf(%VImlqeo)jO^F-L!b+Oz7#q44a#i&@mp0W?&fIWdCM$gt;Af`w{o)QPzfrc$JW982c zp5;OjGe1kycHV{-=TnQo-6(XPnkBRr)^WI-wETFWi}Pv;4eaA=)n0zehIr+dWUq(f ze-RBn>1t~^tU#^ITVRuFaUpQJqP9SyYh^g1ZX#jN?hdkr8@BEFMF4k=O{-3wCArzW z-RSjnTOa9$C~Umw`>wfjz2Y#P+jBqr_<{_b0O!2$=YV~^PLwHRUGu$JPbU~zL0mHA zW8ZK$_&`t2HaFI}(D~Qc%gIP}h=wPzyG#bG7Nbdi!i+(IkdqAMq$c6@jO)hsIDZzh z!<#H`Rfyc!H`=;WmfYQ(jz`EgW^>b=|B388%cTWO4AvXt#^=={3Cm4eP$WVuy zsP1kS8+`0OpFBL!*$cKl21Ybm)1*L3{sIDb9so2s0c&W1Mw8#CVmCpTA67y>-nPp)*(%&89 zXXf5dT?)lAh=tbK>J>1897xsHN{I?qq2`|wIN%hM$N@RWsS*AowC=t@AQhehNO$0J z?w~sVevi664!11WhJ8<`z`B;aeU|Y25B_!unZH9*(?e4wN6}WXidQih`)dq<;55Kk z-6tpw&DX<7jYk1-={s0gB}(MK*o?d%%1+7P*8IL|_ud=%g}uC>lsUO@!kLig4hJkXDh5g`tF~}I_x+1K z_y*NHAor=>N?ZNxnnpeR^D!k*~yVm(=SA%@ZA(<8=e*0iawlB@VCvQ~_a`CQ6Oewv48O zKtS(51s~DfP|9S)$3l`?&c@HO~AMR?Q8yo)LVHWsu-|Br@rsJ zIkv&yl;Wk;p`KKwBy}}!_?d0d+@mCsV@RFxQi9rTjnWGa*|%LfLGA)5u(XaJ?{75< zDh=$sKXas$B=o0eQ%lOOK;ueK-`(>Y`8BrKxrL`9%3iJop%(r8F&H^6AhW0 zQAU;&ScwgM$G*5ZKz|P#D?lYs0cPRnn&bBVjlKZAsKPht7H&CJ`MGhNS(FrZCD{@q zYo(VCA@kjXIqh6Lg-VAbA2K(0!!bf&1xmxMoE3fN0(HyNC;i=fL;xEBwXw9^A*yjv zn59EcQYIQ;Nj44Zqi7F?TZ{J1myylpbfl48hxv0_J|EsioPA^<%+7i=OI98!(5c3C zxpZXxhj@4e&&+ZZgLuv5X+>Kimb*iFDi@t9UXFc4eT5!Oxm2H5?4Jy*HD4n3UPC$S zFn{km^b?9d=FT#DrCdHer=v!#oD&-=!rXH%)&MzNr96_8wpA#0*GRrhrEOHkjPW~s z5tlmov1htBoo7eBz{z2*Bfv-ZZg=SZfmOo%%xw?aWcU~<|EczJy=}Oc-MMk<+BNonvA{wQUk$EHO>4fMQJ}QwX|X=) ziH@IuW2{sX0OD?EL*>9CMJZ5&iKM|QlE8D9r(5ce(JKTAjn(UGrkr&P?L0_sgl3XS zN5=nS<=j%h{|F4Q7HeFIy270C-9pEkvM~ze&f^p(2db1H*td)v8`$9u76DC2O zwcG@ru}YeMdN^63z;>k7OX>MDu7ZlYLS+FLH7&|fE0CWzVkAW-P^?t zpwW9g|L$i(IEG;23zF8}8bk9Kx;qWcrb9k+?!mJjhn_cTvqmBV_T6$v8j(m!-t zOqLB)Rzz1cHSsJ#x`Qh@k7T$J)banht%TQb;5K8vOY$trIRP?4hS57J!xzxZ^t+_| z#i-}*-TyeWDL1L~YBFwx)rWol(#X%njIFIMAPgTK*zv$Ft?rQir{8bh`0zU>Z?%jW z4FVLN#nvghef68q%klbTD>91p6$fc7orVocP zCLX^;G72{uV z)QiuY$6FLE*Ho9XO+AKybatFvfnxukKcMC-s0%K@5CD8rc_e_|`}2p|8KAL`Cj%&^ zGeBZH=9++f2_%Q(FMmcgZ|pB=^p=}*ce-Dd->edio@;(<{`8vXPE@OqNdZ(%Adgy^ z#|#t?SeZbrM&GS4{-abqhK(B(hz@-5(-k+_Wa7%a#3C?mxiv*JIkVnNX!rKHws7ZJ z3XA8CLQox34V6rz>QslzvL5Ze&aM@00Tus%&JqwIej&N}DN1S50PR#AX~~zv;Ib`@ zR(=NWf))1zA_zE4`@ugBeGcS)7p3tECp~JiKK0*kCs5!^Qxf;YnoosEk`cK;!Jgmo zHO~p4^5^@Lz-rBHLtc7}FK5sPYMlu|$$HU@WZ;_cqP)*UK=Zufx8LIhPQ9;)l&A9W zr9!a)LjX!UZ4Xz7J}zV==o|d*NLiYe?|fmYOVm@}Q?0`lS#z_jx1eE}_P?s1x!9+w zetW?DOZ!vu3VYj{wV3i{++lC7vY3O*K6JL^Swb_XK~Z!FoH_T`gqOv8U&u{ts?Ln# zkgJUL30kso7~DWbjJs^M{T%2-zCgJN55h9ivh+S?*zMqjpl95kiE&zI?Nz}{$$F6^ zncCuKplC+VId5#WV0v?Agxg`uhtKkJ>3Casc$WWI9d0QYdNsnsi@oz6V5j@2h|pmM zC$$sq^-=KMk~p_f4$4|hhNJqmCU=+iW3J?5`Fm93fy8^UXm3HGce{sWV3UEl9U$`0 z0nnWp25Ya}$YeC~&*-Wq-^Zr)_)R&p)Ur`tz-t;&YNLiI=9adOOQsZVv@r67!xZfA zqz>vHtF{Dko+2c(z%ESDIbdq-=0A4^X#WH=TV&~JpB|f%CZPT7Sa7^3EwWMP4s#%tC7*`%l;*x~d{QVd>f|}0%=Nii8RVYQ*nJ+jEM9)^ZQM7R`mY9IXoQX@01~Zak8`aRMTFbA!aQ~d@l2{OeWW_02bQ*jH zMq7UB5v}j`Q&EAJSsL666#MOJIS{Kd^!0ul??%gn&xKwIMXsd-VYdUf*(>w6IlpBJ z%TGgR99OoW$r3B%XF4K6h1{JG#6ha#TXD8 zB8Y7{sOD~LG8ZW zW9tx~mIX@Cn;TTC;iq?fa`qeW3^NI#m|qqZ+9KocD?jFM^z&PZHLiCdR@y=^G>WBF zmVtVx1)RoEN`aX2O|BQ0ztvlrx4WAe&$QiR3;S@%u>Gskq{vsvf|{%H#?~UuZyRAV zbfzI#%&E6Da=0tnLfzAH6F;0ud+LE2>xvlV{$ABNcye03$oDvNj@QVi5O`3Y9qW-l z36^;!YDMvoPNj)8{e~)&YRh@x!ZS_X*vj_3t$E;?ozO&{^N@3@3HsMFCM6f&M8235 z?V*({#VTrVs4$s6yrhHN^Rz|M{*X-+9e8u+Z>7Y}kaMN6`)<)&!ex5Qwp_%=Gvk}P z?RamsS)jk>b5l9-pS}FAq?^`6d(MWYt_Q010^jxHC32{b0FYtqC?=boCCH5L8wNxh3` zrb?&UlCX}b#+P4}cJ8@Lr=TM*uDts8k($EF<}Ug==k+j`A{EdAo4aQ44?B;?rr+MS z%^7%(POlvzeK;82Ffj3A@sq3$hrAFhK5I3g@{W!jYl>GRKazM5(|_o9p6;CLo6ny* z(l)`g@({0-S;+dK?M#ZVY%2S;M`~(J{5Lucy1S$O9@8OP(kJh200eJA!7j^A!)y!^ z_LDE{yiW^+|J-oFh*19Ui_fBcNuzQ{u(MO84d!e}dDYt!{6@er?F^;CiPj$MXPwR%B@`dQi2UZ%ko`oJMdH^+YNXDG5(6^ zg73D0_4_9P>Z_~2m-_3-5<60iLE$g(h9wDbG!%Y7f50#8Se?qh=7|j$DzYQw{D`}p z!UMd<;ji9W_@jwHlQ(Jj|)S)>RlD>lio(qkoV?N@~ frjzE5=sB`(=*#jx6a}6&(LB7bbMK3)^{f8_pXUB8 literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/kafka-streams-initializr.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/kafka-streams-initializr.png new file mode 100644 index 0000000000000000000000000000000000000000..3f1014895b2dba40b7cca1c373b8eb41ea2dc94c GIT binary patch literal 121574 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 literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/logo.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ade2ce6ed9d9e9f2f4d9c5729a252ee618a0a5a7 GIT binary patch literal 4387 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 FV1jwin)(0$ literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/warning.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5b5244605adbb7ab05a1549746a9c35490f95b GIT binary patch literal 2130 zcmbVNYg7|w8V(4q($)50y>JmGlLW#g$xLn}Vd2Si)}#|ptPAQp3Bp-3!-lL0;i^LY?;i#f0m5s49g z3h?3rDQg~EDPlm?FKkgKIcWEK-3X6YU0uzs7H|nq84s39r2!5;pF?SI$QqXy^Ko1x zV~zpENvp@<_Bsd`5MabC#3rvCq&$5dg43yGR zAdy0-rWjC#a1N_+kzUMY#pmogD7!DP(9dEKr3c5ngvUq_6>}Y+w-a81v=eSXnIi_+ zI?U>D1q2C!0zHox#XXKH+@|&rPT*OF5yvY$5J|)WwLqnU)c-5;=UChSlQkaY3@^|g z|J5#YBB}=i+n3Ex9bS$P?xJSKLk)-HHII@;3qG#TG^!+aj>0QkO~7kB0+|yM;YrGB zF>Ge@isQ#73%Tp#k_(tInh3U$uJWY-+DND*o}L-CB5g@#9YWWw~pxZ!Obm>yN#ZHFvL0zA3vNCTJ=t?)~`2O1M{L6un=ml<2x zQEYfifmA?Pz0tqRs^2Utt1pU0BQB1eIY0U_I}c1Y#PP7Ci5s7#IJn}xK{G+{_v^Z+1V#$Erodv>d}ew>RP0wzw+GWkGCBlS1Oj5Z!5NK zUuSR6>pa}RSEZ;qE_w1l#`hQX4E67U6NeP zHZ`T&wj0_H)t|Y1thUqnhub?%e)Y07;a^Tq%FO&iQkR&`qG!dh*2WfW(HuRQj*_DI zeCD1bUA|tMwjOb8E|FRIn$pzEU!2j_N}1Z2ig)vbr5xA0rjC70cmI6*%Uf->hWzaZ z{33HABO5q)vRhzDly2l691@+q3O{}NbSzx+I*k@|L4&3leK#$>u+T#TvTELfKb|IH zc23atf3vmfCa0&TWY@iuoA_Pm<0~ttEC*ut`isb^jXS>X^Sp=l?RXN_OJ*&usGXg$ zTlTv;Ch^vhLDf&+62jl64*&D+=+`sN_dap_1W%p|KQVYIdgPL5uRE9(c4On)DXndL zLNq?%!-u*zmMxyYc4m4Nr>>=A=s}PkJkqr&E^b9>5g+}c1%X}3|WKcg&spcJQ)05zI<<5LTBhNKRg$XRTi2{j)yl_ zj4~kKOvr+m(;vw~9zVh(zC-y9jqQnguz5r7FRq^MyKuXAENp(TAzUVtg&Ts+B_s7) zGn+fN0sG>9GjsPLKTRrvCd`71IZulJ1_1jO9KWbD&_@2UC+LTNpxxrdz#E|j|2nA9 zzB!UTyfAEJ&#%$pQ>QX#8vk@_a5iqukMF;8`wRKe{BI}5$H%OROs4J1#j)|?p|YSh z_SpR^e`VE#F52;WL{!+L(yZLRh40*KS;@box;9(-tE)`mcVp27O*>Z{_Lb*5T3cJA yr~0nPHtg2+UHi&&$8ha;`+hiaUmw&!n@8(?5PqF(KE5>Ym)EG)p&uyBP5%a8^# + + + + + + +spring-cloud-stream-binder-kafka + + + + + + + +

+
+
+
+
+

2.1.0.RC2

+
+
+
+
+

Pick The Documentation Option

+
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/highlight.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-multipage.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-singlepage.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/background.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..15dca6fbe2669fae3609605e49c69cc414f1b6ed GIT binary patch literal 18255 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 EKU&lfD*ylh literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/callouts/1.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/callouts/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d473430b7bec514f7de12f5769fe7c5859e8c5d GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}^nQC}X^4DKU-G|w_t}fLBA)Suv#nrW z!^h2QnY_`l!BOq-UXEX{m2up>JTQkX)2m zTvF+fTUlI^nXH#utd~++ke^qgmzgTe~DWM4ffP81J literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/callouts/2.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/callouts/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5d09341b2f6d2ea2d1d5dad5d980f14b4b05dfd2 GIT binary patch literal 353 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 literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/logo.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ade2ce6ed9d9e9f2f4d9c5729a252ee618a0a5a7 GIT binary patch literal 4387 zcmV+;5!~*HP){P%3MJaDx_;_%u2|NZg!>}aqze!Nxc^y8Ao zaMb9>c)3l4zg^w!(u~7spv{7=)Rn#5sM+hyw%MSF!DHa>*1_JcqtAwz$$7Kao2k-{ z$Ktlp=fbSilJ55Bz}~Eo#%^5i?uh^Z5MW6}K~#90-Cc>2qDT-G%qj|s`%n~65K#I5 zADlwl_5$Q6z@8Veu^l@*Ej;tC%&f&?en^rmW8G4Bfs-$nj#hCGIahUzrMVw+I%xQ$E)R)G83X}t`1ui)Ke0b?i}V~=x;*#OP5^AJ z_OVA5<-$S(*dHs3nS@MY=6>c;q3@Q*^@Wc{Iv$8o7%%=lu>Mmu!n-W>7#}U^c;JPI zcIceuet!P2`VsO2g}6x=;JIIdC*&i)%=!Asvn$`C@XK&1|;bH5D_ z=zH7c!N>)KddJ;g59siDEplU|gd&)!`j@>B<Ren; zZ&4m;WDi^gpt1Gv2zv@ph@g01qCEH@j_rY~NI}KjsHjX%MJEA4+|NkF9jCN)QIRhc zFaLQ2c|!z};lxO_~%A+Qex!?*?#BCYPpKKPI zY^8;41BlDH8Ck6C87V0(Eh9w^6@ery;@8d~7@N5%3D&bI&W)5%c0@q##k7>lV_Tmd zdSptXnJFnrN!I{yxMakbDUX|fdg@WJnp;XPU|!EiuDPM4^)e9poGEjf}cm) zQ6T<|r>a)+C6s`;zm+8Q0)h9IA5I2+zPRKWK##xWH90f{l+8s6PUi_;-+}yxY%qW_ zpq+;jDIBj9-3_RCtVLQ8Qlfc6S#9Zl2_?oe1NdkN)R~2omG>pa#E4!j>XLcm?Homv z)0|1pBko@KhMk9$WCm|6Z@xrINc5&Ax^KW7RoSKZ9md31ze)+imI%u9;l1k3P*$se zQB*}|EF)AlQ+s3l9q}umq*6uHfSQl>hxm| zpk$MFHQ|Ize3VlGK<4Y2*By?DAfD8q1chgsqJWf%4u>l#5$sjHAe?MN@FtB=By8>S z{l+gMS0M8kTOy{7HgpDqa)qoeLq8Iyrv*^7Z*ILgv-I>lSDU1yE;shXv=}u0Bm)79 zpZqyHmaO~`DU)SCU_|?m=93u|FsC%Kn)W)5C8=35QKN++ZrT`%n7|YUMOK|G+@yYz zBsTlUk2m2t-|0W}=uS+>_s~eOomO9eNP&(Tp=ivSZj!ZUx>Nu{loG^10u@~^veRv# zmx6;={>X(lfGBI}VRIH%reoDmG+ED&YsLnu8aM$(K>}kY*{WC@uUGg=h+u|R+ppeQ z8xW0SWbtX~n<7Qc(HS71?mA?&;Jqh|!U`bj9XbqsX$b*$gdCZ6vtd|FipbjbhVnr?e>-4~RyzvF<<-Qs^Xc&1 zMG?)OVl#yvh7FZ<%SeB(RSHMUeR^N=4zyT3l&pu{5o$u;~6g>~~oHNaYV8U>0d+O}rOK%P62>-NULqj@}>^cx{|H`VfP%0dmMM*p1WF zX&7F-oZ#fP%2l0M2J7v2y}j5tt-lDZ!(fW)xl~mt!6pa@qT{k(8D&?Dpg3SeTXh;6 zf~))sUYGV!>A5Fl6kB4L;Y5ruG0!VLN%ntyh9Y>!uB?pF4UL3&H(8sVe5^8A((%`i zD&TE8X^@_Brv#AKv}u7iEW65RY1@Y9KX&$iMCPdhIRDn!vkbDmh(BgVGz>E6X3ukb#p2Dx>^YuoxqN> z&w=TuA#hCAbp}GWYhDjUwWLTfU(G?$^s~;HSU;+R{kpFly^j3+BInx<4KBB1x7JYC zq<$);o)bY?S3fKEx%TA&oqlzKyfMhJHsEOBM5vkH=RD7cW|-B?MI_cw{^7Xc1(m9~ zY|dhW*3%mkt3V{KH|x!_zDoEW{pMW71nBgGRd{1G_98WN0`zS#8>d{w#F$=l%EOAr z%><3QQ|3Oe&L`j+o50)eA0I5EhsJJ-CL4Pp#eODK+j12X5>7tPtJ_F0{3hxA#EBq0 z_hMK!&xF{BCJ#;IRAJKJXvA>xffF#F;@O-dBTNdzspmqpEd}QO8>RCjCxVhZ$Qj=7 zR2}p-3O+iPEC&Ddv3l{56Y;_KSR8ur?jWOew%1`587vFmG)reqt>6);xJOkEPixX_ z{l|b+7-b^&p<-59Q+mbk>LvNW)xz2n&o^6%Q5kc+;MAgscwhSWS<|`zCf*UJUuqoa z<7}JNrV&lKxd)Z!9Qg;2$Q}52x!URT=8B-r)87O|Tk=#LvYxcMhJRYjK97YiKRx*c za9yp+cXdp@JVJ%MGumF%FB?1~_+WQq&dK-ySxOAxpFeD-@#iG-6;v%XIA>!=<*f?Urxr1Pj(NRcREqRRHswF zk;j>n(Teu^{w^dPDOsf5TChaEoY0ZZ0HxLA&?f3eiMsB1rnlg`>2#dD*!qoJFO-O# zDCrWg{cyrF-w{wT!XcoZ6_49SkbCa*A$sQp;){qYC;S(1O3w3cji$AzmFPZyvq-oR zB9zXUx8vCzP2=&Mkk|15Nsl{s2rN>b28Gv_ksGXo2Tx7|t-BV%^X`)si!E0pYw*0d zkugG_qAdWw>pV~oF%cFHS5DfTwX}nDVdUvMW>VPMT=ftWp`2Rh#>gcN;X#OonH{0e zOL_oW%w@gelynN~uV8sJ*A8kU8Ggbe>ACN|&Z+?vZRYo$q3wH25x6ZH0y_Z>zGn@q z+emoZVD*LPpV4o0t@IK&<|`Sd%7^EE+hM!+peeAgujC%P7pzCGt(!;Xv%%^faBH_Ny;(iNv1s|C4 z;d>&5#%14t#C1l6)&Gr!&i#K!Jq$4oFjj-|VjfCJn`i+DF_Z1EJu49V8?S zPwDGv&2QHSrR5O5HXg{G@nB7R5}TH^g2M&sd+LD)RJXytSjbGlvUSlLCDnQI^ADq-=ja;k5rFl-Ml_z)VsGybK8TIasZnEcqLXLuyu~zChc% zL%fec%2=ejbK>iOinblMxi=_y`|4Qa38-k_yc%%b?f12SPL~o`>8RHOeg!~?yA8UI zdPCq>pyRk$361H`|12tC<~>R|`r&Ux7=3_f-}_C1MEoyptpet@ckcq;uZ91Q6(ahB zmSI_8^q;YU1bax!&jo6@9(V!xH$g$gmct4GP2JkGq7VKLLV;pn&(9s!GIhyccg;Y= zB;&be0q?i5@bi3XC zN)ZU(_2cjD^OTzYc6Aza?V^lzbs5IC=Zaqs*DUpq28#7tClK{yXb1Wwu?(E7V(JeM8)nOZvWVMX6F08ci!Lcy`N`3 zRmMkqPWG8hB9T1hF%lKAdbyuT9>n{*eLWY6#T%Du@g&n~JQuNGq$r&!4Flu`Bpp*> zh%RqUHzpvFJTmlZEv{9>@llh3hPZWTc7vHflSqO{yBR^VFdRt3()C6mdFU^lWI(SI zk~M4vs4$DM41J8lf+acP)u|5Q7d9H%x_Cd^XHyaDX=#nXqQj zt>&vFvNyJflaQQ&<7Pgco|~IX%Vp9`mUKGA-Zp( zOJtG50yzv2=0Xrx46(Qj83@V53@*$QjdQ#U%j3e3l*8gOAt(xhqztY^3`s$@h$SN! zBqG*0R&KQ7h!Mrc?dl1;Z?K%-#qz}#48ctnwaJt{-T}%C6K=9*n9P7U2?jzG2&y-_ z1)=T&y^dFcS@bqcC$pFgz^e@N_3!Y2&4rmVrc?^b{#WF$vAX{!YjnaHy1PC8t6j!L zL=U>RZ=0Vuyd59RNX(3d7!LK(`xl6rBPrw5(!bs96XC4+vN`n!pkNhnvKs;x&pmV! z^p5t4F5vmbc<*Tg!?VGlB>@XnzNdTWfhvE25$e1Mo;VNrFPPX7U z(3k?AET0>c;EQjdF;|7qmM;id8Z2DH;$?xdi*jLQS;UTmTiQ;84~KpVQTS}!1G7>???1T1M8Y2Y^v{gyWH4>vrEALt zW@fUDlD9Q{=doHaIiz}LsVtu#Tf|>gNSPn)uUj7xxbS*QsNLaH+;@qq1yM5)eX8Xer{FRzM~ z7xK|ff|w#cs13!6!+4oAeiqo&#|^o&-HT^JJ+1KLT73G&i2y$6Z`@c^KzV`9OsHC8!WcLRbRl_HObYx+233S$HvBP zx5xC8NE3$Tk|?#kKW%jS#1E2l4~Dm9y?iNEMtGE`{31iwDR0{;frQ`P~3kjC$lu_eqZs}wAR(baf^>n-dr`hd)oUmm$gnF zbD^_eYPM#zynGxf-a!tS6u8|n_+WHspz~^faii1kX{e03c}{&}W2fu+^!IEjlU-

MvJZJ$)LTqJA+@mbLxmkyPc#tU=W5xPJ%q2sZXv`v(Ui?>!8Tjh_mSOc$O+ zW<-$ZjJfV@LAsB%Biz5w(;fXV?CW1TB9(ujH2(XqZD*&_2O2L-EZJ~mTUSoq*g)q^ zQ!j3qa>DzQ*dH!xN(0O3n$-7HmkYk_eQXG-gI*K|{dncP!DXswNa?P_Z}nzo#*v#J zQ5S9ROsaZ%ZqC6y?VF!Q1^;o|wu*kH=E=`8B``9)uFtN|s?>Xw*7?*`wfqP}<_A~q zd8VVPq*k-7ZPhbSEogsT%F|x0xuT7xdRv7>Rev?4wv{qrDN}+xS$8V5!!ga&#Y1*BgqL?&c}jPc zG_JlfMSD5I%DQQcHXTbGWQtKpeL6yAB|UI5CQ=~#`}=c}Um;E%R)9u^qI0>&GHQ-g zOm;DCkym+{WF$}@UWrV1mtnTPtu!WtY$r7BOpo|N_#mqWGhK#KR0MD7eW*yPaY&xBTRfcG-E5p&`2dq z875XFdy+3GStd(wD_Mg`dys8Xd_houJju_&*4)mZt2Tk1H)DTRJY^_lf>>*ZU2Th5 zWQ3Ly{;kf91GM2s4Vfv8a-fcsXpb+4t> zmM%11X*>M&PQZNVdARf4d*2x!aq1>jOzQ?>>R)(Ok;sOJ)7jfk$Fdif23? z-}3V78&9qod*O;uGk%fEW^;|k`Lo>bOq2iF72o-IGb2gTw+4B~#iYz(oL}sS7|$R2 zDGfrR{|@~AQJ&v(#4u|ZtJP}t520N48P!$8U;|Vfuq=8>E$w`o2Jf`%eqhqbr%IH1zV?O3uDWqKZId-wMQ*MFefpD5X*w@ zok{kNA?%%$F{M!OUcE^^x{~(wkHK|_*9Yg`KNS88FaVH_sda1Xfs6nE002ovPDHLk FV1jwin)(0$ literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/warning.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5b5244605adbb7ab05a1549746a9c35490f95b GIT binary patch literal 2130 zcmbVNYg7|w8V(4q($)50y>JmGlLW#g$xLn}Vd2Si)}#|ptPAQp3Bp-3!-lL0;i^LY?;i#f0m5s49g z3h?3rDQg~EDPlm?FKkgKIcWEK-3X6YU0uzs7H|nq84s39r2!5;pF?SI$QqXy^Ko1x zV~zpENvp@<_Bsd`5MabC#3rvCq&$5dg43yGR zAdy0-rWjC#a1N_+kzUMY#pmogD7!DP(9dEKr3c5ngvUq_6>}Y+w-a81v=eSXnIi_+ zI?U>D1q2C!0zHox#XXKH+@|&rPT*OF5yvY$5J|)WwLqnU)c-5;=UChSlQkaY3@^|g z|J5#YBB}=i+n3Ex9bS$P?xJSKLk)-HHII@;3qG#TG^!+aj>0QkO~7kB0+|yM;YrGB zF>Ge@isQ#73%Tp#k_(tInh3U$uJWY-+DND*o}L-CB5g@#9YWWw~pxZ!Obm>yN#ZHFvL0zA3vNCTJ=t?)~`2O1M{L6un=ml<2x zQEYfifmA?Pz0tqRs^2Utt1pU0BQB1eIY0U_I}c1Y#PP7Ci5s7#IJn}xK{G+{_v^Z+1V#$Erodv>d}ew>RP0wzw+GWkGCBlS1Oj5Z!5NK zUuSR6>pa}RSEZ;qE_w1l#`hQX4E67U6NeP zHZ`T&wj0_H)t|Y1thUqnhub?%e)Y07;a^Tq%FO&iQkR&`qG!dh*2WfW(HuRQj*_DI zeCD1bUA|tMwjOb8E|FRIn$pzEU!2j_N}1Z2ig)vbr5xA0rjC70cmI6*%Uf->hWzaZ z{33HABO5q)vRhzDly2l691@+q3O{}NbSzx+I*k@|L4&3leK#$>u+T#TvTELfKb|IH zc23atf3vmfCa0&TWY@iuoA_Pm<0~ttEC*ut`isb^jXS>X^Sp=l?RXN_OJ*&usGXg$ zTlTv;Ch^vhLDf&+62jl64*&D+=+`sN_dap_1W%p|KQVYIdgPL5uRE9(c4On)DXndL zLNq?%!-u*zmMxyYc4m4Nr>>=A=s}PkJkqr&E^b9>5g+}c1%X}3|WKcg&spcJQ)05zI<<5LTBhNKRg$XRTi2{j)yl_ zj4~kKOvr+m(;vw~9zVh(zC-y9jqQnguz5r7FRq^MyKuXAENp(TAzUVtg&Ts+B_s7) zGn+fN0sG>9GjsPLKTRrvCd`71IZulJ1_1jO9KWbD&_@2UC+LTNpxxrdz#E|j|2nA9 zzB!UTyfAEJ&#%$pQ>QX#8vk@_a5iqukMF;8`wRKe{BI}5$H%OROs4J1#j)|?p|YSh z_SpR^e`VE#F52;WL{!+L(yZLRh40*KS;@box;9(-tE)`mcVp27O*>Z{_Lb*5T3cJA yr~0nPHtg2+UHi&&$8ha;`+hiaUmw&!n@8(?5PqF(KE5>Ym)EG)p&uyBP5%a8^# + + 2. Apache Kafka Binder Overview

2. Apache Kafka Binder Overview

The following image shows a simplified diagram of how the Apache Kafka binder operates:

Figure 2.1. Kafka Binder

kafka binder

The Apache Kafka Binder implementation maps each destination to an Apache Kafka topic. +The consumer group maps directly to the same Apache Kafka concept. +Partitioning also maps directly to Apache Kafka partitions as well.

The binder currently uses the Apache Kafka kafka-clients 1.0.0 jar and is designed to be used with a broker of at least that version. +This client can communicate with older brokers (see the Kafka documentation), but certain features may not be available. +For example, with versions earlier than 0.11.x.x, native headers are not supported. +Also, 0.11.x.x does not support the autoAddPartitions property.

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__appendices.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__appendices.html new file mode 100644 index 00000000..e10a8e2d --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__appendices.html @@ -0,0 +1,3 @@ + + + Part II. Appendices

Part II. Appendices

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__configuration_options.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__configuration_options.html new file mode 100644 index 00000000..46737f4e --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__configuration_options.html @@ -0,0 +1,147 @@ + + + 3. Configuration Options

3. Configuration Options

This section contains the configuration options used by the Apache Kafka binder.

For common configuration options and properties pertaining to binder, see the core documentation.

3.1 Kafka Binder Properties

spring.cloud.stream.kafka.binder.brokers

A list of brokers to which the Kafka binder connects.

Default: localhost.

spring.cloud.stream.kafka.binder.defaultBrokerPort

brokers allows hosts specified with or without port information (for example, host1,host2:port2). +This sets the default port when no port is configured in the broker list.

Default: 9092.

spring.cloud.stream.kafka.binder.configuration

Key/Value map of client properties (both producers and consumer) passed to all clients created by the binder. +Due to the fact that these properties are used by both producers and consumers, usage should be restricted to common properties — for example, security settings. +Unknown Kafka producer or consumer properties provided through this configuration are filtered out and not allowed to propagate. +Properties here supersede any properties set in boot.

Default: Empty map.

spring.cloud.stream.kafka.binder.consumerProperties

Key/Value map of arbitrary Kafka client consumer properties. +In addition to support known Kafka consumer properties, unknown consumer properties are allowed here as well. +Properties here supersede any properties set in boot and in the configuration property above.

Default: Empty map.

spring.cloud.stream.kafka.binder.headers

The list of custom headers that are transported by the binder. +Only required when communicating with older applications (⇐ 1.3.x) with a kafka-clients version < 0.11.0.0. Newer versions support headers natively.

Default: empty.

spring.cloud.stream.kafka.binder.healthTimeout

The time to wait to get partition information, in seconds. +Health reports as down if this timer expires.

Default: 10.

spring.cloud.stream.kafka.binder.requiredAcks

The number of required acks on the broker. +See the Kafka documentation for the producer acks property.

Default: 1.

spring.cloud.stream.kafka.binder.minPartitionCount

Effective only if autoCreateTopics or autoAddPartitions is set. +The global minimum number of partitions that the binder configures on topics on which it produces or consumes data. +It can be superseded by the partitionCount setting of the producer or by the value of instanceCount * concurrency settings of the producer (if either is larger).

Default: 1.

spring.cloud.stream.kafka.binder.producerProperties

Key/Value map of arbitrary Kafka client producer properties. +In addition to support known Kafka producer properties, unknown producer properties are allowed here as well. +Properties here supersede any properties set in boot and in the configuration property above.

Default: Empty map.

spring.cloud.stream.kafka.binder.replicationFactor

The replication factor of auto-created topics if autoCreateTopics is active. +Can be overridden on each binding.

Default: 1.

spring.cloud.stream.kafka.binder.autoCreateTopics

If set to true, the binder creates new topics automatically. +If set to false, the binder relies on the topics being already configured. +In the latter case, if the topics do not exist, the binder fails to start.

[Note]Note

This setting is independent of the auto.topic.create.enable setting of the broker and does not influence it. +If the server is set to auto-create topics, they may be created as part of the metadata retrieval request, with default broker settings.

Default: true.

spring.cloud.stream.kafka.binder.autoAddPartitions

If set to true, the binder creates new partitions if required. +If set to false, the binder relies on the partition size of the topic being already configured. +If the partition count of the target topic is smaller than the expected value, the binder fails to start.

Default: false.

spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix

Enables transactions in the binder. See transaction.id in the Kafka documentation and Transactions in the spring-kafka documentation. +When transactions are enabled, individual producer properties are ignored and all producers use the spring.cloud.stream.kafka.binder.transaction.producer.* properties.

Default null (no transactions)

spring.cloud.stream.kafka.binder.transaction.producer.*

Global producer properties for producers in a transactional binder. +See spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix and Section 3.3, “Kafka Producer Properties” and the general producer properties supported by all binders.

Default: See individual producer properties.

spring.cloud.stream.kafka.binder.headerMapperBeanName

The bean name of a KafkaHeaderMapper used for mapping spring-messaging headers to and from Kafka headers. +Use this, for example, if you wish to customize the trusted packages in a DefaultKafkaHeaderMapper that uses JSON deserialization for the headers.

Default: none.

3.2 Kafka Consumer Properties

The following properties are available for Kafka consumers only and +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.consumer..

admin.configuration

A Map of Kafka topic properties used when provisioning topics — for example, spring.cloud.stream.kafka.bindings.input.consumer.admin.configuration.message.format.version=0.9.0.0

Default: none.

admin.replicas-assignment

A Map<Integer, List<Integer>> of replica assignments, with the key being the partition and the value being the assignments. +Used when provisioning new topics. +See the NewTopic Javadocs in the kafka-clients jar.

Default: none.

admin.replication-factor

The replication factor to use when provisioning topics. Overrides the binder-wide setting. +Ignored if replicas-assignments is present.

Default: none (the binder-wide default of 1 is used).

autoRebalanceEnabled

When true, topic partitions is automatically rebalanced between the members of a consumer group. +When false, each consumer is assigned a fixed set of partitions based on spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex. +This requires both the spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex properties to be set appropriately on each launched instance. +The value of the spring.cloud.stream.instanceCount property must typically be greater than 1 in this case.

Default: true.

ackEachRecord

When autoCommitOffset is true, this setting dictates whether to commit the offset after each record is processed. +By default, offsets are committed after all records in the batch of records returned by consumer.poll() have been processed. +The number of records returned by a poll can be controlled with the max.poll.records Kafka property, which is set through the consumer configuration property. +Setting this to true may cause a degradation in performance, but doing so reduces the likelihood of redelivered records when a failure occurs. +Also, see the binder requiredAcks property, which also affects the performance of committing offsets.

Default: false.

autoCommitOffset

Whether to autocommit offsets when a message has been processed. +If set to false, a header with the key kafka_acknowledgment of the type org.springframework.kafka.support.Acknowledgment header is present in the inbound message. +Applications may use this header for acknowledging messages. +See the examples section for details. +When this property is set to false, Kafka binder sets the ack mode to org.springframework.kafka.listener.AbstractMessageListenerContainer.AckMode.MANUAL and the application is responsible for acknowledging records. +Also see ackEachRecord.

Default: true.

autoCommitOnError

Effective only if autoCommitOffset is set to true. +If set to false, it suppresses auto-commits for messages that result in errors and commits only for successful messages. It allows a stream to automatically replay from the last successfully processed message, in case of persistent failures. +If set to true, it always auto-commits (if auto-commit is enabled). +If not set (the default), it effectively has the same value as enableDlq, auto-committing erroneous messages if they are sent to a DLQ and not committing them otherwise.

Default: not set.

resetOffsets

Whether to reset offsets on the consumer to the value provided by startOffset. +Must be false if a KafkaRebalanceListener is provided; see Chapter 7, Using a KafkaRebalanceListener.

Default: false.

startOffset

The starting offset for new groups. +Allowed values: earliest and latest. +If the consumer group is set explicitly for the consumer 'binding' (through spring.cloud.stream.bindings.<channelName>.group), 'startOffset' is set to earliest. Otherwise, it is set to latest for the anonymous consumer group. +Also see resetOffsets (earlier in this list).

Default: null (equivalent to earliest).

enableDlq

When set to true, it enables DLQ behavior for the consumer. +By default, messages that result in errors are forwarded to a topic named error.<destination>.<group>. +The DLQ topic name can be configurable by setting the dlqName property. +This provides an alternative option to the more common Kafka replay scenario for the case when the number of errors is relatively small and replaying the entire original topic may be too cumbersome. +See Chapter 8, Dead-Letter Topic Processing processing for more information. +Starting with version 2.0, messages sent to the DLQ topic are enhanced with the following headers: x-original-topic, x-exception-message, and x-exception-stacktrace as byte[]. +Not allowed when destinationIsPattern is true.

Default: false.

configuration

Map with a key/value pair containing generic Kafka consumer properties. +In addition to having Kafka consumer properties, other configuration properties can be passed here. +For example some properties needed by the application such as spring.cloud.stream.kafka.bindings.input.consumer.configuration.foo=bar.

Default: Empty map.

dlqName

The name of the DLQ topic to receive the error messages.

Default: null (If not specified, messages that result in errors are forwarded to a topic named error.<destination>.<group>).

dlqProducerProperties

Using this, DLQ-specific producer properties can be set. +All the properties available through kafka producer properties can be set through this property.

Default: Default Kafka producer properties.

standardHeaders

Indicates which standard headers are populated by the inbound channel adapter. +Allowed values: none, id, timestamp, or both. +Useful if using native deserialization and the first component to receive a message needs an id (such as an aggregator that is configured to use a JDBC message store).

Default: none

converterBeanName

The name of a bean that implements RecordMessageConverter. Used in the inbound channel adapter to replace the default MessagingMessageConverter.

Default: null

idleEventInterval

The interval, in milliseconds, between events indicating that no messages have recently been received. +Use an ApplicationListener<ListenerContainerIdleEvent> to receive these events. +See Section 3.4.3, “Example: Pausing and Resuming the Consumer” for a usage example.

Default: 30000

destinationIsPattern

When true, the destination is treated as a regular expression Pattern used to match topic names by the broker. +When true, topics are not provisioned, and enableDlq is not allowed, because the binder does not know the topic names during the provisioning phase. +Note, the time taken to detect new topics that match the pattern is controlled by the consumer property metadata.max.age.ms, which (at the time of writing) defaults to 300,000ms (5 minutes). +This can be configured using the configuration property above.

Default: false

3.3 Kafka Producer Properties

The following properties are available for Kafka producers only and +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.producer..

admin.configuration

A Map of Kafka topic properties used when provisioning new topics — for example, spring.cloud.stream.kafka.bindings.input.consumer.admin.configuration.message.format.version=0.9.0.0

Default: none.

admin.replicas-assignment

A Map<Integer, List<Integer>> of replica assignments, with the key being the partition and the value being the assignments. +Used when provisioning new topics. +See NewTopic javadocs in the kafka-clients jar.

Default: none.

admin.replication-factor

The replication factor to use when provisioning new topics. Overrides the binder-wide setting. +Ignored if replicas-assignments is present.

Default: none (the binder-wide default of 1 is used).

bufferSize

Upper limit, in bytes, of how much data the Kafka producer attempts to batch before sending.

Default: 16384.

sync

Whether the producer is synchronous.

Default: false.

batchTimeout

How long the producer waits to allow more messages to accumulate in the same batch before sending the messages. +(Normally, the producer does not wait at all and simply sends all the messages that accumulated while the previous send was in progress.) A non-zero value may increase throughput at the expense of latency.

Default: 0.

messageKeyExpression

A SpEL expression evaluated against the outgoing message used to populate the key of the produced Kafka message — for example, headers['myKey']. +The payload cannot be used because, by the time this expression is evaluated, the payload is already in the form of a byte[].

Default: none.

headerPatterns

A comma-delimited list of simple patterns to match Spring messaging headers to be mapped to the Kafka Headers in the ProducerRecord. +Patterns can begin or end with the wildcard character (asterisk). +Patterns can be negated by prefixing with !. +Matching stops after the first match (positive or negative). +For example !ask,as* will pass ash but not ask. +id and timestamp are never mapped.

Default: * (all headers - except the id and timestamp)

configuration

Map with a key/value pair containing generic Kafka producer properties.

Default: Empty map.

[Note]Note

The Kafka binder uses the partitionCount setting of the producer as a hint to create a topic with the given partition count (in conjunction with the minPartitionCount, the maximum of the two being the value being used). +Exercise caution when configuring both minPartitionCount for a binder and partitionCount for an application, as the larger value is used. +If a topic already exists with a smaller partition count and autoAddPartitions is disabled (the default), the binder fails to start. +If a topic already exists with a smaller partition count and autoAddPartitions is enabled, new partitions are added. +If a topic already exists with a larger number of partitions than the maximum of (minPartitionCount or partitionCount), the existing partition count is used.

3.4 Usage examples

In this section, we show the use of the preceding properties for specific scenarios.

3.4.1 Example: Setting autoCommitOffset to false and Relying on Manual Acking

This example illustrates how one may manually acknowledge offsets in a consumer application.

This example requires that spring.cloud.stream.kafka.bindings.input.consumer.autoCommitOffset be set to false. +Use the corresponding input channel name for your example.

@SpringBootApplication
+@EnableBinding(Sink.class)
+public class ManuallyAcknowdledgingConsumer {
+
+ public static void main(String[] args) {
+     SpringApplication.run(ManuallyAcknowdledgingConsumer.class, args);
+ }
+
+ @StreamListener(Sink.INPUT)
+ public void process(Message<?> message) {
+     Acknowledgment acknowledgment = message.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class);
+     if (acknowledgment != null) {
+         System.out.println("Acknowledgment provided");
+         acknowledgment.acknowledge();
+     }
+ }
+}

3.4.2 Example: Security Configuration

Apache Kafka 0.9 supports secure connections between client and brokers. +To take advantage of this feature, follow the guidelines in the Apache Kafka Documentation as well as the Kafka 0.9 security guidelines from the Confluent documentation. +Use the spring.cloud.stream.kafka.binder.configuration option to set security properties for all clients created by the binder.

For example, to set security.protocol to SASL_SSL, set the following property:

spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_SSL

All the other security properties can be set in a similar manner.

When using Kerberos, follow the instructions in the reference documentation for creating and referencing the JAAS configuration.

Spring Cloud Stream supports passing JAAS configuration information to the application by using a JAAS configuration file and using Spring Boot properties.

Using JAAS Configuration Files

The JAAS and (optionally) krb5 file locations can be set for Spring Cloud Stream applications by using system properties. +The following example shows how to launch a Spring Cloud Stream application with SASL and Kerberos by using a JAAS configuration file:

 java -Djava.security.auth.login.config=/path.to/kafka_client_jaas.conf -jar log.jar \
+   --spring.cloud.stream.kafka.binder.brokers=secure.server:9092 \
+   --spring.cloud.stream.bindings.input.destination=stream.ticktock \
+   --spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_PLAINTEXT

Using Spring Boot Properties

As an alternative to having a JAAS configuration file, Spring Cloud Stream provides a mechanism for setting up the JAAS configuration for Spring Cloud Stream applications by using Spring Boot properties.

The following properties can be used to configure the login context of the Kafka client:

spring.cloud.stream.kafka.binder.jaas.loginModule

The login module name. Not necessary to be set in normal cases.

Default: com.sun.security.auth.module.Krb5LoginModule.

spring.cloud.stream.kafka.binder.jaas.controlFlag

The control flag of the login module.

Default: required.

spring.cloud.stream.kafka.binder.jaas.options

Map with a key/value pair containing the login module options.

Default: Empty map.

The following example shows how to launch a Spring Cloud Stream application with SASL and Kerberos by using Spring Boot configuration properties:

 java --spring.cloud.stream.kafka.binder.brokers=secure.server:9092 \
+   --spring.cloud.stream.bindings.input.destination=stream.ticktock \
+   --spring.cloud.stream.kafka.binder.autoCreateTopics=false \
+   --spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_PLAINTEXT \
+   --spring.cloud.stream.kafka.binder.jaas.options.useKeyTab=true \
+   --spring.cloud.stream.kafka.binder.jaas.options.storeKey=true \
+   --spring.cloud.stream.kafka.binder.jaas.options.keyTab=/etc/security/keytabs/kafka_client.keytab \
+   --spring.cloud.stream.kafka.binder.jaas.options.principal=kafka-client-1@EXAMPLE.COM

The preceding example represents the equivalent of the following JAAS file:

KafkaClient {
+    com.sun.security.auth.module.Krb5LoginModule required
+    useKeyTab=true
+    storeKey=true
+    keyTab="/etc/security/keytabs/kafka_client.keytab"
+    principal="kafka-client-1@EXAMPLE.COM";
+};

If the topics required already exist on the broker or will be created by an administrator, autocreation can be turned off and only client JAAS properties need to be sent.

[Note]Note

Do not mix JAAS configuration files and Spring Boot properties in the same application. +If the -Djava.security.auth.login.config system property is already present, Spring Cloud Stream ignores the Spring Boot properties.

[Note]Note

Be careful when using the autoCreateTopics and autoAddPartitions with Kerberos. +Usually, applications may use principals that do not have administrative rights in Kafka and Zookeeper. +Consequently, relying on Spring Cloud Stream to create/modify topics may fail. +In secure environments, we strongly recommend creating topics and managing ACLs administratively by using Kafka tooling.

3.4.3 Example: Pausing and Resuming the Consumer

If you wish to suspend consumption but not cause a partition rebalance, you can pause and resume the consumer. +This is facilitated by adding the Consumer as a parameter to your @StreamListener. +To resume, you need an ApplicationListener for ListenerContainerIdleEvent instances. +The frequency at which events are published is controlled by the idleEventInterval property. +Since the consumer is not thread-safe, you must call these methods on the calling thread.

The following simple application shows how to pause and resume:

@SpringBootApplication
+@EnableBinding(Sink.class)
+public class Application {
+
+	public static void main(String[] args) {
+		SpringApplication.run(Application.class, args);
+	}
+
+	@StreamListener(Sink.INPUT)
+	public void in(String in, @Header(KafkaHeaders.CONSUMER) Consumer<?, ?> consumer) {
+		System.out.println(in);
+		consumer.pause(Collections.singleton(new TopicPartition("myTopic", 0)));
+	}
+
+	@Bean
+	public ApplicationListener<ListenerContainerIdleEvent> idleListener() {
+		return event -> {
+			System.out.println(event);
+			if (event.getConsumer().paused().size() > 0) {
+				event.getConsumer().resume(event.getConsumer().paused());
+			}
+		};
+	}
+
+}
\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__partitioning_with_the_kafka_binder.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__partitioning_with_the_kafka_binder.html new file mode 100644 index 00000000..98b1b3dc --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__partitioning_with_the_kafka_binder.html @@ -0,0 +1,72 @@ + + + 9. Partitioning with the Kafka Binder

9. Partitioning with the Kafka Binder

Apache Kafka supports topic partitioning natively.

Sometimes it is advantageous to send data to specific partitions — for example, when you want to strictly order message processing (all messages for a particular customer should go to the same partition).

The following example shows how to configure the producer and consumer side:

@SpringBootApplication
+@EnableBinding(Source.class)
+public class KafkaPartitionProducerApplication {
+
+    private static final Random RANDOM = new Random(System.currentTimeMillis());
+
+    private static final String[] data = new String[] {
+            "foo1", "bar1", "qux1",
+            "foo2", "bar2", "qux2",
+            "foo3", "bar3", "qux3",
+            "foo4", "bar4", "qux4",
+            };
+
+    public static void main(String[] args) {
+        new SpringApplicationBuilder(KafkaPartitionProducerApplication.class)
+            .web(false)
+            .run(args);
+    }
+
+    @InboundChannelAdapter(channel = Source.OUTPUT, poller = @Poller(fixedRate = "5000"))
+    public Message<?> generate() {
+        String value = data[RANDOM.nextInt(data.length)];
+        System.out.println("Sending: " + value);
+        return MessageBuilder.withPayload(value)
+                .setHeader("partitionKey", value)
+                .build();
+    }
+
+}

application.yml.  +

spring:
+  cloud:
+    stream:
+      bindings:
+        output:
+          destination: partitioned.topic
+          producer:
+            partitioned: true
+            partition-key-expression: headers['partitionKey']
+            partition-count: 12

+

[Important]Important

The topic must be provisioned to have enough partitions to achieve the desired concurrency for all consumer groups. +The above configuration supports up to 12 consumer instances (6 if their concurrency is 2, 4 if their concurrency is 3, and so on). +It is generally best to over-provision the partitions to allow for future increases in consumers or concurrency.

[Note]Note

The preceding configuration uses the default partitioning (key.hashCode() % partitionCount). +This may or may not provide a suitably balanced algorithm, depending on the key values. +You can override this default by using the partitionSelectorExpression or partitionSelectorClass properties.

Since partitions are natively handled by Kafka, no special configuration is needed on the consumer side. +Kafka allocates partitions across the instances.

The following Spring Boot application listens to a Kafka stream and prints (to the console) the partition ID to which each message goes:

@SpringBootApplication
+@EnableBinding(Sink.class)
+public class KafkaPartitionConsumerApplication {
+
+    public static void main(String[] args) {
+        new SpringApplicationBuilder(KafkaPartitionConsumerApplication.class)
+            .web(false)
+            .run(args);
+    }
+
+    @StreamListener(Sink.INPUT)
+    public void listen(@Payload String in, @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) {
+        System.out.println(in + " received from partition " + partition);
+    }
+
+}

application.yml.  +

spring:
+  cloud:
+    stream:
+      bindings:
+        input:
+          destination: partitioned.topic
+          group: myGroup

+

You can add instances as needed. +Kafka rebalances the partition allocations. +If the instance count (or instance count * concurrency) exceeds the number of partitions, some consumers are idle.

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__reference_guide.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__reference_guide.html new file mode 100644 index 00000000..df7694cf --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__reference_guide.html @@ -0,0 +1,5 @@ + + + Part I. Reference Guide

Part I. Reference Guide

This guide describes the Apache Kafka implementation of the Spring Cloud Stream Binder. +It contains information about its design, usage, and configuration options, as well as information on how the Stream Cloud Stream concepts map onto Apache Kafka specific constructs. +In addition, this guide explains the Kafka Streams binding capabilities of Spring Cloud Stream.

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__usage.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__usage.html new file mode 100644 index 00000000..ef83295a --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi__usage.html @@ -0,0 +1,9 @@ + + + 1. Usage

1. Usage

To use Apache Kafka binder, you need to add spring-cloud-stream-binder-kafka as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven:

<dependency>
+  <groupId>org.springframework.cloud</groupId>
+  <artifactId>spring-cloud-stream-binder-kafka</artifactId>
+</dependency>

Alternatively, you can also use the Spring Cloud Stream Kafka Starter, as shown inn the following example for Maven:

<dependency>
+  <groupId>org.springframework.cloud</groupId>
+  <artifactId>spring-cloud-starter-stream-kafka</artifactId>
+</dependency>
\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_building.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_building.html new file mode 100644 index 00000000..c7305437 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_building.html @@ -0,0 +1,56 @@ + + + Appendix A. Building

Appendix A. Building

A.1 Basic Compile and Test

To build the source you will need to install JDK 1.7.

The build uses the Maven wrapper so you don’t have to install a specific +version of Maven. To enable the tests, you should have Kafka server 0.9 or above running +before building. See below for more information on running the servers.

The main build command is

$ ./mvnw clean install

You can also add '-DskipTests' if you like, to avoid running the tests.

[Note]Note

You can also install Maven (>=3.3.3) yourself and run the mvn command +in place of ./mvnw in the examples below. If you do that you also +might need to add -P spring if your local Maven settings do not +contain repository declarations for spring pre-release artifacts.

[Note]Note

Be aware that you might need to increase the amount of memory +available to Maven by setting a MAVEN_OPTS environment variable with +a value like -Xmx512m -XX:MaxPermSize=128m. We try to cover this in +the .mvn configuration, so if you find you have to do it to make a +build succeed, please raise a ticket to get the settings added to +source control.

The projects that require middleware generally include a +docker-compose.yml, so consider using +Docker Compose to run the middeware servers +in Docker containers.

A.2 Documentation

There is a "full" profile that will generate documentation.

A.3 Working with the code

If you don’t have an IDE preference we would recommend that you use +Spring Tools Suite or +Eclipse when working with the code. We use the +m2eclipe eclipse plugin for maven support. Other IDEs and tools +should also work without issue.

A.3.1 Importing into eclipse with m2eclipse

We recommend the m2eclipe eclipse plugin when working with +eclipse. If you don’t already have m2eclipse installed it is available from the "eclipse +marketplace".

Unfortunately m2e does not yet support Maven 3.3, so once the projects +are imported into Eclipse you will also need to tell m2eclipse to use +the .settings.xml file for the projects. If you do not do this you +may see many different errors related to the POMs in the +projects. Open your Eclipse preferences, expand the Maven +preferences, and select User Settings. In the User Settings field +click Browse and navigate to the Spring Cloud project you imported +selecting the .settings.xml file in that project. Click Apply and +then OK to save the preference changes.

[Note]Note

Alternatively you can copy the repository settings from .settings.xml into your own ~/.m2/settings.xml.

A.3.2 Importing into eclipse without m2eclipse

If you prefer not to use m2eclipse you can generate eclipse project metadata using the +following command:

$ ./mvnw eclipse:eclipse

The generated eclipse projects can be imported by selecting import existing projects +from the file menu.

[[contributing] +== Contributing

Spring Cloud is released under the non-restrictive Apache 2.0 license, +and follows a very standard Github development process, using Github +tracker for issues and merging pull requests into master. If you want +to contribute even something trivial please do not hesitate, but +follow the guidelines below.

A.4 Sign the Contributor License Agreement

Before we accept a non-trivial patch or pull request we will need you to sign the +contributor’s agreement. +Signing the contributor’s agreement does not grant anyone commit rights to the main +repository, but it does mean that we can accept your contributions, and you will get an +author credit if we do. Active contributors might be asked to join the core team, and +given the ability to merge pull requests.

A.5 Code Conventions and Housekeeping

None of these is essential for a pull request, but they will all help. They can also be +added after the original pull request but before a merge.

  • Use the Spring Framework code format conventions. If you use Eclipse +you can import formatter settings using the +eclipse-code-formatter.xml file from the +Spring +Cloud Build project. If using IntelliJ, you can use the +Eclipse Code Formatter +Plugin to import the same file.
  • Make sure all new .java files to have a simple Javadoc class comment with at least an +@author tag identifying you, and preferably at least a paragraph on what the class is +for.
  • Add the ASF license header comment to all new .java files (copy from existing files +in the project)
  • Add yourself as an @author to the .java files that you modify substantially (more +than cosmetic changes).
  • Add some Javadocs and, if you change the namespace, some XSD doc elements.
  • A few unit tests would help a lot as well — someone has to do it.
  • If no-one else is using your branch, please rebase it against the current master (or +other target branch in the main project).
  • When writing a commit message please follow these conventions, +if you are fixing an existing issue please add Fixes gh-XXXX at the end of the commit +message (where XXXX is the issue number).
\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-dlq-processing.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-dlq-processing.html new file mode 100644 index 00000000..d5b7d7e2 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-dlq-processing.html @@ -0,0 +1,89 @@ + + + 8. Dead-Letter Topic Processing

8. Dead-Letter Topic Processing

Because you cannot anticipate how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. +If the reason for the dead-lettering is transient, you may wish to route the messages back to the original topic. +However, if the problem is a permanent issue, that could cause an infinite loop. +The sample Spring Boot application within this topic is an example of how to route those messages back to the original topic, but it moves them to a parking lot topic after three attempts. +The application is another spring-cloud-stream application that reads from the dead-letter topic. +It terminates when no messages are received for 5 seconds.

The examples assume the original destination is so8400out and the consumer group is so8400.

There are a couple of strategies to consider:

  • Consider running the rerouting only when the main application is not running. +Otherwise, the retries for transient errors are used up very quickly.
  • Alternatively, use a two-stage approach: Use this application to route to a third topic and another to route from there back to the main topic.

The following code listings show the sample application:

application.properties.  +

spring.cloud.stream.bindings.input.group=so8400replay
+spring.cloud.stream.bindings.input.destination=error.so8400out.so8400
+
+spring.cloud.stream.bindings.output.destination=so8400out
+spring.cloud.stream.bindings.output.producer.partitioned=true
+
+spring.cloud.stream.bindings.parkingLot.destination=so8400in.parkingLot
+spring.cloud.stream.bindings.parkingLot.producer.partitioned=true
+
+spring.cloud.stream.kafka.binder.configuration.auto.offset.reset=earliest
+
+spring.cloud.stream.kafka.binder.headers=x-retries

+

Application.  +

@SpringBootApplication
+@EnableBinding(TwoOutputProcessor.class)
+public class ReRouteDlqKApplication implements CommandLineRunner {
+
+    private static final String X_RETRIES_HEADER = "x-retries";
+
+    public static void main(String[] args) {
+        SpringApplication.run(ReRouteDlqKApplication.class, args).close();
+    }
+
+    private final AtomicInteger processed = new AtomicInteger();
+
+    @Autowired
+    private MessageChannel parkingLot;
+
+    @StreamListener(Processor.INPUT)
+    @SendTo(Processor.OUTPUT)
+    public Message<?> reRoute(Message<?> failed) {
+        processed.incrementAndGet();
+        Integer retries = failed.getHeaders().get(X_RETRIES_HEADER, Integer.class);
+        if (retries == null) {
+            System.out.println("First retry for " + failed);
+            return MessageBuilder.fromMessage(failed)
+                    .setHeader(X_RETRIES_HEADER, new Integer(1))
+                    .setHeader(BinderHeaders.PARTITION_OVERRIDE,
+                            failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID))
+                    .build();
+        }
+        else if (retries.intValue() < 3) {
+            System.out.println("Another retry for " + failed);
+            return MessageBuilder.fromMessage(failed)
+                    .setHeader(X_RETRIES_HEADER, new Integer(retries.intValue() + 1))
+                    .setHeader(BinderHeaders.PARTITION_OVERRIDE,
+                            failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID))
+                    .build();
+        }
+        else {
+            System.out.println("Retries exhausted for " + failed);
+            parkingLot.send(MessageBuilder.fromMessage(failed)
+                    .setHeader(BinderHeaders.PARTITION_OVERRIDE,
+                            failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID))
+                    .build());
+        }
+        return null;
+    }
+
+    @Override
+    public void run(String... args) throws Exception {
+        while (true) {
+            int count = this.processed.get();
+            Thread.sleep(5000);
+            if (count == this.processed.get()) {
+                System.out.println("Idle, terminating");
+                return;
+            }
+        }
+    }
+
+    public interface TwoOutputProcessor extends Processor {
+
+        @Output("parkingLot")
+        MessageChannel parkingLot();
+
+    }
+
+}

+

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-error-channels.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-error-channels.html new file mode 100644 index 00000000..560c0b33 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-error-channels.html @@ -0,0 +1,5 @@ + + + 4. Error Channels

4. Error Channels

Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination and can also be configured to send async producer send failures to an error channel. +See ??? for more information.

The payload of the ErrorMessage for a send failure is a KafkaSendFailureException with properties:

  • failedMessage: The Spring Messaging Message<?> that failed to be sent.
  • record: The raw ProducerRecord that was created from the failedMessage

There is no automatic handling of producer exceptions (such as sending to a Dead-Letter queue). +You can consume these exceptions with your own Spring Integration flow.

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-metrics.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-metrics.html new file mode 100644 index 00000000..608b9a64 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-metrics.html @@ -0,0 +1,5 @@ + + + 5. Kafka Metrics

5. Kafka Metrics

Kafka binder module exposes the following metrics:

spring.cloud.stream.binder.kafka.offset: This metric indicates how many messages have not been yet consumed from a given binder’s topic by a given consumer group. +The metrics provided are based on the Mircometer metrics library. The metric contains the consumer group information, topic and the actual lag in committed offset from the latest offset on the topic. +This metric is particularly useful for providing auto-scaling feedback to a PaaS platform.

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-tombstones.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-tombstones.html new file mode 100644 index 00000000..93f9179d --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_kafka-tombstones.html @@ -0,0 +1,9 @@ + + + 6. Tombstone Records (null record values)

6. Tombstone Records (null record values)

When using compacted topics, a record with a null value (also called a tombstone record) represents the deletion of a key. +To receive such messages in a @StreamListener method, the parameter must be marked as not required to receive a null value argument.

@StreamListener(Sink.INPUT)
+public void in(@Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) byte[] key,
+               @Payload(required = false) Customer customer) {
+    // customer is null if a tombstone record
+    ...
+}
\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_rebalance-listener.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_rebalance-listener.html new file mode 100644 index 00000000..c27f0353 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_rebalance-listener.html @@ -0,0 +1,40 @@ + + + 7. Using a KafkaRebalanceListener

7. Using a KafkaRebalanceListener

Applications may wish to seek topics/partitions to arbitrary offsets when the partitions are initially assigned, or perform other operations on the consumer. +Starting with version 2.1, if you provide a single KafkaRebalanceListener bean in the application context, it will be wired into all Kafka consumer bindings.

public interface KafkaBindingRebalanceListener {
+
+	/**
+	 * Invoked by the container before any pending offsets are committed.
+	 * @param bindingName the name of the binding.
+	 * @param consumer the consumer.
+	 * @param partitions the partitions.
+	 */
+	default void onPartitionsRevokedBeforeCommit(String bindingName, Consumer<?, ?> consumer,
+			Collection<TopicPartition> partitions) {
+
+	}
+
+	/**
+	 * Invoked by the container after any pending offsets are committed.
+	 * @param bindingName the name of the binding.
+	 * @param consumer the consumer.
+	 * @param partitions the partitions.
+	 */
+	default void onPartitionsRevokedAfterCommit(String bindingName, Consumer<?, ?> consumer, Collection<TopicPartition> partitions) {
+
+	}
+
+	/**
+	 * Invoked when partitions are initially assigned or after a rebalance.
+	 * Applications might only want to perform seek operations on an initial assignment.
+	 * @param bindingName the name of the binding.
+	 * @param consumer the consumer.
+	 * @param partitions the partitions.
+	 * @param initial true if this is the initial assignment.
+	 */
+	default void onPartitionsAssigned(String bindingName, Consumer<?, ?> consumer, Collection<TopicPartition> partitions,
+			boolean initial) {
+
+	}
+
+}

You cannot set the resetOffsets consumer property to true when you provide a rebalance listener.

\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_spring-cloud-stream-binder-kafka.html b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_spring-cloud-stream-binder-kafka.html new file mode 100644 index 00000000..7764e932 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/multi/multi_spring-cloud-stream-binder-kafka.html @@ -0,0 +1,3 @@ + + + Spring Cloud Stream Kafka Binder Reference Guide \ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/highlight.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-multipage.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-singlepage.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual.css b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/background.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..15dca6fbe2669fae3609605e49c69cc414f1b6ed GIT binary patch literal 18255 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 EKU&lfD*ylh literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/callouts/1.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/callouts/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d473430b7bec514f7de12f5769fe7c5859e8c5d GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}^nQC}X^4DKU-G|w_t}fLBA)Suv#nrW z!^h2QnY_`l!BOq-UXEX{m2up>JTQkX)2m zTvF+fTUlI^nXH#utd~++ke^qgmzgTe~DWM4ffP81J literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/callouts/2.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/callouts/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5d09341b2f6d2ea2d1d5dad5d980f14b4b05dfd2 GIT binary patch literal 353 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 literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/logo.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ade2ce6ed9d9e9f2f4d9c5729a252ee618a0a5a7 GIT binary patch literal 4387 zcmV+;5!~*HP){P%3MJaDx_;_%u2|NZg!>}aqze!Nxc^y8Ao zaMb9>c)3l4zg^w!(u~7spv{7=)Rn#5sM+hyw%MSF!DHa>*1_JcqtAwz$$7Kao2k-{ z$Ktlp=fbSilJ55Bz}~Eo#%^5i?uh^Z5MW6}K~#90-Cc>2qDT-G%qj|s`%n~65K#I5 zADlwl_5$Q6z@8Veu^l@*Ej;tC%&f&?en^rmW8G4Bfs-$nj#hCGIahUzrMVw+I%xQ$E)R)G83X}t`1ui)Ke0b?i}V~=x;*#OP5^AJ z_OVA5<-$S(*dHs3nS@MY=6>c;q3@Q*^@Wc{Iv$8o7%%=lu>Mmu!n-W>7#}U^c;JPI zcIceuet!P2`VsO2g}6x=;JIIdC*&i)%=!Asvn$`C@XK&1|;bH5D_ z=zH7c!N>)KddJ;g59siDEplU|gd&)!`j@>B<Ren; zZ&4m;WDi^gpt1Gv2zv@ph@g01qCEH@j_rY~NI}KjsHjX%MJEA4+|NkF9jCN)QIRhc zFaLQ2c|!z};lxO_~%A+Qex!?*?#BCYPpKKPI zY^8;41BlDH8Ck6C87V0(Eh9w^6@ery;@8d~7@N5%3D&bI&W)5%c0@q##k7>lV_Tmd zdSptXnJFnrN!I{yxMakbDUX|fdg@WJnp;XPU|!EiuDPM4^)e9poGEjf}cm) zQ6T<|r>a)+C6s`;zm+8Q0)h9IA5I2+zPRKWK##xWH90f{l+8s6PUi_;-+}yxY%qW_ zpq+;jDIBj9-3_RCtVLQ8Qlfc6S#9Zl2_?oe1NdkN)R~2omG>pa#E4!j>XLcm?Homv z)0|1pBko@KhMk9$WCm|6Z@xrINc5&Ax^KW7RoSKZ9md31ze)+imI%u9;l1k3P*$se zQB*}|EF)AlQ+s3l9q}umq*6uHfSQl>hxm| zpk$MFHQ|Ize3VlGK<4Y2*By?DAfD8q1chgsqJWf%4u>l#5$sjHAe?MN@FtB=By8>S z{l+gMS0M8kTOy{7HgpDqa)qoeLq8Iyrv*^7Z*ILgv-I>lSDU1yE;shXv=}u0Bm)79 zpZqyHmaO~`DU)SCU_|?m=93u|FsC%Kn)W)5C8=35QKN++ZrT`%n7|YUMOK|G+@yYz zBsTlUk2m2t-|0W}=uS+>_s~eOomO9eNP&(Tp=ivSZj!ZUx>Nu{loG^10u@~^veRv# zmx6;={>X(lfGBI}VRIH%reoDmG+ED&YsLnu8aM$(K>}kY*{WC@uUGg=h+u|R+ppeQ z8xW0SWbtX~n<7Qc(HS71?mA?&;Jqh|!U`bj9XbqsX$b*$gdCZ6vtd|FipbjbhVnr?e>-4~RyzvF<<-Qs^Xc&1 zMG?)OVl#yvh7FZ<%SeB(RSHMUeR^N=4zyT3l&pu{5o$u;~6g>~~oHNaYV8U>0d+O}rOK%P62>-NULqj@}>^cx{|H`VfP%0dmMM*p1WF zX&7F-oZ#fP%2l0M2J7v2y}j5tt-lDZ!(fW)xl~mt!6pa@qT{k(8D&?Dpg3SeTXh;6 zf~))sUYGV!>A5Fl6kB4L;Y5ruG0!VLN%ntyh9Y>!uB?pF4UL3&H(8sVe5^8A((%`i zD&TE8X^@_Brv#AKv}u7iEW65RY1@Y9KX&$iMCPdhIRDn!vkbDmh(BgVGz>E6X3ukb#p2Dx>^YuoxqN> z&w=TuA#hCAbp}GWYhDjUwWLTfU(G?$^s~;HSU;+R{kpFly^j3+BInx<4KBB1x7JYC zq<$);o)bY?S3fKEx%TA&oqlzKyfMhJHsEOBM5vkH=RD7cW|-B?MI_cw{^7Xc1(m9~ zY|dhW*3%mkt3V{KH|x!_zDoEW{pMW71nBgGRd{1G_98WN0`zS#8>d{w#F$=l%EOAr z%><3QQ|3Oe&L`j+o50)eA0I5EhsJJ-CL4Pp#eODK+j12X5>7tPtJ_F0{3hxA#EBq0 z_hMK!&xF{BCJ#;IRAJKJXvA>xffF#F;@O-dBTNdzspmqpEd}QO8>RCjCxVhZ$Qj=7 zR2}p-3O+iPEC&Ddv3l{56Y;_KSR8ur?jWOew%1`587vFmG)reqt>6);xJOkEPixX_ z{l|b+7-b^&p<-59Q+mbk>LvNW)xz2n&o^6%Q5kc+;MAgscwhSWS<|`zCf*UJUuqoa z<7}JNrV&lKxd)Z!9Qg;2$Q}52x!URT=8B-r)87O|Tk=#LvYxcMhJRYjK97YiKRx*c za9yp+cXdp@JVJ%MGumF%FB?1~_+WQq&dK-ySxOAxpFeD-@#iG-6;v%XIA>!=<*f?Urxr1Pj(NRcREqRRHswF zk;j>n(Teu^{w^dPDOsf5TChaEoY0ZZ0HxLA&?f3eiMsB1rnlg`>2#dD*!qoJFO-O# zDCrWg{cyrF-w{wT!XcoZ6_49SkbCa*A$sQp;){qYC;S(1O3w3cji$AzmFPZyvq-oR zB9zXUx8vCzP2=&Mkk|15Nsl{s2rN>b28Gv_ksGXo2Tx7|t-BV%^X`)si!E0pYw*0d zkugG_qAdWw>pV~oF%cFHS5DfTwX}nDVdUvMW>VPMT=ftWp`2Rh#>gcN;X#OonH{0e zOL_oW%w@gelynN~uV8sJ*A8kU8Ggbe>ACN|&Z+?vZRYo$q3wH25x6ZH0y_Z>zGn@q z+emoZVD*LPpV4o0t@IK&<|`Sd%7^EE+hM!+peeAgujC%P7pzCGt(!;Xv%%^faBH_Ny;(iNv1s|C4 z;d>&5#%14t#C1l6)&Gr!&i#K!Jq$4oFjj-|VjfCJn`i+DF_Z1EJu49V8?S zPwDGv&2QHSrR5O5HXg{G@nB7R5}TH^g2M&sd+LD)RJXytSjbGlvUSlLCDnQI^ADq-=ja;k5rFl-Ml_z)VsGybK8TIasZnEcqLXLuyu~zChc% zL%fec%2=ejbK>iOinblMxi=_y`|4Qa38-k_yc%%b?f12SPL~o`>8RHOeg!~?yA8UI zdPCq>pyRk$361H`|12tC<~>R|`r&Ux7=3_f-}_C1MEoyptpet@ckcq;uZ91Q6(ahB zmSI_8^q;YU1bax!&jo6@9(V!xH$g$gmct4GP2JkGq7VKLLV;pn&(9s!GIhyccg;Y= zB;&be0q?i5@bi3XC zN)ZU(_2cjD^OTzYc6Aza?V^lzbs5IC=Zaqs*DUpq28#7tClK{yXb1Wwu?(E7V(JeM8)nOZvWVMX6F08ci!Lcy`N`3 zRmMkqPWG8hB9T1hF%lKAdbyuT9>n{*eLWY6#T%Du@g&n~JQuNGq$r&!4Flu`Bpp*> zh%RqUHzpvFJTmlZEv{9>@llh3hPZWTc7vHflSqO{yBR^VFdRt3()C6mdFU^lWI(SI zk~M4vs4$DM41J8lf+acP)u|5Q7d9H%x_Cd^XHyaDX=#nXqQj zt>&vFvNyJflaQQ&<7Pgco|~IX%Vp9`mUKGA-Zp( zOJtG50yzv2=0Xrx46(Qj83@V53@*$QjdQ#U%j3e3l*8gOAt(xhqztY^3`s$@h$SN! zBqG*0R&KQ7h!Mrc?dl1;Z?K%-#qz}#48ctnwaJt{-T}%C6K=9*n9P7U2?jzG2&y-_ z1)=T&y^dFcS@bqcC$pFgz^e@N_3!Y2&4rmVrc?^b{#WF$vAX{!YjnaHy1PC8t6j!L zL=U>RZ=0Vuyd59RNX(3d7!LK(`xl6rBPrw5(!bs96XC4+vN`n!pkNhnvKs;x&pmV! z^p5t4F5vmbc<*Tg!?VGlB>@XnzNdTWfhvE25$e1Mo;VNrFPPX7U z(3k?AET0>c;EQjdF;|7qmM;id8Z2DH;$?xdi*jLQS;UTmTiQ;84~KpVQTS}!1G7>???1T1M8Y2Y^v{gyWH4>vrEALt zW@fUDlD9Q{=doHaIiz}LsVtu#Tf|>gNSPn)uUj7xxbS*QsNLaH+;@qq1yM5)eX8Xer{FRzM~ z7xK|ff|w#cs13!6!+4oAeiqo&#|^o&-HT^JJ+1KLT73G&i2y$6Z`@c^KzV`9OsHC8!WcLRbRl_HObYx+233S$HvBP zx5xC8NE3$Tk|?#kKW%jS#1E2l4~Dm9y?iNEMtGE`{31iwDR0{;frQ`P~3kjC$lu_eqZs}wAR(baf^>n-dr`hd)oUmm$gnF zbD^_eYPM#zynGxf-a!tS6u8|n_+WHspz~^faii1kX{e03c}{&}W2fu+^!IEjlU-

MvJZJ$)LTqJA+@mbLxmkyPc#tU=W5xPJ%q2sZXv`v(Ui?>!8Tjh_mSOc$O+ zW<-$ZjJfV@LAsB%Biz5w(;fXV?CW1TB9(ujH2(XqZD*&_2O2L-EZJ~mTUSoq*g)q^ zQ!j3qa>DzQ*dH!xN(0O3n$-7HmkYk_eQXG-gI*K|{dncP!DXswNa?P_Z}nzo#*v#J zQ5S9ROsaZ%ZqC6y?VF!Q1^;o|wu*kH=E=`8B``9)uFtN|s?>Xw*7?*`wfqP}<_A~q zd8VVPq*k-7ZPhbSEogsT%F|x0xuT7xdRv7>Rev?4wv{qrDN}+xS$8V5!!ga&#Y1*BgqL?&c}jPc zG_JlfMSD5I%DQQcHXTbGWQtKpeL6yAB|UI5CQ=~#`}=c}Um;E%R)9u^qI0>&GHQ-g zOm;DCkym+{WF$}@UWrV1mtnTPtu!WtY$r7BOpo|N_#mqWGhK#KR0MD7eW*yPaY&xBTRfcG-E5p&`2dq z875XFdy+3GStd(wD_Mg`dys8Xd_houJju_&*4)mZt2Tk1H)DTRJY^_lf>>*ZU2Th5 zWQ3Ly{;kf91GM2s4Vfv8a-fcsXpb+4t> zmM%11X*>M&PQZNVdARf4d*2x!aq1>jOzQ?>>R)(Ok;sOJ)7jfk$Fdif23? z-}3V78&9qod*O;uGk%fEW^;|k`Lo>bOq2iF72o-IGb2gTw+4B~#iYz(oL}sS7|$R2 zDGfrR{|@~AQJ&v(#4u|ZtJP}t520N48P!$8U;|Vfuq=8>E$w`o2Jf`%eqhqbr%IH1zV?O3uDWqKZId-wMQ*MFefpD5X*w@ zok{kNA?%%$F{M!OUcE^^x{~(wkHK|_*9Yg`KNS88FaVH_sda1Xfs6nE002ovPDHLk FV1jwin)(0$ literal 0 HcmV?d00001 diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/warning.png b/spring-cloud-stream-binder-kafka/2.1.0.RC2/single/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5b5244605adbb7ab05a1549746a9c35490f95b GIT binary patch literal 2130 zcmbVNYg7|w8V(4q($)50y>JmGlLW#g$xLn}Vd2Si)}#|ptPAQp3Bp-3!-lL0;i^LY?;i#f0m5s49g z3h?3rDQg~EDPlm?FKkgKIcWEK-3X6YU0uzs7H|nq84s39r2!5;pF?SI$QqXy^Ko1x zV~zpENvp@<_Bsd`5MabC#3rvCq&$5dg43yGR zAdy0-rWjC#a1N_+kzUMY#pmogD7!DP(9dEKr3c5ngvUq_6>}Y+w-a81v=eSXnIi_+ zI?U>D1q2C!0zHox#XXKH+@|&rPT*OF5yvY$5J|)WwLqnU)c-5;=UChSlQkaY3@^|g z|J5#YBB}=i+n3Ex9bS$P?xJSKLk)-HHII@;3qG#TG^!+aj>0QkO~7kB0+|yM;YrGB zF>Ge@isQ#73%Tp#k_(tInh3U$uJWY-+DND*o}L-CB5g@#9YWWw~pxZ!Obm>yN#ZHFvL0zA3vNCTJ=t?)~`2O1M{L6un=ml<2x zQEYfifmA?Pz0tqRs^2Utt1pU0BQB1eIY0U_I}c1Y#PP7Ci5s7#IJn}xK{G+{_v^Z+1V#$Erodv>d}ew>RP0wzw+GWkGCBlS1Oj5Z!5NK zUuSR6>pa}RSEZ;qE_w1l#`hQX4E67U6NeP zHZ`T&wj0_H)t|Y1thUqnhub?%e)Y07;a^Tq%FO&iQkR&`qG!dh*2WfW(HuRQj*_DI zeCD1bUA|tMwjOb8E|FRIn$pzEU!2j_N}1Z2ig)vbr5xA0rjC70cmI6*%Uf->hWzaZ z{33HABO5q)vRhzDly2l691@+q3O{}NbSzx+I*k@|L4&3leK#$>u+T#TvTELfKb|IH zc23atf3vmfCa0&TWY@iuoA_Pm<0~ttEC*ut`isb^jXS>X^Sp=l?RXN_OJ*&usGXg$ zTlTv;Ch^vhLDf&+62jl64*&D+=+`sN_dap_1W%p|KQVYIdgPL5uRE9(c4On)DXndL zLNq?%!-u*zmMxyYc4m4Nr>>=A=s}PkJkqr&E^b9>5g+}c1%X}3|WKcg&spcJQ)05zI<<5LTBhNKRg$XRTi2{j)yl_ zj4~kKOvr+m(;vw~9zVh(zC-y9jqQnguz5r7FRq^MyKuXAENp(TAzUVtg&Ts+B_s7) zGn+fN0sG>9GjsPLKTRrvCd`71IZulJ1_1jO9KWbD&_@2UC+LTNpxxrdz#E|j|2nA9 zzB!UTyfAEJ&#%$pQ>QX#8vk@_a5iqukMF;8`wRKe{BI}5$H%OROs4J1#j)|?p|YSh z_SpR^e`VE#F52;WL{!+L(yZLRh40*KS;@box;9(-tE)`mcVp27O*>Z{_Lb*5T3cJA yr~0nPHtg2+UHi&&$8ha;`+hiaUmw&!n@8(?5PqF(KE5>Ym)EG)p&uyBP5%a8^# + + Spring Cloud Stream Kafka Binder Reference Guide

Spring Cloud Stream Kafka Binder Reference Guide

Sabby Anandan, Marius Bogoevici, Eric Bottard, Mark Fisher, Ilayaperumal Gopinathan, Gunnar Hillert, Mark Pollack, Patrick Peralta, Glenn Renfro, Thomas Risberg, Dave Syer, David Turanski, Janne Valkealahti, Benjamin Klein, Henryk Konsek, Gary Russell

Part I. Reference Guide

This guide describes the Apache Kafka implementation of the Spring Cloud Stream Binder. +It contains information about its design, usage, and configuration options, as well as information on how the Stream Cloud Stream concepts map onto Apache Kafka specific constructs. +In addition, this guide explains the Kafka Streams binding capabilities of Spring Cloud Stream.

1. Usage

To use Apache Kafka binder, you need to add spring-cloud-stream-binder-kafka as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven:

<dependency>
+  <groupId>org.springframework.cloud</groupId>
+  <artifactId>spring-cloud-stream-binder-kafka</artifactId>
+</dependency>

Alternatively, you can also use the Spring Cloud Stream Kafka Starter, as shown inn the following example for Maven:

<dependency>
+  <groupId>org.springframework.cloud</groupId>
+  <artifactId>spring-cloud-starter-stream-kafka</artifactId>
+</dependency>

2. Apache Kafka Binder Overview

The following image shows a simplified diagram of how the Apache Kafka binder operates:

Figure 2.1. Kafka Binder

kafka binder

The Apache Kafka Binder implementation maps each destination to an Apache Kafka topic. +The consumer group maps directly to the same Apache Kafka concept. +Partitioning also maps directly to Apache Kafka partitions as well.

The binder currently uses the Apache Kafka kafka-clients 1.0.0 jar and is designed to be used with a broker of at least that version. +This client can communicate with older brokers (see the Kafka documentation), but certain features may not be available. +For example, with versions earlier than 0.11.x.x, native headers are not supported. +Also, 0.11.x.x does not support the autoAddPartitions property.

3. Configuration Options

This section contains the configuration options used by the Apache Kafka binder.

For common configuration options and properties pertaining to binder, see the core documentation.

3.1 Kafka Binder Properties

spring.cloud.stream.kafka.binder.brokers

A list of brokers to which the Kafka binder connects.

Default: localhost.

spring.cloud.stream.kafka.binder.defaultBrokerPort

brokers allows hosts specified with or without port information (for example, host1,host2:port2). +This sets the default port when no port is configured in the broker list.

Default: 9092.

spring.cloud.stream.kafka.binder.configuration

Key/Value map of client properties (both producers and consumer) passed to all clients created by the binder. +Due to the fact that these properties are used by both producers and consumers, usage should be restricted to common properties — for example, security settings. +Unknown Kafka producer or consumer properties provided through this configuration are filtered out and not allowed to propagate. +Properties here supersede any properties set in boot.

Default: Empty map.

spring.cloud.stream.kafka.binder.consumerProperties

Key/Value map of arbitrary Kafka client consumer properties. +In addition to support known Kafka consumer properties, unknown consumer properties are allowed here as well. +Properties here supersede any properties set in boot and in the configuration property above.

Default: Empty map.

spring.cloud.stream.kafka.binder.headers

The list of custom headers that are transported by the binder. +Only required when communicating with older applications (⇐ 1.3.x) with a kafka-clients version < 0.11.0.0. Newer versions support headers natively.

Default: empty.

spring.cloud.stream.kafka.binder.healthTimeout

The time to wait to get partition information, in seconds. +Health reports as down if this timer expires.

Default: 10.

spring.cloud.stream.kafka.binder.requiredAcks

The number of required acks on the broker. +See the Kafka documentation for the producer acks property.

Default: 1.

spring.cloud.stream.kafka.binder.minPartitionCount

Effective only if autoCreateTopics or autoAddPartitions is set. +The global minimum number of partitions that the binder configures on topics on which it produces or consumes data. +It can be superseded by the partitionCount setting of the producer or by the value of instanceCount * concurrency settings of the producer (if either is larger).

Default: 1.

spring.cloud.stream.kafka.binder.producerProperties

Key/Value map of arbitrary Kafka client producer properties. +In addition to support known Kafka producer properties, unknown producer properties are allowed here as well. +Properties here supersede any properties set in boot and in the configuration property above.

Default: Empty map.

spring.cloud.stream.kafka.binder.replicationFactor

The replication factor of auto-created topics if autoCreateTopics is active. +Can be overridden on each binding.

Default: 1.

spring.cloud.stream.kafka.binder.autoCreateTopics

If set to true, the binder creates new topics automatically. +If set to false, the binder relies on the topics being already configured. +In the latter case, if the topics do not exist, the binder fails to start.

[Note]Note

This setting is independent of the auto.topic.create.enable setting of the broker and does not influence it. +If the server is set to auto-create topics, they may be created as part of the metadata retrieval request, with default broker settings.

Default: true.

spring.cloud.stream.kafka.binder.autoAddPartitions

If set to true, the binder creates new partitions if required. +If set to false, the binder relies on the partition size of the topic being already configured. +If the partition count of the target topic is smaller than the expected value, the binder fails to start.

Default: false.

spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix

Enables transactions in the binder. See transaction.id in the Kafka documentation and Transactions in the spring-kafka documentation. +When transactions are enabled, individual producer properties are ignored and all producers use the spring.cloud.stream.kafka.binder.transaction.producer.* properties.

Default null (no transactions)

spring.cloud.stream.kafka.binder.transaction.producer.*

Global producer properties for producers in a transactional binder. +See spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix and Section 3.3, “Kafka Producer Properties” and the general producer properties supported by all binders.

Default: See individual producer properties.

spring.cloud.stream.kafka.binder.headerMapperBeanName

The bean name of a KafkaHeaderMapper used for mapping spring-messaging headers to and from Kafka headers. +Use this, for example, if you wish to customize the trusted packages in a DefaultKafkaHeaderMapper that uses JSON deserialization for the headers.

Default: none.

3.2 Kafka Consumer Properties

The following properties are available for Kafka consumers only and +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.consumer..

admin.configuration

A Map of Kafka topic properties used when provisioning topics — for example, spring.cloud.stream.kafka.bindings.input.consumer.admin.configuration.message.format.version=0.9.0.0

Default: none.

admin.replicas-assignment

A Map<Integer, List<Integer>> of replica assignments, with the key being the partition and the value being the assignments. +Used when provisioning new topics. +See the NewTopic Javadocs in the kafka-clients jar.

Default: none.

admin.replication-factor

The replication factor to use when provisioning topics. Overrides the binder-wide setting. +Ignored if replicas-assignments is present.

Default: none (the binder-wide default of 1 is used).

autoRebalanceEnabled

When true, topic partitions is automatically rebalanced between the members of a consumer group. +When false, each consumer is assigned a fixed set of partitions based on spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex. +This requires both the spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex properties to be set appropriately on each launched instance. +The value of the spring.cloud.stream.instanceCount property must typically be greater than 1 in this case.

Default: true.

ackEachRecord

When autoCommitOffset is true, this setting dictates whether to commit the offset after each record is processed. +By default, offsets are committed after all records in the batch of records returned by consumer.poll() have been processed. +The number of records returned by a poll can be controlled with the max.poll.records Kafka property, which is set through the consumer configuration property. +Setting this to true may cause a degradation in performance, but doing so reduces the likelihood of redelivered records when a failure occurs. +Also, see the binder requiredAcks property, which also affects the performance of committing offsets.

Default: false.

autoCommitOffset

Whether to autocommit offsets when a message has been processed. +If set to false, a header with the key kafka_acknowledgment of the type org.springframework.kafka.support.Acknowledgment header is present in the inbound message. +Applications may use this header for acknowledging messages. +See the examples section for details. +When this property is set to false, Kafka binder sets the ack mode to org.springframework.kafka.listener.AbstractMessageListenerContainer.AckMode.MANUAL and the application is responsible for acknowledging records. +Also see ackEachRecord.

Default: true.

autoCommitOnError

Effective only if autoCommitOffset is set to true. +If set to false, it suppresses auto-commits for messages that result in errors and commits only for successful messages. It allows a stream to automatically replay from the last successfully processed message, in case of persistent failures. +If set to true, it always auto-commits (if auto-commit is enabled). +If not set (the default), it effectively has the same value as enableDlq, auto-committing erroneous messages if they are sent to a DLQ and not committing them otherwise.

Default: not set.

resetOffsets

Whether to reset offsets on the consumer to the value provided by startOffset. +Must be false if a KafkaRebalanceListener is provided; see Chapter 7, Using a KafkaRebalanceListener.

Default: false.

startOffset

The starting offset for new groups. +Allowed values: earliest and latest. +If the consumer group is set explicitly for the consumer 'binding' (through spring.cloud.stream.bindings.<channelName>.group), 'startOffset' is set to earliest. Otherwise, it is set to latest for the anonymous consumer group. +Also see resetOffsets (earlier in this list).

Default: null (equivalent to earliest).

enableDlq

When set to true, it enables DLQ behavior for the consumer. +By default, messages that result in errors are forwarded to a topic named error.<destination>.<group>. +The DLQ topic name can be configurable by setting the dlqName property. +This provides an alternative option to the more common Kafka replay scenario for the case when the number of errors is relatively small and replaying the entire original topic may be too cumbersome. +See Chapter 8, Dead-Letter Topic Processing processing for more information. +Starting with version 2.0, messages sent to the DLQ topic are enhanced with the following headers: x-original-topic, x-exception-message, and x-exception-stacktrace as byte[]. +Not allowed when destinationIsPattern is true.

Default: false.

configuration

Map with a key/value pair containing generic Kafka consumer properties. +In addition to having Kafka consumer properties, other configuration properties can be passed here. +For example some properties needed by the application such as spring.cloud.stream.kafka.bindings.input.consumer.configuration.foo=bar.

Default: Empty map.

dlqName

The name of the DLQ topic to receive the error messages.

Default: null (If not specified, messages that result in errors are forwarded to a topic named error.<destination>.<group>).

dlqProducerProperties

Using this, DLQ-specific producer properties can be set. +All the properties available through kafka producer properties can be set through this property.

Default: Default Kafka producer properties.

standardHeaders

Indicates which standard headers are populated by the inbound channel adapter. +Allowed values: none, id, timestamp, or both. +Useful if using native deserialization and the first component to receive a message needs an id (such as an aggregator that is configured to use a JDBC message store).

Default: none

converterBeanName

The name of a bean that implements RecordMessageConverter. Used in the inbound channel adapter to replace the default MessagingMessageConverter.

Default: null

idleEventInterval

The interval, in milliseconds, between events indicating that no messages have recently been received. +Use an ApplicationListener<ListenerContainerIdleEvent> to receive these events. +See Section 3.4.3, “Example: Pausing and Resuming the Consumer” for a usage example.

Default: 30000

destinationIsPattern

When true, the destination is treated as a regular expression Pattern used to match topic names by the broker. +When true, topics are not provisioned, and enableDlq is not allowed, because the binder does not know the topic names during the provisioning phase. +Note, the time taken to detect new topics that match the pattern is controlled by the consumer property metadata.max.age.ms, which (at the time of writing) defaults to 300,000ms (5 minutes). +This can be configured using the configuration property above.

Default: false

3.3 Kafka Producer Properties

The following properties are available for Kafka producers only and +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.producer..

admin.configuration

A Map of Kafka topic properties used when provisioning new topics — for example, spring.cloud.stream.kafka.bindings.input.consumer.admin.configuration.message.format.version=0.9.0.0

Default: none.

admin.replicas-assignment

A Map<Integer, List<Integer>> of replica assignments, with the key being the partition and the value being the assignments. +Used when provisioning new topics. +See NewTopic javadocs in the kafka-clients jar.

Default: none.

admin.replication-factor

The replication factor to use when provisioning new topics. Overrides the binder-wide setting. +Ignored if replicas-assignments is present.

Default: none (the binder-wide default of 1 is used).

bufferSize

Upper limit, in bytes, of how much data the Kafka producer attempts to batch before sending.

Default: 16384.

sync

Whether the producer is synchronous.

Default: false.

batchTimeout

How long the producer waits to allow more messages to accumulate in the same batch before sending the messages. +(Normally, the producer does not wait at all and simply sends all the messages that accumulated while the previous send was in progress.) A non-zero value may increase throughput at the expense of latency.

Default: 0.

messageKeyExpression

A SpEL expression evaluated against the outgoing message used to populate the key of the produced Kafka message — for example, headers['myKey']. +The payload cannot be used because, by the time this expression is evaluated, the payload is already in the form of a byte[].

Default: none.

headerPatterns

A comma-delimited list of simple patterns to match Spring messaging headers to be mapped to the Kafka Headers in the ProducerRecord. +Patterns can begin or end with the wildcard character (asterisk). +Patterns can be negated by prefixing with !. +Matching stops after the first match (positive or negative). +For example !ask,as* will pass ash but not ask. +id and timestamp are never mapped.

Default: * (all headers - except the id and timestamp)

configuration

Map with a key/value pair containing generic Kafka producer properties.

Default: Empty map.

[Note]Note

The Kafka binder uses the partitionCount setting of the producer as a hint to create a topic with the given partition count (in conjunction with the minPartitionCount, the maximum of the two being the value being used). +Exercise caution when configuring both minPartitionCount for a binder and partitionCount for an application, as the larger value is used. +If a topic already exists with a smaller partition count and autoAddPartitions is disabled (the default), the binder fails to start. +If a topic already exists with a smaller partition count and autoAddPartitions is enabled, new partitions are added. +If a topic already exists with a larger number of partitions than the maximum of (minPartitionCount or partitionCount), the existing partition count is used.

3.4 Usage examples

In this section, we show the use of the preceding properties for specific scenarios.

3.4.1 Example: Setting autoCommitOffset to false and Relying on Manual Acking

This example illustrates how one may manually acknowledge offsets in a consumer application.

This example requires that spring.cloud.stream.kafka.bindings.input.consumer.autoCommitOffset be set to false. +Use the corresponding input channel name for your example.

@SpringBootApplication
+@EnableBinding(Sink.class)
+public class ManuallyAcknowdledgingConsumer {
+
+ public static void main(String[] args) {
+     SpringApplication.run(ManuallyAcknowdledgingConsumer.class, args);
+ }
+
+ @StreamListener(Sink.INPUT)
+ public void process(Message<?> message) {
+     Acknowledgment acknowledgment = message.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class);
+     if (acknowledgment != null) {
+         System.out.println("Acknowledgment provided");
+         acknowledgment.acknowledge();
+     }
+ }
+}

3.4.2 Example: Security Configuration

Apache Kafka 0.9 supports secure connections between client and brokers. +To take advantage of this feature, follow the guidelines in the Apache Kafka Documentation as well as the Kafka 0.9 security guidelines from the Confluent documentation. +Use the spring.cloud.stream.kafka.binder.configuration option to set security properties for all clients created by the binder.

For example, to set security.protocol to SASL_SSL, set the following property:

spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_SSL

All the other security properties can be set in a similar manner.

When using Kerberos, follow the instructions in the reference documentation for creating and referencing the JAAS configuration.

Spring Cloud Stream supports passing JAAS configuration information to the application by using a JAAS configuration file and using Spring Boot properties.

Using JAAS Configuration Files

The JAAS and (optionally) krb5 file locations can be set for Spring Cloud Stream applications by using system properties. +The following example shows how to launch a Spring Cloud Stream application with SASL and Kerberos by using a JAAS configuration file:

 java -Djava.security.auth.login.config=/path.to/kafka_client_jaas.conf -jar log.jar \
+   --spring.cloud.stream.kafka.binder.brokers=secure.server:9092 \
+   --spring.cloud.stream.bindings.input.destination=stream.ticktock \
+   --spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_PLAINTEXT

Using Spring Boot Properties

As an alternative to having a JAAS configuration file, Spring Cloud Stream provides a mechanism for setting up the JAAS configuration for Spring Cloud Stream applications by using Spring Boot properties.

The following properties can be used to configure the login context of the Kafka client:

spring.cloud.stream.kafka.binder.jaas.loginModule

The login module name. Not necessary to be set in normal cases.

Default: com.sun.security.auth.module.Krb5LoginModule.

spring.cloud.stream.kafka.binder.jaas.controlFlag

The control flag of the login module.

Default: required.

spring.cloud.stream.kafka.binder.jaas.options

Map with a key/value pair containing the login module options.

Default: Empty map.

The following example shows how to launch a Spring Cloud Stream application with SASL and Kerberos by using Spring Boot configuration properties:

 java --spring.cloud.stream.kafka.binder.brokers=secure.server:9092 \
+   --spring.cloud.stream.bindings.input.destination=stream.ticktock \
+   --spring.cloud.stream.kafka.binder.autoCreateTopics=false \
+   --spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_PLAINTEXT \
+   --spring.cloud.stream.kafka.binder.jaas.options.useKeyTab=true \
+   --spring.cloud.stream.kafka.binder.jaas.options.storeKey=true \
+   --spring.cloud.stream.kafka.binder.jaas.options.keyTab=/etc/security/keytabs/kafka_client.keytab \
+   --spring.cloud.stream.kafka.binder.jaas.options.principal=kafka-client-1@EXAMPLE.COM

The preceding example represents the equivalent of the following JAAS file:

KafkaClient {
+    com.sun.security.auth.module.Krb5LoginModule required
+    useKeyTab=true
+    storeKey=true
+    keyTab="/etc/security/keytabs/kafka_client.keytab"
+    principal="kafka-client-1@EXAMPLE.COM";
+};

If the topics required already exist on the broker or will be created by an administrator, autocreation can be turned off and only client JAAS properties need to be sent.

[Note]Note

Do not mix JAAS configuration files and Spring Boot properties in the same application. +If the -Djava.security.auth.login.config system property is already present, Spring Cloud Stream ignores the Spring Boot properties.

[Note]Note

Be careful when using the autoCreateTopics and autoAddPartitions with Kerberos. +Usually, applications may use principals that do not have administrative rights in Kafka and Zookeeper. +Consequently, relying on Spring Cloud Stream to create/modify topics may fail. +In secure environments, we strongly recommend creating topics and managing ACLs administratively by using Kafka tooling.

3.4.3 Example: Pausing and Resuming the Consumer

If you wish to suspend consumption but not cause a partition rebalance, you can pause and resume the consumer. +This is facilitated by adding the Consumer as a parameter to your @StreamListener. +To resume, you need an ApplicationListener for ListenerContainerIdleEvent instances. +The frequency at which events are published is controlled by the idleEventInterval property. +Since the consumer is not thread-safe, you must call these methods on the calling thread.

The following simple application shows how to pause and resume:

@SpringBootApplication
+@EnableBinding(Sink.class)
+public class Application {
+
+	public static void main(String[] args) {
+		SpringApplication.run(Application.class, args);
+	}
+
+	@StreamListener(Sink.INPUT)
+	public void in(String in, @Header(KafkaHeaders.CONSUMER) Consumer<?, ?> consumer) {
+		System.out.println(in);
+		consumer.pause(Collections.singleton(new TopicPartition("myTopic", 0)));
+	}
+
+	@Bean
+	public ApplicationListener<ListenerContainerIdleEvent> idleListener() {
+		return event -> {
+			System.out.println(event);
+			if (event.getConsumer().paused().size() > 0) {
+				event.getConsumer().resume(event.getConsumer().paused());
+			}
+		};
+	}
+
+}

4. Error Channels

Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination and can also be configured to send async producer send failures to an error channel. +See ??? for more information.

The payload of the ErrorMessage for a send failure is a KafkaSendFailureException with properties:

  • failedMessage: The Spring Messaging Message<?> that failed to be sent.
  • record: The raw ProducerRecord that was created from the failedMessage

There is no automatic handling of producer exceptions (such as sending to a Dead-Letter queue). +You can consume these exceptions with your own Spring Integration flow.

5. Kafka Metrics

Kafka binder module exposes the following metrics:

spring.cloud.stream.binder.kafka.offset: This metric indicates how many messages have not been yet consumed from a given binder’s topic by a given consumer group. +The metrics provided are based on the Mircometer metrics library. The metric contains the consumer group information, topic and the actual lag in committed offset from the latest offset on the topic. +This metric is particularly useful for providing auto-scaling feedback to a PaaS platform.

6. Tombstone Records (null record values)

When using compacted topics, a record with a null value (also called a tombstone record) represents the deletion of a key. +To receive such messages in a @StreamListener method, the parameter must be marked as not required to receive a null value argument.

@StreamListener(Sink.INPUT)
+public void in(@Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) byte[] key,
+               @Payload(required = false) Customer customer) {
+    // customer is null if a tombstone record
+    ...
+}

7. Using a KafkaRebalanceListener

Applications may wish to seek topics/partitions to arbitrary offsets when the partitions are initially assigned, or perform other operations on the consumer. +Starting with version 2.1, if you provide a single KafkaRebalanceListener bean in the application context, it will be wired into all Kafka consumer bindings.

public interface KafkaBindingRebalanceListener {
+
+	/**
+	 * Invoked by the container before any pending offsets are committed.
+	 * @param bindingName the name of the binding.
+	 * @param consumer the consumer.
+	 * @param partitions the partitions.
+	 */
+	default void onPartitionsRevokedBeforeCommit(String bindingName, Consumer<?, ?> consumer,
+			Collection<TopicPartition> partitions) {
+
+	}
+
+	/**
+	 * Invoked by the container after any pending offsets are committed.
+	 * @param bindingName the name of the binding.
+	 * @param consumer the consumer.
+	 * @param partitions the partitions.
+	 */
+	default void onPartitionsRevokedAfterCommit(String bindingName, Consumer<?, ?> consumer, Collection<TopicPartition> partitions) {
+
+	}
+
+	/**
+	 * Invoked when partitions are initially assigned or after a rebalance.
+	 * Applications might only want to perform seek operations on an initial assignment.
+	 * @param bindingName the name of the binding.
+	 * @param consumer the consumer.
+	 * @param partitions the partitions.
+	 * @param initial true if this is the initial assignment.
+	 */
+	default void onPartitionsAssigned(String bindingName, Consumer<?, ?> consumer, Collection<TopicPartition> partitions,
+			boolean initial) {
+
+	}
+
+}

You cannot set the resetOffsets consumer property to true when you provide a rebalance listener.

8. Dead-Letter Topic Processing

Because you cannot anticipate how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. +If the reason for the dead-lettering is transient, you may wish to route the messages back to the original topic. +However, if the problem is a permanent issue, that could cause an infinite loop. +The sample Spring Boot application within this topic is an example of how to route those messages back to the original topic, but it moves them to a parking lot topic after three attempts. +The application is another spring-cloud-stream application that reads from the dead-letter topic. +It terminates when no messages are received for 5 seconds.

The examples assume the original destination is so8400out and the consumer group is so8400.

There are a couple of strategies to consider:

  • Consider running the rerouting only when the main application is not running. +Otherwise, the retries for transient errors are used up very quickly.
  • Alternatively, use a two-stage approach: Use this application to route to a third topic and another to route from there back to the main topic.

The following code listings show the sample application:

application.properties.  +

spring.cloud.stream.bindings.input.group=so8400replay
+spring.cloud.stream.bindings.input.destination=error.so8400out.so8400
+
+spring.cloud.stream.bindings.output.destination=so8400out
+spring.cloud.stream.bindings.output.producer.partitioned=true
+
+spring.cloud.stream.bindings.parkingLot.destination=so8400in.parkingLot
+spring.cloud.stream.bindings.parkingLot.producer.partitioned=true
+
+spring.cloud.stream.kafka.binder.configuration.auto.offset.reset=earliest
+
+spring.cloud.stream.kafka.binder.headers=x-retries

+

Application.  +

@SpringBootApplication
+@EnableBinding(TwoOutputProcessor.class)
+public class ReRouteDlqKApplication implements CommandLineRunner {
+
+    private static final String X_RETRIES_HEADER = "x-retries";
+
+    public static void main(String[] args) {
+        SpringApplication.run(ReRouteDlqKApplication.class, args).close();
+    }
+
+    private final AtomicInteger processed = new AtomicInteger();
+
+    @Autowired
+    private MessageChannel parkingLot;
+
+    @StreamListener(Processor.INPUT)
+    @SendTo(Processor.OUTPUT)
+    public Message<?> reRoute(Message<?> failed) {
+        processed.incrementAndGet();
+        Integer retries = failed.getHeaders().get(X_RETRIES_HEADER, Integer.class);
+        if (retries == null) {
+            System.out.println("First retry for " + failed);
+            return MessageBuilder.fromMessage(failed)
+                    .setHeader(X_RETRIES_HEADER, new Integer(1))
+                    .setHeader(BinderHeaders.PARTITION_OVERRIDE,
+                            failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID))
+                    .build();
+        }
+        else if (retries.intValue() < 3) {
+            System.out.println("Another retry for " + failed);
+            return MessageBuilder.fromMessage(failed)
+                    .setHeader(X_RETRIES_HEADER, new Integer(retries.intValue() + 1))
+                    .setHeader(BinderHeaders.PARTITION_OVERRIDE,
+                            failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID))
+                    .build();
+        }
+        else {
+            System.out.println("Retries exhausted for " + failed);
+            parkingLot.send(MessageBuilder.fromMessage(failed)
+                    .setHeader(BinderHeaders.PARTITION_OVERRIDE,
+                            failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID))
+                    .build());
+        }
+        return null;
+    }
+
+    @Override
+    public void run(String... args) throws Exception {
+        while (true) {
+            int count = this.processed.get();
+            Thread.sleep(5000);
+            if (count == this.processed.get()) {
+                System.out.println("Idle, terminating");
+                return;
+            }
+        }
+    }
+
+    public interface TwoOutputProcessor extends Processor {
+
+        @Output("parkingLot")
+        MessageChannel parkingLot();
+
+    }
+
+}

+

9. Partitioning with the Kafka Binder

Apache Kafka supports topic partitioning natively.

Sometimes it is advantageous to send data to specific partitions — for example, when you want to strictly order message processing (all messages for a particular customer should go to the same partition).

The following example shows how to configure the producer and consumer side:

@SpringBootApplication
+@EnableBinding(Source.class)
+public class KafkaPartitionProducerApplication {
+
+    private static final Random RANDOM = new Random(System.currentTimeMillis());
+
+    private static final String[] data = new String[] {
+            "foo1", "bar1", "qux1",
+            "foo2", "bar2", "qux2",
+            "foo3", "bar3", "qux3",
+            "foo4", "bar4", "qux4",
+            };
+
+    public static void main(String[] args) {
+        new SpringApplicationBuilder(KafkaPartitionProducerApplication.class)
+            .web(false)
+            .run(args);
+    }
+
+    @InboundChannelAdapter(channel = Source.OUTPUT, poller = @Poller(fixedRate = "5000"))
+    public Message<?> generate() {
+        String value = data[RANDOM.nextInt(data.length)];
+        System.out.println("Sending: " + value);
+        return MessageBuilder.withPayload(value)
+                .setHeader("partitionKey", value)
+                .build();
+    }
+
+}

application.yml.  +

spring:
+  cloud:
+    stream:
+      bindings:
+        output:
+          destination: partitioned.topic
+          producer:
+            partitioned: true
+            partition-key-expression: headers['partitionKey']
+            partition-count: 12

+

[Important]Important

The topic must be provisioned to have enough partitions to achieve the desired concurrency for all consumer groups. +The above configuration supports up to 12 consumer instances (6 if their concurrency is 2, 4 if their concurrency is 3, and so on). +It is generally best to over-provision the partitions to allow for future increases in consumers or concurrency.

[Note]Note

The preceding configuration uses the default partitioning (key.hashCode() % partitionCount). +This may or may not provide a suitably balanced algorithm, depending on the key values. +You can override this default by using the partitionSelectorExpression or partitionSelectorClass properties.

Since partitions are natively handled by Kafka, no special configuration is needed on the consumer side. +Kafka allocates partitions across the instances.

The following Spring Boot application listens to a Kafka stream and prints (to the console) the partition ID to which each message goes:

@SpringBootApplication
+@EnableBinding(Sink.class)
+public class KafkaPartitionConsumerApplication {
+
+    public static void main(String[] args) {
+        new SpringApplicationBuilder(KafkaPartitionConsumerApplication.class)
+            .web(false)
+            .run(args);
+    }
+
+    @StreamListener(Sink.INPUT)
+    public void listen(@Payload String in, @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) {
+        System.out.println(in + " received from partition " + partition);
+    }
+
+}

application.yml.  +

spring:
+  cloud:
+    stream:
+      bindings:
+        input:
+          destination: partitioned.topic
+          group: myGroup

+

You can add instances as needed. +Kafka rebalances the partition allocations. +If the instance count (or instance count * concurrency) exceeds the number of partitions, some consumers are idle.

Part II. Appendices

Appendix A. Building

A.1 Basic Compile and Test

To build the source you will need to install JDK 1.7.

The build uses the Maven wrapper so you don’t have to install a specific +version of Maven. To enable the tests, you should have Kafka server 0.9 or above running +before building. See below for more information on running the servers.

The main build command is

$ ./mvnw clean install

You can also add '-DskipTests' if you like, to avoid running the tests.

[Note]Note

You can also install Maven (>=3.3.3) yourself and run the mvn command +in place of ./mvnw in the examples below. If you do that you also +might need to add -P spring if your local Maven settings do not +contain repository declarations for spring pre-release artifacts.

[Note]Note

Be aware that you might need to increase the amount of memory +available to Maven by setting a MAVEN_OPTS environment variable with +a value like -Xmx512m -XX:MaxPermSize=128m. We try to cover this in +the .mvn configuration, so if you find you have to do it to make a +build succeed, please raise a ticket to get the settings added to +source control.

The projects that require middleware generally include a +docker-compose.yml, so consider using +Docker Compose to run the middeware servers +in Docker containers.

A.2 Documentation

There is a "full" profile that will generate documentation.

A.3 Working with the code

If you don’t have an IDE preference we would recommend that you use +Spring Tools Suite or +Eclipse when working with the code. We use the +m2eclipe eclipse plugin for maven support. Other IDEs and tools +should also work without issue.

A.3.1 Importing into eclipse with m2eclipse

We recommend the m2eclipe eclipse plugin when working with +eclipse. If you don’t already have m2eclipse installed it is available from the "eclipse +marketplace".

Unfortunately m2e does not yet support Maven 3.3, so once the projects +are imported into Eclipse you will also need to tell m2eclipse to use +the .settings.xml file for the projects. If you do not do this you +may see many different errors related to the POMs in the +projects. Open your Eclipse preferences, expand the Maven +preferences, and select User Settings. In the User Settings field +click Browse and navigate to the Spring Cloud project you imported +selecting the .settings.xml file in that project. Click Apply and +then OK to save the preference changes.

[Note]Note

Alternatively you can copy the repository settings from .settings.xml into your own ~/.m2/settings.xml.

A.3.2 Importing into eclipse without m2eclipse

If you prefer not to use m2eclipse you can generate eclipse project metadata using the +following command:

$ ./mvnw eclipse:eclipse

The generated eclipse projects can be imported by selecting import existing projects +from the file menu.

[[contributing] +== Contributing

Spring Cloud is released under the non-restrictive Apache 2.0 license, +and follows a very standard Github development process, using Github +tracker for issues and merging pull requests into master. If you want +to contribute even something trivial please do not hesitate, but +follow the guidelines below.

A.4 Sign the Contributor License Agreement

Before we accept a non-trivial patch or pull request we will need you to sign the +contributor’s agreement. +Signing the contributor’s agreement does not grant anyone commit rights to the main +repository, but it does mean that we can accept your contributions, and you will get an +author credit if we do. Active contributors might be asked to join the core team, and +given the ability to merge pull requests.

A.5 Code Conventions and Housekeeping

None of these is essential for a pull request, but they will all help. They can also be +added after the original pull request but before a merge.

  • Use the Spring Framework code format conventions. If you use Eclipse +you can import formatter settings using the +eclipse-code-formatter.xml file from the +Spring +Cloud Build project. If using IntelliJ, you can use the +Eclipse Code Formatter +Plugin to import the same file.
  • Make sure all new .java files to have a simple Javadoc class comment with at least an +@author tag identifying you, and preferably at least a paragraph on what the class is +for.
  • Add the ASF license header comment to all new .java files (copy from existing files +in the project)
  • Add yourself as an @author to the .java files that you modify substantially (more +than cosmetic changes).
  • Add some Javadocs and, if you change the namespace, some XSD doc elements.
  • A few unit tests would help a lot as well — someone has to do it.
  • If no-one else is using your branch, please rebase it against the current master (or +other target branch in the main project).
  • When writing a commit message please follow these conventions, +if you are fixing an existing issue please add Fixes gh-XXXX at the end of the commit +message (where XXXX is the issue number).
\ No newline at end of file diff --git a/spring-cloud-stream-binder-kafka/2.1.0.RC2/spring-cloud-stream-binder-kafka.xml b/spring-cloud-stream-binder-kafka/2.1.0.RC2/spring-cloud-stream-binder-kafka.xml new file mode 100644 index 00000000..6afb1383 --- /dev/null +++ b/spring-cloud-stream-binder-kafka/2.1.0.RC2/spring-cloud-stream-binder-kafka.xml @@ -0,0 +1,1000 @@ + + + + + +Spring Cloud Stream Kafka Binder Reference Guide +2018-11-19 + + +Sabby Anandan, Marius Bogoevici, Eric Bottard, Mark Fisher, Ilayaperumal Gopinathan, Gunnar Hillert, Mark Pollack, Patrick Peralta, Glenn Renfro, Thomas Risberg, Dave Syer, David Turanski, Janne Valkealahti, Benjamin Klein, Henryk Konsek, Gary Russell + + +S + + +Reference Guide + +This guide describes the Apache Kafka implementation of the Spring Cloud Stream Binder. +It contains information about its design, usage, and configuration options, as well as information on how the Stream Cloud Stream concepts map onto Apache Kafka specific constructs. +In addition, this guide explains the Kafka Streams binding capabilities of Spring Cloud Stream. + + +Usage +To use Apache Kafka binder, you need to add spring-cloud-stream-binder-kafka as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven: +<dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-stream-binder-kafka</artifactId> +</dependency> +Alternatively, you can also use the Spring Cloud Stream Kafka Starter, as shown inn the following example for Maven: +<dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-starter-stream-kafka</artifactId> +</dependency> + + +Apache Kafka Binder Overview +The following image shows a simplified diagram of how the Apache Kafka binder operates: +
+Kafka Binder + + + + +kafka binder + +
+The Apache Kafka Binder implementation maps each destination to an Apache Kafka topic. +The consumer group maps directly to the same Apache Kafka concept. +Partitioning also maps directly to Apache Kafka partitions as well. +The binder currently uses the Apache Kafka kafka-clients 1.0.0 jar and is designed to be used with a broker of at least that version. +This client can communicate with older brokers (see the Kafka documentation), but certain features may not be available. +For example, with versions earlier than 0.11.x.x, native headers are not supported. +Also, 0.11.x.x does not support the autoAddPartitions property. +
+ +Configuration Options +This section contains the configuration options used by the Apache Kafka binder. +For common configuration options and properties pertaining to binder, see the core documentation. +
+Kafka Binder Properties + + +spring.cloud.stream.kafka.binder.brokers + +A list of brokers to which the Kafka binder connects. +Default: localhost. + + + +spring.cloud.stream.kafka.binder.defaultBrokerPort + +brokers allows hosts specified with or without port information (for example, host1,host2:port2). +This sets the default port when no port is configured in the broker list. +Default: 9092. + + + +spring.cloud.stream.kafka.binder.configuration + +Key/Value map of client properties (both producers and consumer) passed to all clients created by the binder. +Due to the fact that these properties are used by both producers and consumers, usage should be restricted to common properties — for example, security settings. +Unknown Kafka producer or consumer properties provided through this configuration are filtered out and not allowed to propagate. +Properties here supersede any properties set in boot. +Default: Empty map. + + + +spring.cloud.stream.kafka.binder.consumerProperties + +Key/Value map of arbitrary Kafka client consumer properties. +In addition to support known Kafka consumer properties, unknown consumer properties are allowed here as well. +Properties here supersede any properties set in boot and in the configuration property above. +Default: Empty map. + + + +spring.cloud.stream.kafka.binder.headers + +The list of custom headers that are transported by the binder. +Only required when communicating with older applications (⇐ 1.3.x) with a kafka-clients version < 0.11.0.0. Newer versions support headers natively. +Default: empty. + + + +spring.cloud.stream.kafka.binder.healthTimeout + +The time to wait to get partition information, in seconds. +Health reports as down if this timer expires. +Default: 10. + + + +spring.cloud.stream.kafka.binder.requiredAcks + +The number of required acks on the broker. +See the Kafka documentation for the producer acks property. +Default: 1. + + + +spring.cloud.stream.kafka.binder.minPartitionCount + +Effective only if autoCreateTopics or autoAddPartitions is set. +The global minimum number of partitions that the binder configures on topics on which it produces or consumes data. +It can be superseded by the partitionCount setting of the producer or by the value of instanceCount * concurrency settings of the producer (if either is larger). +Default: 1. + + + +spring.cloud.stream.kafka.binder.producerProperties + +Key/Value map of arbitrary Kafka client producer properties. +In addition to support known Kafka producer properties, unknown producer properties are allowed here as well. +Properties here supersede any properties set in boot and in the configuration property above. +Default: Empty map. + + + +spring.cloud.stream.kafka.binder.replicationFactor + +The replication factor of auto-created topics if autoCreateTopics is active. +Can be overridden on each binding. +Default: 1. + + + +spring.cloud.stream.kafka.binder.autoCreateTopics + +If set to true, the binder creates new topics automatically. +If set to false, the binder relies on the topics being already configured. +In the latter case, if the topics do not exist, the binder fails to start. + +This setting is independent of the auto.topic.create.enable setting of the broker and does not influence it. +If the server is set to auto-create topics, they may be created as part of the metadata retrieval request, with default broker settings. + +Default: true. + + + +spring.cloud.stream.kafka.binder.autoAddPartitions + +If set to true, the binder creates new partitions if required. +If set to false, the binder relies on the partition size of the topic being already configured. +If the partition count of the target topic is smaller than the expected value, the binder fails to start. +Default: false. + + + +spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix + +Enables transactions in the binder. See transaction.id in the Kafka documentation and Transactions in the spring-kafka documentation. +When transactions are enabled, individual producer properties are ignored and all producers use the spring.cloud.stream.kafka.binder.transaction.producer.* properties. +Default null (no transactions) + + + +spring.cloud.stream.kafka.binder.transaction.producer.* + +Global producer properties for producers in a transactional binder. +See spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix and and the general producer properties supported by all binders. +Default: See individual producer properties. + + + +spring.cloud.stream.kafka.binder.headerMapperBeanName + +The bean name of a KafkaHeaderMapper used for mapping spring-messaging headers to and from Kafka headers. +Use this, for example, if you wish to customize the trusted packages in a DefaultKafkaHeaderMapper that uses JSON deserialization for the headers. +Default: none. + + + +
+
+Kafka Consumer Properties +The following properties are available for Kafka consumers only and +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.consumer.. + + +admin.configuration + +A Map of Kafka topic properties used when provisioning topics — for example, spring.cloud.stream.kafka.bindings.input.consumer.admin.configuration.message.format.version=0.9.0.0 +Default: none. + + + +admin.replicas-assignment + +A Map<Integer, List<Integer>> of replica assignments, with the key being the partition and the value being the assignments. +Used when provisioning new topics. +See the NewTopic Javadocs in the kafka-clients jar. +Default: none. + + + +admin.replication-factor + +The replication factor to use when provisioning topics. Overrides the binder-wide setting. +Ignored if replicas-assignments is present. +Default: none (the binder-wide default of 1 is used). + + + +autoRebalanceEnabled + +When true, topic partitions is automatically rebalanced between the members of a consumer group. +When false, each consumer is assigned a fixed set of partitions based on spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex. +This requires both the spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex properties to be set appropriately on each launched instance. +The value of the spring.cloud.stream.instanceCount property must typically be greater than 1 in this case. +Default: true. + + + +ackEachRecord + +When autoCommitOffset is true, this setting dictates whether to commit the offset after each record is processed. +By default, offsets are committed after all records in the batch of records returned by consumer.poll() have been processed. +The number of records returned by a poll can be controlled with the max.poll.records Kafka property, which is set through the consumer configuration property. +Setting this to true may cause a degradation in performance, but doing so reduces the likelihood of redelivered records when a failure occurs. +Also, see the binder requiredAcks property, which also affects the performance of committing offsets. +Default: false. + + + +autoCommitOffset + +Whether to autocommit offsets when a message has been processed. +If set to false, a header with the key kafka_acknowledgment of the type org.springframework.kafka.support.Acknowledgment header is present in the inbound message. +Applications may use this header for acknowledging messages. +See the examples section for details. +When this property is set to false, Kafka binder sets the ack mode to org.springframework.kafka.listener.AbstractMessageListenerContainer.AckMode.MANUAL and the application is responsible for acknowledging records. +Also see ackEachRecord. +Default: true. + + + +autoCommitOnError + +Effective only if autoCommitOffset is set to true. +If set to false, it suppresses auto-commits for messages that result in errors and commits only for successful messages. It allows a stream to automatically replay from the last successfully processed message, in case of persistent failures. +If set to true, it always auto-commits (if auto-commit is enabled). +If not set (the default), it effectively has the same value as enableDlq, auto-committing erroneous messages if they are sent to a DLQ and not committing them otherwise. +Default: not set. + + + +resetOffsets + +Whether to reset offsets on the consumer to the value provided by startOffset. +Must be false if a KafkaRebalanceListener is provided; see . +Default: false. + + + +startOffset + +The starting offset for new groups. +Allowed values: earliest and latest. +If the consumer group is set explicitly for the consumer 'binding' (through spring.cloud.stream.bindings.<channelName>.group), 'startOffset' is set to earliest. Otherwise, it is set to latest for the anonymous consumer group. +Also see resetOffsets (earlier in this list). +Default: null (equivalent to earliest). + + + +enableDlq + +When set to true, it enables DLQ behavior for the consumer. +By default, messages that result in errors are forwarded to a topic named error.<destination>.<group>. +The DLQ topic name can be configurable by setting the dlqName property. +This provides an alternative option to the more common Kafka replay scenario for the case when the number of errors is relatively small and replaying the entire original topic may be too cumbersome. +See processing for more information. +Starting with version 2.0, messages sent to the DLQ topic are enhanced with the following headers: x-original-topic, x-exception-message, and x-exception-stacktrace as byte[]. +Not allowed when destinationIsPattern is true. +Default: false. + + + +configuration + +Map with a key/value pair containing generic Kafka consumer properties. +In addition to having Kafka consumer properties, other configuration properties can be passed here. +For example some properties needed by the application such as spring.cloud.stream.kafka.bindings.input.consumer.configuration.foo=bar. +Default: Empty map. + + + +dlqName + +The name of the DLQ topic to receive the error messages. +Default: null (If not specified, messages that result in errors are forwarded to a topic named error.<destination>.<group>). + + + +dlqProducerProperties + +Using this, DLQ-specific producer properties can be set. +All the properties available through kafka producer properties can be set through this property. +Default: Default Kafka producer properties. + + + +standardHeaders + +Indicates which standard headers are populated by the inbound channel adapter. +Allowed values: none, id, timestamp, or both. +Useful if using native deserialization and the first component to receive a message needs an id (such as an aggregator that is configured to use a JDBC message store). +Default: none + + + +converterBeanName + +The name of a bean that implements RecordMessageConverter. Used in the inbound channel adapter to replace the default MessagingMessageConverter. +Default: null + + + +idleEventInterval + +The interval, in milliseconds, between events indicating that no messages have recently been received. +Use an ApplicationListener<ListenerContainerIdleEvent> to receive these events. +See for a usage example. +Default: 30000 + + + +destinationIsPattern + +When true, the destination is treated as a regular expression Pattern used to match topic names by the broker. +When true, topics are not provisioned, and enableDlq is not allowed, because the binder does not know the topic names during the provisioning phase. +Note, the time taken to detect new topics that match the pattern is controlled by the consumer property metadata.max.age.ms, which (at the time of writing) defaults to 300,000ms (5 minutes). +This can be configured using the configuration property above. +Default: false + + + +
+
+Kafka Producer Properties +The following properties are available for Kafka producers only and +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.producer.. + + +admin.configuration + +A Map of Kafka topic properties used when provisioning new topics — for example, spring.cloud.stream.kafka.bindings.input.consumer.admin.configuration.message.format.version=0.9.0.0 +Default: none. + + + +admin.replicas-assignment + +A Map<Integer, List<Integer>> of replica assignments, with the key being the partition and the value being the assignments. +Used when provisioning new topics. +See NewTopic javadocs in the kafka-clients jar. +Default: none. + + + +admin.replication-factor + +The replication factor to use when provisioning new topics. Overrides the binder-wide setting. +Ignored if replicas-assignments is present. +Default: none (the binder-wide default of 1 is used). + + + +bufferSize + +Upper limit, in bytes, of how much data the Kafka producer attempts to batch before sending. +Default: 16384. + + + +sync + +Whether the producer is synchronous. +Default: false. + + + +batchTimeout + +How long the producer waits to allow more messages to accumulate in the same batch before sending the messages. +(Normally, the producer does not wait at all and simply sends all the messages that accumulated while the previous send was in progress.) A non-zero value may increase throughput at the expense of latency. +Default: 0. + + + +messageKeyExpression + +A SpEL expression evaluated against the outgoing message used to populate the key of the produced Kafka message — for example, headers['myKey']. +The payload cannot be used because, by the time this expression is evaluated, the payload is already in the form of a byte[]. +Default: none. + + + +headerPatterns + +A comma-delimited list of simple patterns to match Spring messaging headers to be mapped to the Kafka Headers in the ProducerRecord. +Patterns can begin or end with the wildcard character (asterisk). +Patterns can be negated by prefixing with !. +Matching stops after the first match (positive or negative). +For example !ask,as* will pass ash but not ask. +id and timestamp are never mapped. +Default: * (all headers - except the id and timestamp) + + + +configuration + +Map with a key/value pair containing generic Kafka producer properties. +Default: Empty map. + + + + +The Kafka binder uses the partitionCount setting of the producer as a hint to create a topic with the given partition count (in conjunction with the minPartitionCount, the maximum of the two being the value being used). +Exercise caution when configuring both minPartitionCount for a binder and partitionCount for an application, as the larger value is used. +If a topic already exists with a smaller partition count and autoAddPartitions is disabled (the default), the binder fails to start. +If a topic already exists with a smaller partition count and autoAddPartitions is enabled, new partitions are added. +If a topic already exists with a larger number of partitions than the maximum of (minPartitionCount or partitionCount), the existing partition count is used. + +
+
+Usage examples +In this section, we show the use of the preceding properties for specific scenarios. +
+Example: Setting <literal>autoCommitOffset</literal> to <literal>false</literal> and Relying on Manual Acking +This example illustrates how one may manually acknowledge offsets in a consumer application. +This example requires that spring.cloud.stream.kafka.bindings.input.consumer.autoCommitOffset be set to false. +Use the corresponding input channel name for your example. +@SpringBootApplication +@EnableBinding(Sink.class) +public class ManuallyAcknowdledgingConsumer { + + public static void main(String[] args) { + SpringApplication.run(ManuallyAcknowdledgingConsumer.class, args); + } + + @StreamListener(Sink.INPUT) + public void process(Message<?> message) { + Acknowledgment acknowledgment = message.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class); + if (acknowledgment != null) { + System.out.println("Acknowledgment provided"); + acknowledgment.acknowledge(); + } + } +} +
+
+Example: Security Configuration +Apache Kafka 0.9 supports secure connections between client and brokers. +To take advantage of this feature, follow the guidelines in the Apache Kafka Documentation as well as the Kafka 0.9 security guidelines from the Confluent documentation. +Use the spring.cloud.stream.kafka.binder.configuration option to set security properties for all clients created by the binder. +For example, to set security.protocol to SASL_SSL, set the following property: +spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_SSL +All the other security properties can be set in a similar manner. +When using Kerberos, follow the instructions in the reference documentation for creating and referencing the JAAS configuration. +Spring Cloud Stream supports passing JAAS configuration information to the application by using a JAAS configuration file and using Spring Boot properties. +
+Using JAAS Configuration Files +The JAAS and (optionally) krb5 file locations can be set for Spring Cloud Stream applications by using system properties. +The following example shows how to launch a Spring Cloud Stream application with SASL and Kerberos by using a JAAS configuration file: + java -Djava.security.auth.login.config=/path.to/kafka_client_jaas.conf -jar log.jar \ + --spring.cloud.stream.kafka.binder.brokers=secure.server:9092 \ + --spring.cloud.stream.bindings.input.destination=stream.ticktock \ + --spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_PLAINTEXT +
+
+Using Spring Boot Properties +As an alternative to having a JAAS configuration file, Spring Cloud Stream provides a mechanism for setting up the JAAS configuration for Spring Cloud Stream applications by using Spring Boot properties. +The following properties can be used to configure the login context of the Kafka client: + + +spring.cloud.stream.kafka.binder.jaas.loginModule + +The login module name. Not necessary to be set in normal cases. +Default: com.sun.security.auth.module.Krb5LoginModule. + + + +spring.cloud.stream.kafka.binder.jaas.controlFlag + +The control flag of the login module. +Default: required. + + + +spring.cloud.stream.kafka.binder.jaas.options + +Map with a key/value pair containing the login module options. +Default: Empty map. + + + +The following example shows how to launch a Spring Cloud Stream application with SASL and Kerberos by using Spring Boot configuration properties: + java --spring.cloud.stream.kafka.binder.brokers=secure.server:9092 \ + --spring.cloud.stream.bindings.input.destination=stream.ticktock \ + --spring.cloud.stream.kafka.binder.autoCreateTopics=false \ + --spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_PLAINTEXT \ + --spring.cloud.stream.kafka.binder.jaas.options.useKeyTab=true \ + --spring.cloud.stream.kafka.binder.jaas.options.storeKey=true \ + --spring.cloud.stream.kafka.binder.jaas.options.keyTab=/etc/security/keytabs/kafka_client.keytab \ + --spring.cloud.stream.kafka.binder.jaas.options.principal=kafka-client-1@EXAMPLE.COM +The preceding example represents the equivalent of the following JAAS file: +KafkaClient { + com.sun.security.auth.module.Krb5LoginModule required + useKeyTab=true + storeKey=true + keyTab="/etc/security/keytabs/kafka_client.keytab" + principal="kafka-client-1@EXAMPLE.COM"; +}; +If the topics required already exist on the broker or will be created by an administrator, autocreation can be turned off and only client JAAS properties need to be sent. + +Do not mix JAAS configuration files and Spring Boot properties in the same application. +If the -Djava.security.auth.login.config system property is already present, Spring Cloud Stream ignores the Spring Boot properties. + + +Be careful when using the autoCreateTopics and autoAddPartitions with Kerberos. +Usually, applications may use principals that do not have administrative rights in Kafka and Zookeeper. +Consequently, relying on Spring Cloud Stream to create/modify topics may fail. +In secure environments, we strongly recommend creating topics and managing ACLs administratively by using Kafka tooling. + +
+
+
+Example: Pausing and Resuming the Consumer +If you wish to suspend consumption but not cause a partition rebalance, you can pause and resume the consumer. +This is facilitated by adding the Consumer as a parameter to your @StreamListener. +To resume, you need an ApplicationListener for ListenerContainerIdleEvent instances. +The frequency at which events are published is controlled by the idleEventInterval property. +Since the consumer is not thread-safe, you must call these methods on the calling thread. +The following simple application shows how to pause and resume: +@SpringBootApplication +@EnableBinding(Sink.class) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @StreamListener(Sink.INPUT) + public void in(String in, @Header(KafkaHeaders.CONSUMER) Consumer<?, ?> consumer) { + System.out.println(in); + consumer.pause(Collections.singleton(new TopicPartition("myTopic", 0))); + } + + @Bean + public ApplicationListener<ListenerContainerIdleEvent> idleListener() { + return event -> { + System.out.println(event); + if (event.getConsumer().paused().size() > 0) { + event.getConsumer().resume(event.getConsumer().paused()); + } + }; + } + +} +
+
+
+ +Error Channels +Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination and can also be configured to send async producer send failures to an error channel. +See for more information. +The payload of the ErrorMessage for a send failure is a KafkaSendFailureException with properties: + + +failedMessage: The Spring Messaging Message<?> that failed to be sent. + + +record: The raw ProducerRecord that was created from the failedMessage + + +There is no automatic handling of producer exceptions (such as sending to a Dead-Letter queue). +You can consume these exceptions with your own Spring Integration flow. + + +Kafka Metrics +Kafka binder module exposes the following metrics: +spring.cloud.stream.binder.kafka.offset: This metric indicates how many messages have not been yet consumed from a given binder’s topic by a given consumer group. +The metrics provided are based on the Mircometer metrics library. The metric contains the consumer group information, topic and the actual lag in committed offset from the latest offset on the topic. +This metric is particularly useful for providing auto-scaling feedback to a PaaS platform. + + +Tombstone Records (null record values) +When using compacted topics, a record with a null value (also called a tombstone record) represents the deletion of a key. +To receive such messages in a @StreamListener method, the parameter must be marked as not required to receive a null value argument. + +@StreamListener(Sink.INPUT) +public void in(@Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) byte[] key, + @Payload(required = false) Customer customer) { + // customer is null if a tombstone record + ... +} + + + +Using a KafkaRebalanceListener +Applications may wish to seek topics/partitions to arbitrary offsets when the partitions are initially assigned, or perform other operations on the consumer. +Starting with version 2.1, if you provide a single KafkaRebalanceListener bean in the application context, it will be wired into all Kafka consumer bindings. + +public interface KafkaBindingRebalanceListener { + + /** + * Invoked by the container before any pending offsets are committed. + * @param bindingName the name of the binding. + * @param consumer the consumer. + * @param partitions the partitions. + */ + default void onPartitionsRevokedBeforeCommit(String bindingName, Consumer<?, ?> consumer, + Collection<TopicPartition> partitions) { + + } + + /** + * Invoked by the container after any pending offsets are committed. + * @param bindingName the name of the binding. + * @param consumer the consumer. + * @param partitions the partitions. + */ + default void onPartitionsRevokedAfterCommit(String bindingName, Consumer<?, ?> consumer, Collection<TopicPartition> partitions) { + + } + + /** + * Invoked when partitions are initially assigned or after a rebalance. + * Applications might only want to perform seek operations on an initial assignment. + * @param bindingName the name of the binding. + * @param consumer the consumer. + * @param partitions the partitions. + * @param initial true if this is the initial assignment. + */ + default void onPartitionsAssigned(String bindingName, Consumer<?, ?> consumer, Collection<TopicPartition> partitions, + boolean initial) { + + } + +} + +You cannot set the resetOffsets consumer property to true when you provide a rebalance listener. + + +Dead-Letter Topic Processing +Because you cannot anticipate how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. +If the reason for the dead-lettering is transient, you may wish to route the messages back to the original topic. +However, if the problem is a permanent issue, that could cause an infinite loop. +The sample Spring Boot application within this topic is an example of how to route those messages back to the original topic, but it moves them to a parking lot topic after three attempts. +The application is another spring-cloud-stream application that reads from the dead-letter topic. +It terminates when no messages are received for 5 seconds. +The examples assume the original destination is so8400out and the consumer group is so8400. +There are a couple of strategies to consider: + + +Consider running the rerouting only when the main application is not running. +Otherwise, the retries for transient errors are used up very quickly. + + +Alternatively, use a two-stage approach: Use this application to route to a third topic and another to route from there back to the main topic. + + +The following code listings show the sample application: + +application.properties + +spring.cloud.stream.bindings.input.group=so8400replay +spring.cloud.stream.bindings.input.destination=error.so8400out.so8400 + +spring.cloud.stream.bindings.output.destination=so8400out +spring.cloud.stream.bindings.output.producer.partitioned=true + +spring.cloud.stream.bindings.parkingLot.destination=so8400in.parkingLot +spring.cloud.stream.bindings.parkingLot.producer.partitioned=true + +spring.cloud.stream.kafka.binder.configuration.auto.offset.reset=earliest + +spring.cloud.stream.kafka.binder.headers=x-retries + + + +Application + +@SpringBootApplication +@EnableBinding(TwoOutputProcessor.class) +public class ReRouteDlqKApplication implements CommandLineRunner { + + private static final String X_RETRIES_HEADER = "x-retries"; + + public static void main(String[] args) { + SpringApplication.run(ReRouteDlqKApplication.class, args).close(); + } + + private final AtomicInteger processed = new AtomicInteger(); + + @Autowired + private MessageChannel parkingLot; + + @StreamListener(Processor.INPUT) + @SendTo(Processor.OUTPUT) + public Message<?> reRoute(Message<?> failed) { + processed.incrementAndGet(); + Integer retries = failed.getHeaders().get(X_RETRIES_HEADER, Integer.class); + if (retries == null) { + System.out.println("First retry for " + failed); + return MessageBuilder.fromMessage(failed) + .setHeader(X_RETRIES_HEADER, new Integer(1)) + .setHeader(BinderHeaders.PARTITION_OVERRIDE, + failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID)) + .build(); + } + else if (retries.intValue() < 3) { + System.out.println("Another retry for " + failed); + return MessageBuilder.fromMessage(failed) + .setHeader(X_RETRIES_HEADER, new Integer(retries.intValue() + 1)) + .setHeader(BinderHeaders.PARTITION_OVERRIDE, + failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID)) + .build(); + } + else { + System.out.println("Retries exhausted for " + failed); + parkingLot.send(MessageBuilder.fromMessage(failed) + .setHeader(BinderHeaders.PARTITION_OVERRIDE, + failed.getHeaders().get(KafkaHeaders.RECEIVED_PARTITION_ID)) + .build()); + } + return null; + } + + @Override + public void run(String... args) throws Exception { + while (true) { + int count = this.processed.get(); + Thread.sleep(5000); + if (count == this.processed.get()) { + System.out.println("Idle, terminating"); + return; + } + } + } + + public interface TwoOutputProcessor extends Processor { + + @Output("parkingLot") + MessageChannel parkingLot(); + + } + +} + + + + +Partitioning with the Kafka Binder +Apache Kafka supports topic partitioning natively. +Sometimes it is advantageous to send data to specific partitions — for example, when you want to strictly order message processing (all messages for a particular customer should go to the same partition). +The following example shows how to configure the producer and consumer side: +@SpringBootApplication +@EnableBinding(Source.class) +public class KafkaPartitionProducerApplication { + + private static final Random RANDOM = new Random(System.currentTimeMillis()); + + private static final String[] data = new String[] { + "foo1", "bar1", "qux1", + "foo2", "bar2", "qux2", + "foo3", "bar3", "qux3", + "foo4", "bar4", "qux4", + }; + + public static void main(String[] args) { + new SpringApplicationBuilder(KafkaPartitionProducerApplication.class) + .web(false) + .run(args); + } + + @InboundChannelAdapter(channel = Source.OUTPUT, poller = @Poller(fixedRate = "5000")) + public Message<?> generate() { + String value = data[RANDOM.nextInt(data.length)]; + System.out.println("Sending: " + value); + return MessageBuilder.withPayload(value) + .setHeader("partitionKey", value) + .build(); + } + +} + +application.yml + +spring: + cloud: + stream: + bindings: + output: + destination: partitioned.topic + producer: + partitioned: true + partition-key-expression: headers['partitionKey'] + partition-count: 12 + + + +The topic must be provisioned to have enough partitions to achieve the desired concurrency for all consumer groups. +The above configuration supports up to 12 consumer instances (6 if their concurrency is 2, 4 if their concurrency is 3, and so on). +It is generally best to over-provision the partitions to allow for future increases in consumers or concurrency. + + +The preceding configuration uses the default partitioning (key.hashCode() % partitionCount). +This may or may not provide a suitably balanced algorithm, depending on the key values. +You can override this default by using the partitionSelectorExpression or partitionSelectorClass properties. + +Since partitions are natively handled by Kafka, no special configuration is needed on the consumer side. +Kafka allocates partitions across the instances. +The following Spring Boot application listens to a Kafka stream and prints (to the console) the partition ID to which each message goes: +@SpringBootApplication +@EnableBinding(Sink.class) +public class KafkaPartitionConsumerApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(KafkaPartitionConsumerApplication.class) + .web(false) + .run(args); + } + + @StreamListener(Sink.INPUT) + public void listen(@Payload String in, @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) { + System.out.println(in + " received from partition " + partition); + } + +} + +application.yml + +spring: + cloud: + stream: + bindings: + input: + destination: partitioned.topic + group: myGroup + + +You can add instances as needed. +Kafka rebalances the partition allocations. +If the instance count (or instance count * concurrency) exceeds the number of partitions, some consumers are idle. + +
+ +Appendices + +Building +
+Basic Compile and Test +To build the source you will need to install JDK 1.7. +The build uses the Maven wrapper so you don’t have to install a specific +version of Maven. To enable the tests, you should have Kafka server 0.9 or above running +before building. See below for more information on running the servers. +The main build command is +$ ./mvnw clean install +You can also add '-DskipTests' if you like, to avoid running the tests. + +You can also install Maven (>=3.3.3) yourself and run the mvn command +in place of ./mvnw in the examples below. If you do that you also +might need to add -P spring if your local Maven settings do not +contain repository declarations for spring pre-release artifacts. + + +Be aware that you might need to increase the amount of memory +available to Maven by setting a MAVEN_OPTS environment variable with +a value like -Xmx512m -XX:MaxPermSize=128m. We try to cover this in +the .mvn configuration, so if you find you have to do it to make a +build succeed, please raise a ticket to get the settings added to +source control. + +The projects that require middleware generally include a +docker-compose.yml, so consider using +Docker Compose to run the middeware servers +in Docker containers. +
+
+Documentation +There is a "full" profile that will generate documentation. +
+
+Working with the code +If you don’t have an IDE preference we would recommend that you use +Spring Tools Suite or +Eclipse when working with the code. We use the +m2eclipe eclipse plugin for maven support. Other IDEs and tools +should also work without issue. +
+Importing into eclipse with m2eclipse +We recommend the m2eclipe eclipse plugin when working with +eclipse. If you don’t already have m2eclipse installed it is available from the "eclipse +marketplace". +Unfortunately m2e does not yet support Maven 3.3, so once the projects +are imported into Eclipse you will also need to tell m2eclipse to use +the .settings.xml file for the projects. If you do not do this you +may see many different errors related to the POMs in the +projects. Open your Eclipse preferences, expand the Maven +preferences, and select User Settings. In the User Settings field +click Browse and navigate to the Spring Cloud project you imported +selecting the .settings.xml file in that project. Click Apply and +then OK to save the preference changes. + +Alternatively you can copy the repository settings from .settings.xml into your own ~/.m2/settings.xml. + +
+
+Importing into eclipse without m2eclipse +If you prefer not to use m2eclipse you can generate eclipse project metadata using the +following command: +$ ./mvnw eclipse:eclipse +The generated eclipse projects can be imported by selecting import existing projects +from the file menu. +[[contributing] +== Contributing +Spring Cloud is released under the non-restrictive Apache 2.0 license, +and follows a very standard Github development process, using Github +tracker for issues and merging pull requests into master. If you want +to contribute even something trivial please do not hesitate, but +follow the guidelines below. +
+
+
+Sign the Contributor License Agreement +Before we accept a non-trivial patch or pull request we will need you to sign the +contributor’s agreement. +Signing the contributor’s agreement does not grant anyone commit rights to the main +repository, but it does mean that we can accept your contributions, and you will get an +author credit if we do. Active contributors might be asked to join the core team, and +given the ability to merge pull requests. +
+
+Code Conventions and Housekeeping +None of these is essential for a pull request, but they will all help. They can also be +added after the original pull request but before a merge. + + +Use the Spring Framework code format conventions. If you use Eclipse +you can import formatter settings using the +eclipse-code-formatter.xml file from the +Spring +Cloud Build project. If using IntelliJ, you can use the +Eclipse Code Formatter +Plugin to import the same file. + + +Make sure all new .java files to have a simple Javadoc class comment with at least an +@author tag identifying you, and preferably at least a paragraph on what the class is +for. + + +Add the ASF license header comment to all new .java files (copy from existing files +in the project) + + +Add yourself as an @author to the .java files that you modify substantially (more +than cosmetic changes). + + +Add some Javadocs and, if you change the namespace, some XSD doc elements. + + +A few unit tests would help a lot as well — someone has to do it. + + +If no-one else is using your branch, please rebase it against the current master (or +other target branch in the main project). + + +When writing a commit message please follow these conventions, +if you are fixing an existing issue please add Fixes gh-XXXX at the end of the commit +message (where XXXX is the issue number). + + +
+
+
+
\ No newline at end of file