Sync docs from v2.1.4.RELEASE to gh-pages
35
spring-cloud-zookeeper/2.1.4.RELEASE/css/highlight.css
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
342
spring-cloud-zookeeper/2.1.4.RELEASE/css/manual.css
Normal file
@@ -0,0 +1,342 @@
|
||||
@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;
|
||||
}
|
||||
330
spring-cloud-zookeeper/2.1.4.RELEASE/ghpages.sh
Normal file
@@ -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 1.0.0.RELEASE/ 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 1.0.0.RELEASE/ 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 <<EOF
|
||||
The idea of this script is to update gh-pages branch with the generated docs. Without any options
|
||||
the script will work in the following manner:
|
||||
|
||||
- if there's no gh-pages / target for docs module then the script ends
|
||||
- for master branch the generated docs are copied to the root of gh-pages branch
|
||||
- for any other branch (if that branch is whitelisted) a subfolder with branch name is created
|
||||
and docs are copied there
|
||||
- if the version switch is passed (-v) then a tag with (v) prefix will be retrieved and a folder
|
||||
with that version number will be created in the gh-pages branch. WARNING! No whitelist verification will take place
|
||||
- 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/<project-name>/<version>`
|
||||
- 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/<project-name>/<version>`
|
||||
|
||||
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
|
||||
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/background.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/callouts/1.png
Normal file
|
After Width: | Height: | Size: 329 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/callouts/2.png
Normal file
|
After Width: | Height: | Size: 353 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/callouts/3.png
Normal file
|
After Width: | Height: | Size: 350 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/caution.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/important.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/note.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/tip.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/images/warning.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
35
spring-cloud-zookeeper/2.1.4.RELEASE/multi/css/highlight.css
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
342
spring-cloud-zookeeper/2.1.4.RELEASE/multi/css/manual.css
Normal file
@@ -0,0 +1,342 @@
|
||||
@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;
|
||||
}
|
||||
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/background.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/callouts/1.png
Normal file
|
After Width: | Height: | Size: 329 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/callouts/2.png
Normal file
|
After Width: | Height: | Size: 353 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/callouts/3.png
Normal file
|
After Width: | Height: | Size: 350 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/caution.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/important.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/note.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/tip.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/multi/images/warning.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,9 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title></title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="next" href="multi_spring-cloud-zookeeper-install.html" title="1. Install Zookeeper"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-install.html">Next</a></td></tr></table><hr></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a name="d0e9" href="#d0e9"></a></h1></div></div></div><p>This project provides Zookeeper integrations for Spring Boot applications through
|
||||
autoconfiguration and binding to the Spring Environment and other Spring programming model
|
||||
idioms. With a few annotations, you can quickly enable and configure the common patterns
|
||||
inside your application and build large distributed systems with Zookeeper based
|
||||
components. The provided patterns include Service Discovery and Configuration. Integration
|
||||
with Spring Cloud Netflix provides Intelligent Routing (Zuul), Client Side Load Balancing
|
||||
(Ribbon), and Circuit Breaker (Hystrix).</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-install.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Spring Cloud Zookeeper </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> 1. Install Zookeeper</td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,61 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>7. Distributed Configuration with Zookeeper</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_spring-cloud-zookeeper-dependency-watcher.html" title="6. Spring Cloud Zookeeper Dependency Watcher"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">7. Distributed Configuration with Zookeeper</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-dependency-watcher.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-config" href="#spring-cloud-zookeeper-config"></a>7. Distributed Configuration with Zookeeper</h1></div></div></div><p>Zookeeper provides a
|
||||
<a class="link" href="https://zookeeper.apache.org/doc/current/zookeeperOver.html#sc_dataModelNameSpace" target="_top">hierarchical namespace</a>
|
||||
that lets clients store arbitrary data, such as configuration data. Spring Cloud Zookeeper
|
||||
Config is an alternative to the
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-config" target="_top">Config Server and Client</a>.
|
||||
Configuration is loaded into the Spring Environment during the special <span class="quote">“<span class="quote">bootstrap</span>”</span>
|
||||
phase. Configuration is stored in the <code class="literal">/config</code> namespace by default. Multiple
|
||||
<code class="literal">PropertySource</code> instances are created, based on the application’s name and the active
|
||||
profiles, to mimic the Spring Cloud Config order of resolving properties. For example, an
|
||||
application with a name of <code class="literal">testApp</code> and with the <code class="literal">dev</code> profile has the following property
|
||||
sources created for it:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">config/testApp,dev</code></li><li class="listitem"><code class="literal">config/testApp</code></li><li class="listitem"><code class="literal">config/application,dev</code></li><li class="listitem"><code class="literal">config/application</code></li></ul></div><p>The most specific property source is at the top, with the least specific at the bottom.
|
||||
Properties in the <code class="literal">config/application</code> namespace apply to all applications that use
|
||||
zookeeper for configuration. Properties in the <code class="literal">config/testApp</code> namespace are available
|
||||
only to the instances of the service named <code class="literal">testApp</code>.</p><p>Configuration is currently read on startup of the application. Sending a HTTP <code class="literal">POST</code>
|
||||
request to <code class="literal">/refresh</code> causes the configuration to be reloaded. Watching the configuration
|
||||
namespace (which Zookeeper supports) is not currently implemented.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_activating_3" href="#_activating_3"></a>7.1 Activating</h2></div></div></div><p>Including a dependency on
|
||||
<code class="literal">org.springframework.cloud:spring-cloud-starter-zookeeper-config</code> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Config.</p><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>When working with version 3.4 of Zookeeper you need to change
|
||||
the way you include the dependency as described <a class="link" href="multi_spring-cloud-zookeeper-install.html" title="1. Install Zookeeper">here</a>.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_customizing" href="#_customizing"></a>7.2 Customizing</h2></div></div></div><p>Zookeeper Config may be customized by setting the following properties:</p><p><b>bootstrap.yml. </b>
|
||||
</p><pre class="programlisting">spring:
|
||||
cloud:
|
||||
zookeeper:
|
||||
config:
|
||||
enabled: true
|
||||
root: configuration
|
||||
defaultContext: apps
|
||||
profileSeparator: '::'</pre><p>
|
||||
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">enabled</code>: Setting this value to <code class="literal">false</code> disables Zookeeper Config.</li><li class="listitem"><code class="literal">root</code>: Sets the base namespace for configuration values.</li><li class="listitem"><code class="literal">defaultContext</code>: Sets the name used by all applications.</li><li class="listitem"><code class="literal">profileSeparator</code>: Sets the value of the separator used to separate the profile name in
|
||||
property sources with profiles.</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_access_control_lists_acls" href="#_access_control_lists_acls"></a>7.3 Access Control Lists (ACLs)</h2></div></div></div><p>You can add authentication information for Zookeeper ACLs by calling the <code class="literal">addAuthInfo</code>
|
||||
method of a <code class="literal">CuratorFramework</code> bean. One way to accomplish this is to provide your own
|
||||
<code class="literal">CuratorFramework</code> bean, as shown in the following example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@BoostrapConfiguration</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomCuratorFrameworkConfig {
|
||||
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@Bean</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> CuratorFramework curatorFramework() {
|
||||
CuratorFramework curator = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CuratorFramework();
|
||||
curator.addAuthInfo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"digest"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"user:password"</span>.getBytes());
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> curator;
|
||||
}
|
||||
|
||||
}</pre><p>Consult
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-zookeeper/blob/master/spring-cloud-zookeeper-core/src/main/java/org/springframework/cloud/zookeeper/ZookeeperAutoConfiguration.java" target="_top">the ZookeeperAutoConfiguration class</a>
|
||||
to see how the <code class="literal">CuratorFramework</code> bean’s default configuration.</p><p>Alternatively, you can add your credentials from a class that depends on the existing
|
||||
<code class="literal">CuratorFramework</code> bean, as shown in the following example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@BoostrapConfiguration</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> DefaultCuratorFrameworkConfig {
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> ZookeeperConfig(CuratorFramework curator) {
|
||||
curator.addAuthInfo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"digest"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"user:password"</span>.getBytes());
|
||||
}
|
||||
|
||||
}</pre><p>The creation of this bean must occur during the boostrapping phase. You can register
|
||||
configuration classes to run during this phase by annotating them with
|
||||
<code class="literal">@BootstrapConfiguration</code> and including them in a comma-separated list that you set as the
|
||||
value of the <code class="literal">org.springframework.cloud.bootstrap.BootstrapConfiguration</code> property in the
|
||||
<code class="literal">resources/META-INF/spring.factories</code> file, as shown in the following example:</p><p><b>resources/META-INF/spring.factories. </b>
|
||||
</p><pre class="screen">org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
my.project.CustomCuratorFrameworkConfig,\
|
||||
my.project.DefaultCuratorFrameworkConfig</pre><p>
|
||||
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-dependency-watcher.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">6. Spring Cloud Zookeeper Dependency Watcher </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,86 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>5. Zookeeper Dependencies</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_spring-cloud-zookeeper-service-registry.html" title="4. Spring Cloud Zookeeper and Service Registry"><link rel="next" href="multi_spring-cloud-zookeeper-dependency-watcher.html" title="6. Spring Cloud Zookeeper Dependency Watcher"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">5. Zookeeper Dependencies</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-service-registry.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-dependency-watcher.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-dependencies" href="#spring-cloud-zookeeper-dependencies"></a>5. Zookeeper Dependencies</h1></div></div></div><p>The following topics cover how to work with Spring Cloud Zookeeper dependencies:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="xref" href="multi_spring-cloud-zookeeper-dependencies.html#spring-cloud-zookeeper-dependencies-using" title="5.1 Using the Zookeeper Dependencies">Section 5.1, “Using the Zookeeper Dependencies”</a></li><li class="listitem"><a class="xref" href="multi_spring-cloud-zookeeper-dependencies.html#spring-cloud-zookeeper-dependencies-activating" title="5.2 Activating Zookeeper Dependencies">Section 5.2, “Activating Zookeeper Dependencies”</a></li><li class="listitem"><a class="xref" href="multi_spring-cloud-zookeeper-dependencies.html#spring-cloud-zookeeper-dependencies-setting-up" title="5.3 Setting up Zookeeper Dependencies">Section 5.3, “Setting up Zookeeper Dependencies”</a></li><li class="listitem"><a class="xref" href="multi_spring-cloud-zookeeper-dependencies.html#spring-cloud-zookeeper-dependencies-configuring" title="5.4 Configuring Spring Cloud Zookeeper Dependencies">Section 5.4, “Configuring Spring Cloud Zookeeper Dependencies”</a></li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-using" href="#spring-cloud-zookeeper-dependencies-using"></a>5.1 Using the Zookeeper Dependencies</h2></div></div></div><p>Spring Cloud Zookeeper gives you a possibility to provide dependencies of your application
|
||||
as properties. As dependencies, you can understand other applications that are registered
|
||||
in Zookeeper and which you would like to call through
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign" target="_top">Feign</a>
|
||||
(a REST client builder) and <a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon" target="_top">Spring <code class="literal">RestTemplate</code></a>.</p><p>You can also use the Zookeeper Dependency Watchers functionality to control and monitor
|
||||
the state of your dependencies.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-activating" href="#spring-cloud-zookeeper-dependencies-activating"></a>5.2 Activating Zookeeper Dependencies</h2></div></div></div><p>Including a dependency on
|
||||
<code class="literal">org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</code> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Dependencies. Even if you provide
|
||||
the dependencies in your properties, you can turn off the dependencies. To do so, set the
|
||||
<code class="literal">spring.cloud.zookeeper.dependency.enabled</code> property to false (it defaults to <code class="literal">true</code>).</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-setting-up" href="#spring-cloud-zookeeper-dependencies-setting-up"></a>5.3 Setting up Zookeeper Dependencies</h2></div></div></div><p>Consider the following example of dependency representation:</p><p><b>application.yml. </b>
|
||||
</p><pre class="programlisting">spring.application.name: yourServiceName
|
||||
spring.cloud.zookeeper:
|
||||
dependencies:
|
||||
newsletter:
|
||||
path: /path/where/newsletter/has/registered/in/zookeeper
|
||||
loadBalancerType: ROUND_ROBIN
|
||||
contentTypeTemplate: application/vnd.newsletter.$version+json
|
||||
version: v1
|
||||
headers:
|
||||
header1:
|
||||
- value1
|
||||
header2:
|
||||
- value2
|
||||
required: false
|
||||
stubs: org.springframework:foo:stubs
|
||||
mailing:
|
||||
path: /path/where/mailing/has/registered/in/zookeeper
|
||||
loadBalancerType: ROUND_ROBIN
|
||||
contentTypeTemplate: application/vnd.mailing.$version+json
|
||||
version: v1
|
||||
required: true</pre><p>
|
||||
</p><p>The next few sections go through each part of the dependency one by one. The root property
|
||||
name is <code class="literal">spring.cloud.zookeeper.dependencies</code>.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-zookeeper-dependencies-setting-up-aliases" href="#spring-cloud-zookeeper-dependencies-setting-up-aliases"></a>5.3.1 Aliases</h3></div></div></div><p>Below the root property you have to represent each dependency as an alias. This is due to
|
||||
the constraints of Ribbon, which requires that the application ID be placed in the URL.
|
||||
Consequently, you cannot pass any complex path, suchas <code class="literal">/myApp/myRoute/name</code>). The alias
|
||||
is the name you use instead of the <code class="literal">serviceId</code> for <code class="literal">DiscoveryClient</code>, <code class="literal">Feign</code>, or
|
||||
<code class="literal">RestTemplate</code>.</p><p>In the previous examples, the aliases are <code class="literal">newsletter</code> and <code class="literal">mailing</code>. The following
|
||||
example shows Feign usage with a <code class="literal">newsletter</code> alias:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@FeignClient("newsletter")</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">interface</span> NewsletterService {
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@RequestMapping(method = RequestMethod.GET, value = "/newsletter")</xslthl:annotation>
|
||||
String getNewsletters();
|
||||
}</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_path" href="#_path"></a>5.3.2 Path</h3></div></div></div><p>The path is represented by the <code class="literal">path</code> YAML property and is the path under which the
|
||||
dependency is registered under Zookeeper. As described in the
|
||||
<a class="link" href="multi_spring-cloud-zookeeper-dependencies.html#spring-cloud-zookeeper-dependencies-setting-up-aliases" title="5.3.1 Aliases">previous section</a>, Ribbon
|
||||
operates on URLs. As a result, this path is not compliant with its requirement.
|
||||
That is why Spring Cloud Zookeeper maps the alias to the proper path.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_load_balancer_type" href="#_load_balancer_type"></a>5.3.3 Load Balancer Type</h3></div></div></div><p>The load balancer type is represented by <code class="literal">loadBalancerType</code> YAML property.</p><p>If you know what kind of load-balancing strategy has to be applied when calling this
|
||||
particular dependency, you can provide it in the YAML file, and it is automatically
|
||||
applied. You can choose one of the following load balancing strategies:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">STICKY: Once chosen, the instance is always called.</li><li class="listitem">RANDOM: Picks an instance randomly.</li><li class="listitem">ROUND_ROBIN: Iterates over instances over and over again.</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_content_type_template_and_version" href="#_content_type_template_and_version"></a>5.3.4 <code class="literal">Content-Type</code> Template and Version</h3></div></div></div><p>The <code class="literal">Content-Type</code> template and version are represented by the <code class="literal">contentTypeTemplate</code> and
|
||||
<code class="literal">version</code> YAML properties.</p><p>If you version your API in the <code class="literal">Content-Type</code> header, you do not want to add this header
|
||||
to each of your requests. Also, if you want to call a new version of the API, you do not
|
||||
want to roam around your code to bump up the API version. That is why you can provide a
|
||||
<code class="literal">contentTypeTemplate</code> with a special <code class="literal">$version</code> placeholder. That placeholder will be filled by the value of the
|
||||
<code class="literal">version</code> YAML property. Consider the following example of a <code class="literal">contentTypeTemplate</code>:</p><pre class="screen">application/vnd.newsletter.$version+json</pre><p>Further consider the following <code class="literal">version</code>:</p><pre class="screen">v1</pre><p>The combination of <code class="literal">contentTypeTemplate</code> and version results in the creation of a
|
||||
<code class="literal">Content-Type</code> header for each request, as follows:</p><pre class="screen">application/vnd.newsletter.v1+json</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_default_headers" href="#_default_headers"></a>5.3.5 Default Headers</h3></div></div></div><p>Default headers are represented by the <code class="literal">headers</code> map in YAML.</p><p>Sometimes, each call to a dependency requires setting up of some default headers. To not
|
||||
do that in code, you can set them up in the YAML file, as shown in the following example
|
||||
<code class="literal">headers</code> section:</p><pre class="programlisting">headers:
|
||||
Accept:
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
Cache-Control:
|
||||
- no-cache</pre><p>That <code class="literal">headers</code> section results in adding the <code class="literal">Accept</code> and <code class="literal">Cache-Control</code> headers with
|
||||
appropriate list of values in your HTTP request.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_required_dependencies" href="#_required_dependencies"></a>5.3.6 Required Dependencies</h3></div></div></div><p>Required dependencies are represented by <code class="literal">required</code> property in YAML.</p><p>If one of your dependencies is required to be up when your application boots, you can set
|
||||
the <code class="literal">required: true</code> property in the YAML file.</p><p>If your application cannot localize the required dependency during boot time, it throws an
|
||||
exception, and the Spring Context fails to set up. In other words, your application cannot
|
||||
start if the required dependency is not registered in Zookeeper.</p><p>You can read more about Spring Cloud Zookeeper Presence Checker
|
||||
<a class="link" href="multi_spring-cloud-zookeeper-dependency-watcher.html#spring-cloud-zookeeper-dependency-watcher-presence-checker" title="6.3 Using the Presence Checker">later in this document</a>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_stubs" href="#_stubs"></a>5.3.7 Stubs</h3></div></div></div><p>You can provide a colon-separated path to the JAR containing stubs of the dependency, as
|
||||
shown in the following example:</p><p><code class="literal">stubs: org.springframework:myApp:stubs</code></p><p>where:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">org.springframework</code> is the <code class="literal">groupId</code>.</li><li class="listitem"><code class="literal">myApp</code> is the <code class="literal">artifactId</code>.</li><li class="listitem"><code class="literal">stubs</code> is the classifier. (Note that <code class="literal">stubs</code> is the default value.)</li></ul></div><p>Because <code class="literal">stubs</code> is the default classifier, the preceding example is equal to the following
|
||||
example:</p><p><code class="literal">stubs: org.springframework:myApp</code></p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-configuring" href="#spring-cloud-zookeeper-dependencies-configuring"></a>5.4 Configuring Spring Cloud Zookeeper Dependencies</h2></div></div></div><p>You can set the following properties to enable or disable parts of Zookeeper Dependencies
|
||||
functionalities:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependencies</code>: If you do not set this property, you cannot use
|
||||
Zookeeper Dependencies.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.ribbon.enabled</code> (enabled by default): Ribbon requires
|
||||
either explicit global configuration or a particular one for a dependency. By turning on
|
||||
this property, runtime load balancing strategy resolution is possible, and you can use the
|
||||
<code class="literal">loadBalancerType</code> section of the Zookeeper Dependencies. The configuration that needs
|
||||
this property has an implementation of <code class="literal">LoadBalancerClient</code> that delegates to the
|
||||
<code class="literal">ILoadBalancer</code> presented in the next bullet.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.ribbon.loadbalancer</code> (enabled by default): Thanks to
|
||||
this property, the custom <code class="literal">ILoadBalancer</code> knows that the part of the URI passed to Ribbon
|
||||
might actually be the alias that has to be resolved to a proper path in Zookeeper. Without
|
||||
this property, you cannot register applications under nested paths.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.headers.enabled</code> (enabled by default): This property
|
||||
registers a <code class="literal">RibbonClient</code> that automatically appends appropriate headers and content
|
||||
types with their versions, as presented in the Dependency configuration. Without this
|
||||
setting, those two parameters do not work.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.resttemplate.enabled</code> (enabled by default): When
|
||||
enabled, this property modifies the request headers of a <code class="literal">@LoadBalanced</code>-annotated
|
||||
<code class="literal">RestTemplate</code> such that it passes headers and content type with the version set in
|
||||
dependency configuration. Without this setting, those two parameters do not work.</li></ul></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-service-registry.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-dependency-watcher.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4. Spring Cloud Zookeeper and Service Registry </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> 6. Spring Cloud Zookeeper Dependency Watcher</td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,21 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>6. Spring Cloud Zookeeper Dependency Watcher</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_spring-cloud-zookeeper-dependencies.html" title="5. Zookeeper Dependencies"><link rel="next" href="multi_spring-cloud-zookeeper-config.html" title="7. Distributed Configuration with Zookeeper"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">6. Spring Cloud Zookeeper Dependency Watcher</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-dependencies.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-config.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-dependency-watcher" href="#spring-cloud-zookeeper-dependency-watcher"></a>6. Spring Cloud Zookeeper Dependency Watcher</h1></div></div></div><p>The Dependency Watcher mechanism lets you register listeners to your dependencies. The
|
||||
functionality is, in fact, an implementation of the <code class="literal">Observator</code> pattern. When a
|
||||
dependency changes, its state (to either UP or DOWN), some custom logic can be applied.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_activating_2" href="#_activating_2"></a>6.1 Activating</h2></div></div></div><p>Spring Cloud Zookeeper Dependencies functionality needs to be enabled for you to use the
|
||||
Dependency Watcher mechanism.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_registering_a_listener" href="#_registering_a_listener"></a>6.2 Registering a Listener</h2></div></div></div><p>To register a listener, you must implement an interface called
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.DependencyWatcherListener</code> and
|
||||
register it as a bean. The interface gives you one method:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> stateChanged(String dependencyName, DependencyState newState);</pre><p>If you want to register a listener for a particular dependency, the <code class="literal">dependencyName</code> would
|
||||
be the discriminator for your concrete implementation. <code class="literal">newState</code> provides you with
|
||||
information about whether your dependency has changed to <code class="literal">CONNECTED</code> or <code class="literal">DISCONNECTED</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependency-watcher-presence-checker" href="#spring-cloud-zookeeper-dependency-watcher-presence-checker"></a>6.3 Using the Presence Checker</h2></div></div></div><p>Bound with the Dependency Watcher is the functionality called Presence Checker. It lets
|
||||
you provide custom behavior when your application boots, to react according to the state
|
||||
of your dependencies.</p><p>The default implementation of the abstract
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.presence.DependencyPresenceOnStartupVerifier</code>
|
||||
class is the
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.presence.DefaultDependencyPresenceOnStartupVerifier</code>,
|
||||
which works in the following way.</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">If the dependency is marked us <code class="literal">required</code> and is not in Zookeeper, when your application
|
||||
boots, it throws an exception and shuts down.</li><li class="listitem">If the dependency is not <code class="literal">required</code>, the
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.presence.LogMissingDependencyChecker</code>
|
||||
logs that the dependency is missing at the <code class="literal">WARN</code> level.</li></ol></div><p>Because the <code class="literal">DefaultDependencyPresenceOnStartupVerifier</code> is registered only when there is
|
||||
no bean of type <code class="literal">DependencyPresenceOnStartupVerifier</code>, this functionality can be
|
||||
overridden.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-dependencies.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-config.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5. Zookeeper Dependencies </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> 7. Distributed Configuration with Zookeeper</td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,53 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>2. Service Discovery with Zookeeper</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_spring-cloud-zookeeper-install.html" title="1. Install Zookeeper"><link rel="next" href="multi_spring-cloud-zookeeper-netflix.html" title="3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2. Service Discovery with Zookeeper</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-install.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-netflix.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-discovery" href="#spring-cloud-zookeeper-discovery"></a>2. Service Discovery with Zookeeper</h1></div></div></div><p>Service Discovery is one of the key tenets of a microservice based architecture. Trying to
|
||||
hand-configure each client or some form of convention can be difficult to do and can be
|
||||
brittle. <a class="link" href="https://curator.apache.org" target="_top">Curator</a>(A Java library for Zookeeper) provides Service
|
||||
Discovery through a <a class="link" href="https://curator.apache.org/curator-x-discovery/" target="_top">Service Discovery
|
||||
Extension</a>. Spring Cloud Zookeeper uses this extension for service registration and
|
||||
discovery.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_activating" href="#_activating"></a>2.1 Activating</h2></div></div></div><p>Including a dependency on
|
||||
<code class="literal">org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</code> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Discovery.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>For web functionality, you still need to include
|
||||
<code class="literal">org.springframework.boot:spring-boot-starter-web</code>.</p></td></tr></table></div><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>When working with version 3.4 of Zookeeper you need to change
|
||||
the way you include the dependency as described <a class="link" href="multi_spring-cloud-zookeeper-install.html" title="1. Install Zookeeper">here</a>.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_registering_with_zookeeper" href="#_registering_with_zookeeper"></a>2.2 Registering with Zookeeper</h2></div></div></div><p>When a client registers with Zookeeper, it provides metadata (such as host and port, ID,
|
||||
and name) about itself.</p><p>The following example shows a Zookeeper client:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@SpringBootApplication</xslthl:annotation>
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@RestController</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> Application {
|
||||
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@RequestMapping("/")</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String home() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello world"</span>;
|
||||
}
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> main(String[] args) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> SpringApplicationBuilder(Application.<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span>).web(true).run(args);
|
||||
}
|
||||
|
||||
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The preceding example is a normal Spring Boot application.</p></td></tr></table></div><p>If Zookeeper is located somewhere other than <code class="literal">localhost:2181</code>, the configuration must
|
||||
provide the location of the server, as shown in the following example:</p><p><b>application.yml. </b>
|
||||
</p><pre class="programlisting">spring:
|
||||
cloud:
|
||||
zookeeper:
|
||||
connect-string: localhost:2181</pre><p>
|
||||
</p><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>If you use <a class="link" href="multi_spring-cloud-zookeeper-config.html" title="7. Distributed Configuration with Zookeeper">Spring Cloud Zookeeper Config</a>, the
|
||||
values shown in the preceding example need to be in <code class="literal">bootstrap.yml</code> instead of
|
||||
<code class="literal">application.yml</code>.</p></td></tr></table></div><p>The default service name, instance ID, and port (taken from the <code class="literal">Environment</code>) are
|
||||
<code class="literal">${spring.application.name}</code>, the Spring Context ID, and <code class="literal">${server.port}</code>, respectively.</p><p>Having <code class="literal">spring-cloud-starter-zookeeper-discovery</code> on the classpath makes the app into both
|
||||
a Zookeeper <span class="quote">“<span class="quote">service</span>”</span> (that is, it registers itself) and a <span class="quote">“<span class="quote">client</span>”</span> (that is, it can
|
||||
query Zookeeper to locate other services).</p><p>If you would like to disable the Zookeeper Discovery Client, you can set
|
||||
<code class="literal">spring.cloud.zookeeper.discovery.enabled</code> to <code class="literal">false</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_the_discoveryclient" href="#_using_the_discoveryclient"></a>2.3 Using the DiscoveryClient</h2></div></div></div><p>Spring Cloud has support for
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign" target="_top">Feign</a>
|
||||
(a REST client builder) and
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon" target="_top">Spring
|
||||
<code class="literal">RestTemplate</code></a>, using logical service names instead of physical URLs.</p><p>You can also use the <code class="literal">org.springframework.cloud.client.discovery.DiscoveryClient</code>, which
|
||||
provides a simple API for discovery clients that is not specific to Netflix, as shown in
|
||||
the following example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@Autowired</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> DiscoveryClient discoveryClient;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String serviceUrl() {
|
||||
List<ServiceInstance> list = discoveryClient.getInstances(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"STORES"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">if</span> (list != null && list.size() > <xslthl:number xmlns:xslthl="http://xslthl.sourceforge.net/">0</xslthl:number> ) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> list.get(<xslthl:number xmlns:xslthl="http://xslthl.sourceforge.net/">0</xslthl:number>).getUri().toString();
|
||||
}
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> null;
|
||||
}</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-install.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-netflix.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">1. Install Zookeeper </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> 3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>1. Install Zookeeper</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_pr01.html" title=""><link rel="next" href="multi_spring-cloud-zookeeper-discovery.html" title="2. Service Discovery with Zookeeper"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">1. Install Zookeeper</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_pr01.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-discovery.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-install" href="#spring-cloud-zookeeper-install"></a>1. Install Zookeeper</h1></div></div></div><p>See the <a class="link" href="https://zookeeper.apache.org/doc/current/zookeeperStarted.html" target="_top">installation
|
||||
documentation</a> for instructions on how to install Zookeeper.</p><p>Spring Cloud Zookeeper uses Apache Curator behind the scenes.
|
||||
While Zookeeper 3.5.x is still considered "beta" by the Zookeeper development team,
|
||||
the reality is that it is used in production by many users.
|
||||
However, Zookeeper 3.4.x is also used in production.
|
||||
Prior to Apache Curator 4.0, both versions of Zookeeper were supported via two versions of Apache Curator.
|
||||
Starting with Curator 4.0 both versions of Zookeeper are supported via the same Curator libraries.</p><p>In case you are integrating with version 3.4 you need to change the Zookeeper dependency
|
||||
that comes shipped with <code class="literal">curator</code>, and thus <code class="literal">spring-cloud-zookeeper</code>.
|
||||
To do so simply exclude that dependency and add the 3.4.x version like shown below.</p><p><b>maven. </b>
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-starter-zookeeper-all<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.apache.zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.apache.zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>3.4.12<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.slf4j<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>slf4j-log4j12<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span></pre><p>
|
||||
</p><p><b>gradle. </b>
|
||||
</p><pre class="programlisting">compile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.springframework.cloud:spring-cloud-starter-zookeeper-all'</span>) {
|
||||
exclude group: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.apache.zookeeper'</span>, module: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'zookeeper'</span>
|
||||
}
|
||||
compile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.apache.zookeeper:zookeeper:3.4.12'</span>) {
|
||||
exclude group: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.slf4j'</span>, module: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'slf4j-log4j12'</span>
|
||||
}</pre><p>
|
||||
</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_pr01.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-discovery.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> 2. Service Discovery with Zookeeper</td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_spring-cloud-zookeeper-discovery.html" title="2. Service Discovery with Zookeeper"><link rel="next" href="multi_spring-cloud-zookeeper-service-registry.html" title="4. Spring Cloud Zookeeper and Service Registry"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-discovery.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-service-registry.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-netflix" href="#spring-cloud-zookeeper-netflix"></a>3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</h1></div></div></div><p>Spring Cloud Netflix supplies useful tools that work regardless of which <code class="literal">DiscoveryClient</code>
|
||||
implementation you use. Feign, Turbine, Ribbon, and Zuul all work with Spring Cloud
|
||||
Zookeeper.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_ribbon_with_zookeeper" href="#_ribbon_with_zookeeper"></a>3.1 Ribbon with Zookeeper</h2></div></div></div><p>Spring Cloud Zookeeper provides an implementation of Ribbon’s <code class="literal">ServerList</code>. When you use
|
||||
the <code class="literal">spring-cloud-starter-zookeeper-discovery</code>, Ribbon is autoconfigured to use the
|
||||
<code class="literal">ZookeeperServerList</code> by default.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-discovery.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-service-registry.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2. Service Discovery with Zookeeper </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> 4. Spring Cloud Zookeeper and Service Registry</td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>4. Spring Cloud Zookeeper and Service Registry</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="up" href="multi_spring-cloud-zookeeper.html" title="Spring Cloud Zookeeper"><link rel="prev" href="multi_spring-cloud-zookeeper-netflix.html" title="3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components"><link rel="next" href="multi_spring-cloud-zookeeper-dependencies.html" title="5. Zookeeper Dependencies"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">4. Spring Cloud Zookeeper and Service Registry</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-netflix.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-dependencies.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-service-registry" href="#spring-cloud-zookeeper-service-registry"></a>4. Spring Cloud Zookeeper and Service Registry</h1></div></div></div><p>Spring Cloud Zookeeper implements the <code class="literal">ServiceRegistry</code> interface, letting developers
|
||||
register arbitrary services in a programmatic way.</p><p>The <code class="literal">ServiceInstanceRegistration</code> class offers a <code class="literal">builder()</code> method to create a
|
||||
<code class="literal">Registration</code> object that can be used by the <code class="literal">ServiceRegistry</code>, as shown in the following
|
||||
example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@Autowired</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> ZookeeperServiceRegistry serviceRegistry;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> registerThings() {
|
||||
ZookeeperRegistration registration = ServiceInstanceRegistration.builder()
|
||||
.defaultUriSpec()
|
||||
.address(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"anyUrl"</span>)
|
||||
.port(<xslthl:number xmlns:xslthl="http://xslthl.sourceforge.net/">10</xslthl:number>)
|
||||
.name(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/a/b/c/d/anotherservice"</span>)
|
||||
.build();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.serviceRegistry.register(registration);
|
||||
}</pre><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_instance_status" href="#_instance_status"></a>4.1 Instance Status</h2></div></div></div><p>Netflix Eureka supports having instances that are <code class="literal">OUT_OF_SERVICE</code> registered with the
|
||||
server. These instances are not returned as active service instances. This is useful for
|
||||
behaviors such as blue/green deployments. (Note that the Curator Service Discovery recipe
|
||||
does not support this behavior.) Taking advantage of the flexible payload has let Spring
|
||||
Cloud Zookeeper implement <code class="literal">OUT_OF_SERVICE</code> by updating some specific metadata and then
|
||||
filtering on that metadata in the Ribbon <code class="literal">ZookeeperServerList</code>. The <code class="literal">ZookeeperServerList</code>
|
||||
filters out all non-null instance statuses that do not equal <code class="literal">UP</code>. If the instance status
|
||||
field is empty, it is considered to be <code class="literal">UP</code> for backwards compatibility. To change the
|
||||
status of an instance, make a <code class="literal">POST</code> with <code class="literal">OUT_OF_SERVICE</code> to the <code class="literal">ServiceRegistry</code>
|
||||
instance status actuator endpoint, as shown in the following example:</p><pre class="programlisting">$ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The preceding example uses the <code class="literal">http</code> command from <a class="link" href="https://httpie.org" target="_top">https://httpie.org</a>.</p></td></tr></table></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-zookeeper-netflix.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_spring-cloud-zookeeper-dependencies.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-zookeeper.html">Home</a></td><td width="40%" align="right" valign="top"> 5. Zookeeper Dependencies</td></tr></table></div></body></html>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
342
spring-cloud-zookeeper/2.1.4.RELEASE/single/css/manual.css
Normal file
@@ -0,0 +1,342 @@
|
||||
@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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 353 B |
|
After Width: | Height: | Size: 350 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/single/images/caution.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/single/images/important.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/single/images/logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/single/images/note.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/single/images/tip.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
spring-cloud-zookeeper/2.1.4.RELEASE/single/images/warning.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,282 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Spring Cloud Zookeeper</title><link rel="stylesheet" type="text/css" href="css/manual-singlepage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div lang="en" class="book"><div class="titlepage"><div><div><h1 class="title"><a name="d0e3"></a>Spring Cloud Zookeeper</h1></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="preface"><a href="#d0e9"></a></span></dt><dt><span class="chapter"><a href="#spring-cloud-zookeeper-install">1. Install Zookeeper</a></span></dt><dt><span class="chapter"><a href="#spring-cloud-zookeeper-discovery">2. Service Discovery with Zookeeper</a></span></dt><dd><dl><dt><span class="section"><a href="#_activating">2.1. Activating</a></span></dt><dt><span class="section"><a href="#_registering_with_zookeeper">2.2. Registering with Zookeeper</a></span></dt><dt><span class="section"><a href="#_using_the_discoveryclient">2.3. Using the DiscoveryClient</a></span></dt></dl></dd><dt><span class="chapter"><a href="#spring-cloud-zookeeper-netflix">3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</a></span></dt><dd><dl><dt><span class="section"><a href="#_ribbon_with_zookeeper">3.1. Ribbon with Zookeeper</a></span></dt></dl></dd><dt><span class="chapter"><a href="#spring-cloud-zookeeper-service-registry">4. Spring Cloud Zookeeper and Service Registry</a></span></dt><dd><dl><dt><span class="section"><a href="#_instance_status">4.1. Instance Status</a></span></dt></dl></dd><dt><span class="chapter"><a href="#spring-cloud-zookeeper-dependencies">5. Zookeeper Dependencies</a></span></dt><dd><dl><dt><span class="section"><a href="#spring-cloud-zookeeper-dependencies-using">5.1. Using the Zookeeper Dependencies</a></span></dt><dt><span class="section"><a href="#spring-cloud-zookeeper-dependencies-activating">5.2. Activating Zookeeper Dependencies</a></span></dt><dt><span class="section"><a href="#spring-cloud-zookeeper-dependencies-setting-up">5.3. Setting up Zookeeper Dependencies</a></span></dt><dd><dl><dt><span class="section"><a href="#spring-cloud-zookeeper-dependencies-setting-up-aliases">5.3.1. Aliases</a></span></dt><dt><span class="section"><a href="#_path">5.3.2. Path</a></span></dt><dt><span class="section"><a href="#_load_balancer_type">5.3.3. Load Balancer Type</a></span></dt><dt><span class="section"><a href="#_content_type_template_and_version">5.3.4. <code class="literal">Content-Type</code> Template and Version</a></span></dt><dt><span class="section"><a href="#_default_headers">5.3.5. Default Headers</a></span></dt><dt><span class="section"><a href="#_required_dependencies">5.3.6. Required Dependencies</a></span></dt><dt><span class="section"><a href="#_stubs">5.3.7. Stubs</a></span></dt></dl></dd><dt><span class="section"><a href="#spring-cloud-zookeeper-dependencies-configuring">5.4. Configuring Spring Cloud Zookeeper Dependencies</a></span></dt></dl></dd><dt><span class="chapter"><a href="#spring-cloud-zookeeper-dependency-watcher">6. Spring Cloud Zookeeper Dependency Watcher</a></span></dt><dd><dl><dt><span class="section"><a href="#_activating_2">6.1. Activating</a></span></dt><dt><span class="section"><a href="#_registering_a_listener">6.2. Registering a Listener</a></span></dt><dt><span class="section"><a href="#spring-cloud-zookeeper-dependency-watcher-presence-checker">6.3. Using the Presence Checker</a></span></dt></dl></dd><dt><span class="chapter"><a href="#spring-cloud-zookeeper-config">7. Distributed Configuration with Zookeeper</a></span></dt><dd><dl><dt><span class="section"><a href="#_activating_3">7.1. Activating</a></span></dt><dt><span class="section"><a href="#_customizing">7.2. Customizing</a></span></dt><dt><span class="section"><a href="#_access_control_lists_acls">7.3. Access Control Lists (ACLs)</a></span></dt></dl></dd></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a name="d0e9" href="#d0e9"></a></h1></div></div></div><p>This project provides Zookeeper integrations for Spring Boot applications through
|
||||
autoconfiguration and binding to the Spring Environment and other Spring programming model
|
||||
idioms. With a few annotations, you can quickly enable and configure the common patterns
|
||||
inside your application and build large distributed systems with Zookeeper based
|
||||
components. The provided patterns include Service Discovery and Configuration. Integration
|
||||
with Spring Cloud Netflix provides Intelligent Routing (Zuul), Client Side Load Balancing
|
||||
(Ribbon), and Circuit Breaker (Hystrix).</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-install" href="#spring-cloud-zookeeper-install"></a>1. Install Zookeeper</h1></div></div></div><p>See the <a class="link" href="https://zookeeper.apache.org/doc/current/zookeeperStarted.html" target="_top">installation
|
||||
documentation</a> for instructions on how to install Zookeeper.</p><p>Spring Cloud Zookeeper uses Apache Curator behind the scenes.
|
||||
While Zookeeper 3.5.x is still considered "beta" by the Zookeeper development team,
|
||||
the reality is that it is used in production by many users.
|
||||
However, Zookeeper 3.4.x is also used in production.
|
||||
Prior to Apache Curator 4.0, both versions of Zookeeper were supported via two versions of Apache Curator.
|
||||
Starting with Curator 4.0 both versions of Zookeeper are supported via the same Curator libraries.</p><p>In case you are integrating with version 3.4 you need to change the Zookeeper dependency
|
||||
that comes shipped with <code class="literal">curator</code>, and thus <code class="literal">spring-cloud-zookeeper</code>.
|
||||
To do so simply exclude that dependency and add the 3.4.x version like shown below.</p><p><b>maven. </b>
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-starter-zookeeper-all<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.apache.zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.apache.zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>zookeeper<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>3.4.12<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.slf4j<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>slf4j-log4j12<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusion></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></exclusions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span></pre><p>
|
||||
</p><p><b>gradle. </b>
|
||||
</p><pre class="programlisting">compile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.springframework.cloud:spring-cloud-starter-zookeeper-all'</span>) {
|
||||
exclude group: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.apache.zookeeper'</span>, module: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'zookeeper'</span>
|
||||
}
|
||||
compile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.apache.zookeeper:zookeeper:3.4.12'</span>) {
|
||||
exclude group: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'org.slf4j'</span>, module: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'slf4j-log4j12'</span>
|
||||
}</pre><p>
|
||||
</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-discovery" href="#spring-cloud-zookeeper-discovery"></a>2. Service Discovery with Zookeeper</h1></div></div></div><p>Service Discovery is one of the key tenets of a microservice based architecture. Trying to
|
||||
hand-configure each client or some form of convention can be difficult to do and can be
|
||||
brittle. <a class="link" href="https://curator.apache.org" target="_top">Curator</a>(A Java library for Zookeeper) provides Service
|
||||
Discovery through a <a class="link" href="https://curator.apache.org/curator-x-discovery/" target="_top">Service Discovery
|
||||
Extension</a>. Spring Cloud Zookeeper uses this extension for service registration and
|
||||
discovery.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_activating" href="#_activating"></a>2.1 Activating</h2></div></div></div><p>Including a dependency on
|
||||
<code class="literal">org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</code> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Discovery.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>For web functionality, you still need to include
|
||||
<code class="literal">org.springframework.boot:spring-boot-starter-web</code>.</p></td></tr></table></div><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>When working with version 3.4 of Zookeeper you need to change
|
||||
the way you include the dependency as described <a class="link" href="#spring-cloud-zookeeper-install" title="1. Install Zookeeper">here</a>.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_registering_with_zookeeper" href="#_registering_with_zookeeper"></a>2.2 Registering with Zookeeper</h2></div></div></div><p>When a client registers with Zookeeper, it provides metadata (such as host and port, ID,
|
||||
and name) about itself.</p><p>The following example shows a Zookeeper client:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@SpringBootApplication</xslthl:annotation>
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@RestController</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> Application {
|
||||
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@RequestMapping("/")</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String home() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello world"</span>;
|
||||
}
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> main(String[] args) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> SpringApplicationBuilder(Application.<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span>).web(true).run(args);
|
||||
}
|
||||
|
||||
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The preceding example is a normal Spring Boot application.</p></td></tr></table></div><p>If Zookeeper is located somewhere other than <code class="literal">localhost:2181</code>, the configuration must
|
||||
provide the location of the server, as shown in the following example:</p><p><b>application.yml. </b>
|
||||
</p><pre class="programlisting">spring:
|
||||
cloud:
|
||||
zookeeper:
|
||||
connect-string: localhost:2181</pre><p>
|
||||
</p><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>If you use <a class="link" href="#spring-cloud-zookeeper-config" title="7. Distributed Configuration with Zookeeper">Spring Cloud Zookeeper Config</a>, the
|
||||
values shown in the preceding example need to be in <code class="literal">bootstrap.yml</code> instead of
|
||||
<code class="literal">application.yml</code>.</p></td></tr></table></div><p>The default service name, instance ID, and port (taken from the <code class="literal">Environment</code>) are
|
||||
<code class="literal">${spring.application.name}</code>, the Spring Context ID, and <code class="literal">${server.port}</code>, respectively.</p><p>Having <code class="literal">spring-cloud-starter-zookeeper-discovery</code> on the classpath makes the app into both
|
||||
a Zookeeper <span class="quote">“<span class="quote">service</span>”</span> (that is, it registers itself) and a <span class="quote">“<span class="quote">client</span>”</span> (that is, it can
|
||||
query Zookeeper to locate other services).</p><p>If you would like to disable the Zookeeper Discovery Client, you can set
|
||||
<code class="literal">spring.cloud.zookeeper.discovery.enabled</code> to <code class="literal">false</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_the_discoveryclient" href="#_using_the_discoveryclient"></a>2.3 Using the DiscoveryClient</h2></div></div></div><p>Spring Cloud has support for
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign" target="_top">Feign</a>
|
||||
(a REST client builder) and
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon" target="_top">Spring
|
||||
<code class="literal">RestTemplate</code></a>, using logical service names instead of physical URLs.</p><p>You can also use the <code class="literal">org.springframework.cloud.client.discovery.DiscoveryClient</code>, which
|
||||
provides a simple API for discovery clients that is not specific to Netflix, as shown in
|
||||
the following example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@Autowired</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> DiscoveryClient discoveryClient;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String serviceUrl() {
|
||||
List<ServiceInstance> list = discoveryClient.getInstances(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"STORES"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">if</span> (list != null && list.size() > <xslthl:number xmlns:xslthl="http://xslthl.sourceforge.net/">0</xslthl:number> ) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> list.get(<xslthl:number xmlns:xslthl="http://xslthl.sourceforge.net/">0</xslthl:number>).getUri().toString();
|
||||
}
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> null;
|
||||
}</pre></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-netflix" href="#spring-cloud-zookeeper-netflix"></a>3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</h1></div></div></div><p>Spring Cloud Netflix supplies useful tools that work regardless of which <code class="literal">DiscoveryClient</code>
|
||||
implementation you use. Feign, Turbine, Ribbon, and Zuul all work with Spring Cloud
|
||||
Zookeeper.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_ribbon_with_zookeeper" href="#_ribbon_with_zookeeper"></a>3.1 Ribbon with Zookeeper</h2></div></div></div><p>Spring Cloud Zookeeper provides an implementation of Ribbon’s <code class="literal">ServerList</code>. When you use
|
||||
the <code class="literal">spring-cloud-starter-zookeeper-discovery</code>, Ribbon is autoconfigured to use the
|
||||
<code class="literal">ZookeeperServerList</code> by default.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-service-registry" href="#spring-cloud-zookeeper-service-registry"></a>4. Spring Cloud Zookeeper and Service Registry</h1></div></div></div><p>Spring Cloud Zookeeper implements the <code class="literal">ServiceRegistry</code> interface, letting developers
|
||||
register arbitrary services in a programmatic way.</p><p>The <code class="literal">ServiceInstanceRegistration</code> class offers a <code class="literal">builder()</code> method to create a
|
||||
<code class="literal">Registration</code> object that can be used by the <code class="literal">ServiceRegistry</code>, as shown in the following
|
||||
example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@Autowired</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> ZookeeperServiceRegistry serviceRegistry;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> registerThings() {
|
||||
ZookeeperRegistration registration = ServiceInstanceRegistration.builder()
|
||||
.defaultUriSpec()
|
||||
.address(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"anyUrl"</span>)
|
||||
.port(<xslthl:number xmlns:xslthl="http://xslthl.sourceforge.net/">10</xslthl:number>)
|
||||
.name(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/a/b/c/d/anotherservice"</span>)
|
||||
.build();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.serviceRegistry.register(registration);
|
||||
}</pre><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_instance_status" href="#_instance_status"></a>4.1 Instance Status</h2></div></div></div><p>Netflix Eureka supports having instances that are <code class="literal">OUT_OF_SERVICE</code> registered with the
|
||||
server. These instances are not returned as active service instances. This is useful for
|
||||
behaviors such as blue/green deployments. (Note that the Curator Service Discovery recipe
|
||||
does not support this behavior.) Taking advantage of the flexible payload has let Spring
|
||||
Cloud Zookeeper implement <code class="literal">OUT_OF_SERVICE</code> by updating some specific metadata and then
|
||||
filtering on that metadata in the Ribbon <code class="literal">ZookeeperServerList</code>. The <code class="literal">ZookeeperServerList</code>
|
||||
filters out all non-null instance statuses that do not equal <code class="literal">UP</code>. If the instance status
|
||||
field is empty, it is considered to be <code class="literal">UP</code> for backwards compatibility. To change the
|
||||
status of an instance, make a <code class="literal">POST</code> with <code class="literal">OUT_OF_SERVICE</code> to the <code class="literal">ServiceRegistry</code>
|
||||
instance status actuator endpoint, as shown in the following example:</p><pre class="programlisting">$ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The preceding example uses the <code class="literal">http</code> command from <a class="link" href="https://httpie.org" target="_top">https://httpie.org</a>.</p></td></tr></table></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-dependencies" href="#spring-cloud-zookeeper-dependencies"></a>5. Zookeeper Dependencies</h1></div></div></div><p>The following topics cover how to work with Spring Cloud Zookeeper dependencies:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="xref" href="#spring-cloud-zookeeper-dependencies-using" title="5.1 Using the Zookeeper Dependencies">Section 5.1, “Using the Zookeeper Dependencies”</a></li><li class="listitem"><a class="xref" href="#spring-cloud-zookeeper-dependencies-activating" title="5.2 Activating Zookeeper Dependencies">Section 5.2, “Activating Zookeeper Dependencies”</a></li><li class="listitem"><a class="xref" href="#spring-cloud-zookeeper-dependencies-setting-up" title="5.3 Setting up Zookeeper Dependencies">Section 5.3, “Setting up Zookeeper Dependencies”</a></li><li class="listitem"><a class="xref" href="#spring-cloud-zookeeper-dependencies-configuring" title="5.4 Configuring Spring Cloud Zookeeper Dependencies">Section 5.4, “Configuring Spring Cloud Zookeeper Dependencies”</a></li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-using" href="#spring-cloud-zookeeper-dependencies-using"></a>5.1 Using the Zookeeper Dependencies</h2></div></div></div><p>Spring Cloud Zookeeper gives you a possibility to provide dependencies of your application
|
||||
as properties. As dependencies, you can understand other applications that are registered
|
||||
in Zookeeper and which you would like to call through
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign" target="_top">Feign</a>
|
||||
(a REST client builder) and <a class="link" href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon" target="_top">Spring <code class="literal">RestTemplate</code></a>.</p><p>You can also use the Zookeeper Dependency Watchers functionality to control and monitor
|
||||
the state of your dependencies.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-activating" href="#spring-cloud-zookeeper-dependencies-activating"></a>5.2 Activating Zookeeper Dependencies</h2></div></div></div><p>Including a dependency on
|
||||
<code class="literal">org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</code> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Dependencies. Even if you provide
|
||||
the dependencies in your properties, you can turn off the dependencies. To do so, set the
|
||||
<code class="literal">spring.cloud.zookeeper.dependency.enabled</code> property to false (it defaults to <code class="literal">true</code>).</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-setting-up" href="#spring-cloud-zookeeper-dependencies-setting-up"></a>5.3 Setting up Zookeeper Dependencies</h2></div></div></div><p>Consider the following example of dependency representation:</p><p><b>application.yml. </b>
|
||||
</p><pre class="programlisting">spring.application.name: yourServiceName
|
||||
spring.cloud.zookeeper:
|
||||
dependencies:
|
||||
newsletter:
|
||||
path: /path/where/newsletter/has/registered/in/zookeeper
|
||||
loadBalancerType: ROUND_ROBIN
|
||||
contentTypeTemplate: application/vnd.newsletter.$version+json
|
||||
version: v1
|
||||
headers:
|
||||
header1:
|
||||
- value1
|
||||
header2:
|
||||
- value2
|
||||
required: false
|
||||
stubs: org.springframework:foo:stubs
|
||||
mailing:
|
||||
path: /path/where/mailing/has/registered/in/zookeeper
|
||||
loadBalancerType: ROUND_ROBIN
|
||||
contentTypeTemplate: application/vnd.mailing.$version+json
|
||||
version: v1
|
||||
required: true</pre><p>
|
||||
</p><p>The next few sections go through each part of the dependency one by one. The root property
|
||||
name is <code class="literal">spring.cloud.zookeeper.dependencies</code>.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spring-cloud-zookeeper-dependencies-setting-up-aliases" href="#spring-cloud-zookeeper-dependencies-setting-up-aliases"></a>5.3.1 Aliases</h3></div></div></div><p>Below the root property you have to represent each dependency as an alias. This is due to
|
||||
the constraints of Ribbon, which requires that the application ID be placed in the URL.
|
||||
Consequently, you cannot pass any complex path, suchas <code class="literal">/myApp/myRoute/name</code>). The alias
|
||||
is the name you use instead of the <code class="literal">serviceId</code> for <code class="literal">DiscoveryClient</code>, <code class="literal">Feign</code>, or
|
||||
<code class="literal">RestTemplate</code>.</p><p>In the previous examples, the aliases are <code class="literal">newsletter</code> and <code class="literal">mailing</code>. The following
|
||||
example shows Feign usage with a <code class="literal">newsletter</code> alias:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@FeignClient("newsletter")</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">interface</span> NewsletterService {
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@RequestMapping(method = RequestMethod.GET, value = "/newsletter")</xslthl:annotation>
|
||||
String getNewsletters();
|
||||
}</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_path" href="#_path"></a>5.3.2 Path</h3></div></div></div><p>The path is represented by the <code class="literal">path</code> YAML property and is the path under which the
|
||||
dependency is registered under Zookeeper. As described in the
|
||||
<a class="link" href="#spring-cloud-zookeeper-dependencies-setting-up-aliases" title="5.3.1 Aliases">previous section</a>, Ribbon
|
||||
operates on URLs. As a result, this path is not compliant with its requirement.
|
||||
That is why Spring Cloud Zookeeper maps the alias to the proper path.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_load_balancer_type" href="#_load_balancer_type"></a>5.3.3 Load Balancer Type</h3></div></div></div><p>The load balancer type is represented by <code class="literal">loadBalancerType</code> YAML property.</p><p>If you know what kind of load-balancing strategy has to be applied when calling this
|
||||
particular dependency, you can provide it in the YAML file, and it is automatically
|
||||
applied. You can choose one of the following load balancing strategies:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">STICKY: Once chosen, the instance is always called.</li><li class="listitem">RANDOM: Picks an instance randomly.</li><li class="listitem">ROUND_ROBIN: Iterates over instances over and over again.</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_content_type_template_and_version" href="#_content_type_template_and_version"></a>5.3.4 <code class="literal">Content-Type</code> Template and Version</h3></div></div></div><p>The <code class="literal">Content-Type</code> template and version are represented by the <code class="literal">contentTypeTemplate</code> and
|
||||
<code class="literal">version</code> YAML properties.</p><p>If you version your API in the <code class="literal">Content-Type</code> header, you do not want to add this header
|
||||
to each of your requests. Also, if you want to call a new version of the API, you do not
|
||||
want to roam around your code to bump up the API version. That is why you can provide a
|
||||
<code class="literal">contentTypeTemplate</code> with a special <code class="literal">$version</code> placeholder. That placeholder will be filled by the value of the
|
||||
<code class="literal">version</code> YAML property. Consider the following example of a <code class="literal">contentTypeTemplate</code>:</p><pre class="screen">application/vnd.newsletter.$version+json</pre><p>Further consider the following <code class="literal">version</code>:</p><pre class="screen">v1</pre><p>The combination of <code class="literal">contentTypeTemplate</code> and version results in the creation of a
|
||||
<code class="literal">Content-Type</code> header for each request, as follows:</p><pre class="screen">application/vnd.newsletter.v1+json</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_default_headers" href="#_default_headers"></a>5.3.5 Default Headers</h3></div></div></div><p>Default headers are represented by the <code class="literal">headers</code> map in YAML.</p><p>Sometimes, each call to a dependency requires setting up of some default headers. To not
|
||||
do that in code, you can set them up in the YAML file, as shown in the following example
|
||||
<code class="literal">headers</code> section:</p><pre class="programlisting">headers:
|
||||
Accept:
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
Cache-Control:
|
||||
- no-cache</pre><p>That <code class="literal">headers</code> section results in adding the <code class="literal">Accept</code> and <code class="literal">Cache-Control</code> headers with
|
||||
appropriate list of values in your HTTP request.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_required_dependencies" href="#_required_dependencies"></a>5.3.6 Required Dependencies</h3></div></div></div><p>Required dependencies are represented by <code class="literal">required</code> property in YAML.</p><p>If one of your dependencies is required to be up when your application boots, you can set
|
||||
the <code class="literal">required: true</code> property in the YAML file.</p><p>If your application cannot localize the required dependency during boot time, it throws an
|
||||
exception, and the Spring Context fails to set up. In other words, your application cannot
|
||||
start if the required dependency is not registered in Zookeeper.</p><p>You can read more about Spring Cloud Zookeeper Presence Checker
|
||||
<a class="link" href="#spring-cloud-zookeeper-dependency-watcher-presence-checker" title="6.3 Using the Presence Checker">later in this document</a>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_stubs" href="#_stubs"></a>5.3.7 Stubs</h3></div></div></div><p>You can provide a colon-separated path to the JAR containing stubs of the dependency, as
|
||||
shown in the following example:</p><p><code class="literal">stubs: org.springframework:myApp:stubs</code></p><p>where:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">org.springframework</code> is the <code class="literal">groupId</code>.</li><li class="listitem"><code class="literal">myApp</code> is the <code class="literal">artifactId</code>.</li><li class="listitem"><code class="literal">stubs</code> is the classifier. (Note that <code class="literal">stubs</code> is the default value.)</li></ul></div><p>Because <code class="literal">stubs</code> is the default classifier, the preceding example is equal to the following
|
||||
example:</p><p><code class="literal">stubs: org.springframework:myApp</code></p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependencies-configuring" href="#spring-cloud-zookeeper-dependencies-configuring"></a>5.4 Configuring Spring Cloud Zookeeper Dependencies</h2></div></div></div><p>You can set the following properties to enable or disable parts of Zookeeper Dependencies
|
||||
functionalities:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependencies</code>: If you do not set this property, you cannot use
|
||||
Zookeeper Dependencies.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.ribbon.enabled</code> (enabled by default): Ribbon requires
|
||||
either explicit global configuration or a particular one for a dependency. By turning on
|
||||
this property, runtime load balancing strategy resolution is possible, and you can use the
|
||||
<code class="literal">loadBalancerType</code> section of the Zookeeper Dependencies. The configuration that needs
|
||||
this property has an implementation of <code class="literal">LoadBalancerClient</code> that delegates to the
|
||||
<code class="literal">ILoadBalancer</code> presented in the next bullet.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.ribbon.loadbalancer</code> (enabled by default): Thanks to
|
||||
this property, the custom <code class="literal">ILoadBalancer</code> knows that the part of the URI passed to Ribbon
|
||||
might actually be the alias that has to be resolved to a proper path in Zookeeper. Without
|
||||
this property, you cannot register applications under nested paths.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.headers.enabled</code> (enabled by default): This property
|
||||
registers a <code class="literal">RibbonClient</code> that automatically appends appropriate headers and content
|
||||
types with their versions, as presented in the Dependency configuration. Without this
|
||||
setting, those two parameters do not work.</li><li class="listitem"><code class="literal">spring.cloud.zookeeper.dependency.resttemplate.enabled</code> (enabled by default): When
|
||||
enabled, this property modifies the request headers of a <code class="literal">@LoadBalanced</code>-annotated
|
||||
<code class="literal">RestTemplate</code> such that it passes headers and content type with the version set in
|
||||
dependency configuration. Without this setting, those two parameters do not work.</li></ul></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-dependency-watcher" href="#spring-cloud-zookeeper-dependency-watcher"></a>6. Spring Cloud Zookeeper Dependency Watcher</h1></div></div></div><p>The Dependency Watcher mechanism lets you register listeners to your dependencies. The
|
||||
functionality is, in fact, an implementation of the <code class="literal">Observator</code> pattern. When a
|
||||
dependency changes, its state (to either UP or DOWN), some custom logic can be applied.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_activating_2" href="#_activating_2"></a>6.1 Activating</h2></div></div></div><p>Spring Cloud Zookeeper Dependencies functionality needs to be enabled for you to use the
|
||||
Dependency Watcher mechanism.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_registering_a_listener" href="#_registering_a_listener"></a>6.2 Registering a Listener</h2></div></div></div><p>To register a listener, you must implement an interface called
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.DependencyWatcherListener</code> and
|
||||
register it as a bean. The interface gives you one method:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> stateChanged(String dependencyName, DependencyState newState);</pre><p>If you want to register a listener for a particular dependency, the <code class="literal">dependencyName</code> would
|
||||
be the discriminator for your concrete implementation. <code class="literal">newState</code> provides you with
|
||||
information about whether your dependency has changed to <code class="literal">CONNECTED</code> or <code class="literal">DISCONNECTED</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spring-cloud-zookeeper-dependency-watcher-presence-checker" href="#spring-cloud-zookeeper-dependency-watcher-presence-checker"></a>6.3 Using the Presence Checker</h2></div></div></div><p>Bound with the Dependency Watcher is the functionality called Presence Checker. It lets
|
||||
you provide custom behavior when your application boots, to react according to the state
|
||||
of your dependencies.</p><p>The default implementation of the abstract
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.presence.DependencyPresenceOnStartupVerifier</code>
|
||||
class is the
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.presence.DefaultDependencyPresenceOnStartupVerifier</code>,
|
||||
which works in the following way.</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">If the dependency is marked us <code class="literal">required</code> and is not in Zookeeper, when your application
|
||||
boots, it throws an exception and shuts down.</li><li class="listitem">If the dependency is not <code class="literal">required</code>, the
|
||||
<code class="literal">org.springframework.cloud.zookeeper.discovery.watcher.presence.LogMissingDependencyChecker</code>
|
||||
logs that the dependency is missing at the <code class="literal">WARN</code> level.</li></ol></div><p>Because the <code class="literal">DefaultDependencyPresenceOnStartupVerifier</code> is registered only when there is
|
||||
no bean of type <code class="literal">DependencyPresenceOnStartupVerifier</code>, this functionality can be
|
||||
overridden.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="spring-cloud-zookeeper-config" href="#spring-cloud-zookeeper-config"></a>7. Distributed Configuration with Zookeeper</h1></div></div></div><p>Zookeeper provides a
|
||||
<a class="link" href="https://zookeeper.apache.org/doc/current/zookeeperOver.html#sc_dataModelNameSpace" target="_top">hierarchical namespace</a>
|
||||
that lets clients store arbitrary data, such as configuration data. Spring Cloud Zookeeper
|
||||
Config is an alternative to the
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-config" target="_top">Config Server and Client</a>.
|
||||
Configuration is loaded into the Spring Environment during the special <span class="quote">“<span class="quote">bootstrap</span>”</span>
|
||||
phase. Configuration is stored in the <code class="literal">/config</code> namespace by default. Multiple
|
||||
<code class="literal">PropertySource</code> instances are created, based on the application’s name and the active
|
||||
profiles, to mimic the Spring Cloud Config order of resolving properties. For example, an
|
||||
application with a name of <code class="literal">testApp</code> and with the <code class="literal">dev</code> profile has the following property
|
||||
sources created for it:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">config/testApp,dev</code></li><li class="listitem"><code class="literal">config/testApp</code></li><li class="listitem"><code class="literal">config/application,dev</code></li><li class="listitem"><code class="literal">config/application</code></li></ul></div><p>The most specific property source is at the top, with the least specific at the bottom.
|
||||
Properties in the <code class="literal">config/application</code> namespace apply to all applications that use
|
||||
zookeeper for configuration. Properties in the <code class="literal">config/testApp</code> namespace are available
|
||||
only to the instances of the service named <code class="literal">testApp</code>.</p><p>Configuration is currently read on startup of the application. Sending a HTTP <code class="literal">POST</code>
|
||||
request to <code class="literal">/refresh</code> causes the configuration to be reloaded. Watching the configuration
|
||||
namespace (which Zookeeper supports) is not currently implemented.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_activating_3" href="#_activating_3"></a>7.1 Activating</h2></div></div></div><p>Including a dependency on
|
||||
<code class="literal">org.springframework.cloud:spring-cloud-starter-zookeeper-config</code> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Config.</p><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Caution"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td><th align="left">Caution</th></tr><tr><td align="left" valign="top"><p>When working with version 3.4 of Zookeeper you need to change
|
||||
the way you include the dependency as described <a class="link" href="#spring-cloud-zookeeper-install" title="1. Install Zookeeper">here</a>.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_customizing" href="#_customizing"></a>7.2 Customizing</h2></div></div></div><p>Zookeeper Config may be customized by setting the following properties:</p><p><b>bootstrap.yml. </b>
|
||||
</p><pre class="programlisting">spring:
|
||||
cloud:
|
||||
zookeeper:
|
||||
config:
|
||||
enabled: true
|
||||
root: configuration
|
||||
defaultContext: apps
|
||||
profileSeparator: '::'</pre><p>
|
||||
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">enabled</code>: Setting this value to <code class="literal">false</code> disables Zookeeper Config.</li><li class="listitem"><code class="literal">root</code>: Sets the base namespace for configuration values.</li><li class="listitem"><code class="literal">defaultContext</code>: Sets the name used by all applications.</li><li class="listitem"><code class="literal">profileSeparator</code>: Sets the value of the separator used to separate the profile name in
|
||||
property sources with profiles.</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_access_control_lists_acls" href="#_access_control_lists_acls"></a>7.3 Access Control Lists (ACLs)</h2></div></div></div><p>You can add authentication information for Zookeeper ACLs by calling the <code class="literal">addAuthInfo</code>
|
||||
method of a <code class="literal">CuratorFramework</code> bean. One way to accomplish this is to provide your own
|
||||
<code class="literal">CuratorFramework</code> bean, as shown in the following example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@BoostrapConfiguration</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomCuratorFrameworkConfig {
|
||||
|
||||
<xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@Bean</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> CuratorFramework curatorFramework() {
|
||||
CuratorFramework curator = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CuratorFramework();
|
||||
curator.addAuthInfo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"digest"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"user:password"</span>.getBytes());
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> curator;
|
||||
}
|
||||
|
||||
}</pre><p>Consult
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-zookeeper/blob/master/spring-cloud-zookeeper-core/src/main/java/org/springframework/cloud/zookeeper/ZookeeperAutoConfiguration.java" target="_top">the ZookeeperAutoConfiguration class</a>
|
||||
to see how the <code class="literal">CuratorFramework</code> bean’s default configuration.</p><p>Alternatively, you can add your credentials from a class that depends on the existing
|
||||
<code class="literal">CuratorFramework</code> bean, as shown in the following example:</p><pre class="programlisting"><xslthl:annotation xmlns:xslthl="http://xslthl.sourceforge.net/">@BoostrapConfiguration</xslthl:annotation>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> DefaultCuratorFrameworkConfig {
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> ZookeeperConfig(CuratorFramework curator) {
|
||||
curator.addAuthInfo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"digest"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"user:password"</span>.getBytes());
|
||||
}
|
||||
|
||||
}</pre><p>The creation of this bean must occur during the boostrapping phase. You can register
|
||||
configuration classes to run during this phase by annotating them with
|
||||
<code class="literal">@BootstrapConfiguration</code> and including them in a comma-separated list that you set as the
|
||||
value of the <code class="literal">org.springframework.cloud.bootstrap.BootstrapConfiguration</code> property in the
|
||||
<code class="literal">resources/META-INF/spring.factories</code> file, as shown in the following example:</p><p><b>resources/META-INF/spring.factories. </b>
|
||||
</p><pre class="screen">org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
my.project.CustomCuratorFrameworkConfig,\
|
||||
my.project.DefaultCuratorFrameworkConfig</pre><p>
|
||||
</p></div></div></div></body></html>
|
||||
117
spring-cloud-zookeeper/2.1.4.RELEASE/spring-cloud-zookeeper.html
Normal file
@@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>spring-cloud-zookeeper</title>
|
||||
<link rel="stylesheet" href="css/manual-singlepage.css">
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="article">
|
||||
<div id="header">
|
||||
<h1>spring-cloud-zookeeper</h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="preamble">
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>2.1.4.RELEASE</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_pick_the_documentation_option">Pick The Documentation Option</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="single/spring-cloud-zookeeper.html">Single HTML</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="multi/multi_spring-cloud-zookeeper.html">Multi HTML</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js"></script>
|
||||
<script>prettyPrint()</script>
|
||||
</body>
|
||||
</html>
|
||||
584
spring-cloud-zookeeper/2.1.4.RELEASE/spring-cloud-zookeeper.xml
Normal file
@@ -0,0 +1,584 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?asciidoc-toc?>
|
||||
<?asciidoc-numbered?>
|
||||
<book xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
|
||||
<info>
|
||||
<title>Spring Cloud Zookeeper</title>
|
||||
<date>2019-11-18</date>
|
||||
</info>
|
||||
<preface>
|
||||
<title></title>
|
||||
<simpara>This project provides Zookeeper integrations for Spring Boot applications through
|
||||
autoconfiguration and binding to the Spring Environment and other Spring programming model
|
||||
idioms. With a few annotations, you can quickly enable and configure the common patterns
|
||||
inside your application and build large distributed systems with Zookeeper based
|
||||
components. The provided patterns include Service Discovery and Configuration. Integration
|
||||
with Spring Cloud Netflix provides Intelligent Routing (Zuul), Client Side Load Balancing
|
||||
(Ribbon), and Circuit Breaker (Hystrix).</simpara>
|
||||
</preface>
|
||||
<chapter xml:id="spring-cloud-zookeeper-install">
|
||||
<title>Install Zookeeper</title>
|
||||
<simpara>See the <link xl:href="https://zookeeper.apache.org/doc/current/zookeeperStarted.html">installation
|
||||
documentation</link> for instructions on how to install Zookeeper.</simpara>
|
||||
<simpara>Spring Cloud Zookeeper uses Apache Curator behind the scenes.
|
||||
While Zookeeper 3.5.x is still considered "beta" by the Zookeeper development team,
|
||||
the reality is that it is used in production by many users.
|
||||
However, Zookeeper 3.4.x is also used in production.
|
||||
Prior to Apache Curator 4.0, both versions of Zookeeper were supported via two versions of Apache Curator.
|
||||
Starting with Curator 4.0 both versions of Zookeeper are supported via the same Curator libraries.</simpara>
|
||||
<simpara>In case you are integrating with version 3.4 you need to change the Zookeeper dependency
|
||||
that comes shipped with <literal>curator</literal>, and thus <literal>spring-cloud-zookeeper</literal>.
|
||||
To do so simply exclude that dependency and add the 3.4.x version like shown below.</simpara>
|
||||
<formalpara>
|
||||
<title>maven</title>
|
||||
<para>
|
||||
<programlisting language="xml" linenumbering="unnumbered"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<version>3.4.12</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency></programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<formalpara>
|
||||
<title>gradle</title>
|
||||
<para>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">compile('org.springframework.cloud:spring-cloud-starter-zookeeper-all') {
|
||||
exclude group: 'org.apache.zookeeper', module: 'zookeeper'
|
||||
}
|
||||
compile('org.apache.zookeeper:zookeeper:3.4.12') {
|
||||
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
|
||||
}</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
</chapter>
|
||||
<chapter xml:id="spring-cloud-zookeeper-discovery">
|
||||
<title>Service Discovery with Zookeeper</title>
|
||||
<simpara>Service Discovery is one of the key tenets of a microservice based architecture. Trying to
|
||||
hand-configure each client or some form of convention can be difficult to do and can be
|
||||
brittle. <link xl:href="https://curator.apache.org">Curator</link>(A Java library for Zookeeper) provides Service
|
||||
Discovery through a <link xl:href="https://curator.apache.org/curator-x-discovery/">Service Discovery
|
||||
Extension</link>. Spring Cloud Zookeeper uses this extension for service registration and
|
||||
discovery.</simpara>
|
||||
<section xml:id="_activating">
|
||||
<title>Activating</title>
|
||||
<simpara>Including a dependency on
|
||||
<literal>org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</literal> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Discovery.</simpara>
|
||||
<note>
|
||||
<simpara>For web functionality, you still need to include
|
||||
<literal>org.springframework.boot:spring-boot-starter-web</literal>.</simpara>
|
||||
</note>
|
||||
<caution>
|
||||
<simpara>When working with version 3.4 of Zookeeper you need to change
|
||||
the way you include the dependency as described <link linkend="spring-cloud-zookeeper-install">here</link>.</simpara>
|
||||
</caution>
|
||||
</section>
|
||||
<section xml:id="_registering_with_zookeeper">
|
||||
<title>Registering with Zookeeper</title>
|
||||
<simpara>When a client registers with Zookeeper, it provides metadata (such as host and port, ID,
|
||||
and name) about itself.</simpara>
|
||||
<simpara>The following example shows a Zookeeper client:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">@SpringBootApplication
|
||||
@RestController
|
||||
public class Application {
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return "Hello world";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).web(true).run(args);
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
<note>
|
||||
<simpara>The preceding example is a normal Spring Boot application.</simpara>
|
||||
</note>
|
||||
<simpara>If Zookeeper is located somewhere other than <literal>localhost:2181</literal>, the configuration must
|
||||
provide the location of the server, as shown in the following example:</simpara>
|
||||
<formalpara>
|
||||
<title>application.yml</title>
|
||||
<para>
|
||||
<programlisting language="yml" linenumbering="unnumbered">spring:
|
||||
cloud:
|
||||
zookeeper:
|
||||
connect-string: localhost:2181</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<caution>
|
||||
<simpara>If you use <link linkend="spring-cloud-zookeeper-config">Spring Cloud Zookeeper Config</link>, the
|
||||
values shown in the preceding example need to be in <literal>bootstrap.yml</literal> instead of
|
||||
<literal>application.yml</literal>.</simpara>
|
||||
</caution>
|
||||
<simpara>The default service name, instance ID, and port (taken from the <literal>Environment</literal>) are
|
||||
<literal>${spring.application.name}</literal>, the Spring Context ID, and <literal>${server.port}</literal>, respectively.</simpara>
|
||||
<simpara>Having <literal>spring-cloud-starter-zookeeper-discovery</literal> on the classpath makes the app into both
|
||||
a Zookeeper <quote>service</quote> (that is, it registers itself) and a <quote>client</quote> (that is, it can
|
||||
query Zookeeper to locate other services).</simpara>
|
||||
<simpara>If you would like to disable the Zookeeper Discovery Client, you can set
|
||||
<literal>spring.cloud.zookeeper.discovery.enabled</literal> to <literal>false</literal>.</simpara>
|
||||
</section>
|
||||
<section xml:id="_using_the_discoveryclient">
|
||||
<title>Using the DiscoveryClient</title>
|
||||
<simpara>Spring Cloud has support for
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign">Feign</link>
|
||||
(a REST client builder) and
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon">Spring
|
||||
<literal>RestTemplate</literal></link>, using logical service names instead of physical URLs.</simpara>
|
||||
<simpara>You can also use the <literal>org.springframework.cloud.client.discovery.DiscoveryClient</literal>, which
|
||||
provides a simple API for discovery clients that is not specific to Netflix, as shown in
|
||||
the following example:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
public String serviceUrl() {
|
||||
List<ServiceInstance> list = discoveryClient.getInstances("STORES");
|
||||
if (list != null && list.size() > 0 ) {
|
||||
return list.get(0).getUri().toString();
|
||||
}
|
||||
return null;
|
||||
}</programlisting>
|
||||
</section>
|
||||
</chapter>
|
||||
<chapter xml:id="spring-cloud-zookeeper-netflix">
|
||||
<title>Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</title>
|
||||
<simpara>Spring Cloud Netflix supplies useful tools that work regardless of which <literal>DiscoveryClient</literal>
|
||||
implementation you use. Feign, Turbine, Ribbon, and Zuul all work with Spring Cloud
|
||||
Zookeeper.</simpara>
|
||||
<section xml:id="_ribbon_with_zookeeper">
|
||||
<title>Ribbon with Zookeeper</title>
|
||||
<simpara>Spring Cloud Zookeeper provides an implementation of Ribbon’s <literal>ServerList</literal>. When you use
|
||||
the <literal>spring-cloud-starter-zookeeper-discovery</literal>, Ribbon is autoconfigured to use the
|
||||
<literal>ZookeeperServerList</literal> by default.</simpara>
|
||||
</section>
|
||||
</chapter>
|
||||
<chapter xml:id="spring-cloud-zookeeper-service-registry">
|
||||
<title>Spring Cloud Zookeeper and Service Registry</title>
|
||||
<simpara>Spring Cloud Zookeeper implements the <literal>ServiceRegistry</literal> interface, letting developers
|
||||
register arbitrary services in a programmatic way.</simpara>
|
||||
<simpara>The <literal>ServiceInstanceRegistration</literal> class offers a <literal>builder()</literal> method to create a
|
||||
<literal>Registration</literal> object that can be used by the <literal>ServiceRegistry</literal>, as shown in the following
|
||||
example:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">@Autowired
|
||||
private ZookeeperServiceRegistry serviceRegistry;
|
||||
|
||||
public void registerThings() {
|
||||
ZookeeperRegistration registration = ServiceInstanceRegistration.builder()
|
||||
.defaultUriSpec()
|
||||
.address("anyUrl")
|
||||
.port(10)
|
||||
.name("/a/b/c/d/anotherservice")
|
||||
.build();
|
||||
this.serviceRegistry.register(registration);
|
||||
}</programlisting>
|
||||
<section xml:id="_instance_status">
|
||||
<title>Instance Status</title>
|
||||
<simpara>Netflix Eureka supports having instances that are <literal>OUT_OF_SERVICE</literal> registered with the
|
||||
server. These instances are not returned as active service instances. This is useful for
|
||||
behaviors such as blue/green deployments. (Note that the Curator Service Discovery recipe
|
||||
does not support this behavior.) Taking advantage of the flexible payload has let Spring
|
||||
Cloud Zookeeper implement <literal>OUT_OF_SERVICE</literal> by updating some specific metadata and then
|
||||
filtering on that metadata in the Ribbon <literal>ZookeeperServerList</literal>. The <literal>ZookeeperServerList</literal>
|
||||
filters out all non-null instance statuses that do not equal <literal>UP</literal>. If the instance status
|
||||
field is empty, it is considered to be <literal>UP</literal> for backwards compatibility. To change the
|
||||
status of an instance, make a <literal>POST</literal> with <literal>OUT_OF_SERVICE</literal> to the <literal>ServiceRegistry</literal>
|
||||
instance status actuator endpoint, as shown in the following example:</simpara>
|
||||
<programlisting language="sh" linenumbering="unnumbered">$ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE</programlisting>
|
||||
<note>
|
||||
<simpara>The preceding example uses the <literal>http</literal> command from <link xl:href="https://httpie.org">https://httpie.org</link>.</simpara>
|
||||
</note>
|
||||
</section>
|
||||
</chapter>
|
||||
<chapter xml:id="spring-cloud-zookeeper-dependencies">
|
||||
<title>Zookeeper Dependencies</title>
|
||||
<simpara>The following topics cover how to work with Spring Cloud Zookeeper dependencies:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><xref linkend="spring-cloud-zookeeper-dependencies-using"/></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><xref linkend="spring-cloud-zookeeper-dependencies-activating"/></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><xref linkend="spring-cloud-zookeeper-dependencies-setting-up"/></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><xref linkend="spring-cloud-zookeeper-dependencies-configuring"/></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<section xml:id="spring-cloud-zookeeper-dependencies-using">
|
||||
<title>Using the Zookeeper Dependencies</title>
|
||||
<simpara>Spring Cloud Zookeeper gives you a possibility to provide dependencies of your application
|
||||
as properties. As dependencies, you can understand other applications that are registered
|
||||
in Zookeeper and which you would like to call through
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign">Feign</link>
|
||||
(a REST client builder) and <link xl:href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon">Spring <literal>RestTemplate</literal></link>.</simpara>
|
||||
<simpara>You can also use the Zookeeper Dependency Watchers functionality to control and monitor
|
||||
the state of your dependencies.</simpara>
|
||||
</section>
|
||||
<section xml:id="spring-cloud-zookeeper-dependencies-activating">
|
||||
<title>Activating Zookeeper Dependencies</title>
|
||||
<simpara>Including a dependency on
|
||||
<literal>org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</literal> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Dependencies. Even if you provide
|
||||
the dependencies in your properties, you can turn off the dependencies. To do so, set the
|
||||
<literal>spring.cloud.zookeeper.dependency.enabled</literal> property to false (it defaults to <literal>true</literal>).</simpara>
|
||||
</section>
|
||||
<section xml:id="spring-cloud-zookeeper-dependencies-setting-up">
|
||||
<title>Setting up Zookeeper Dependencies</title>
|
||||
<simpara>Consider the following example of dependency representation:</simpara>
|
||||
<formalpara>
|
||||
<title>application.yml</title>
|
||||
<para>
|
||||
<programlisting language="yml" linenumbering="unnumbered">spring.application.name: yourServiceName
|
||||
spring.cloud.zookeeper:
|
||||
dependencies:
|
||||
newsletter:
|
||||
path: /path/where/newsletter/has/registered/in/zookeeper
|
||||
loadBalancerType: ROUND_ROBIN
|
||||
contentTypeTemplate: application/vnd.newsletter.$version+json
|
||||
version: v1
|
||||
headers:
|
||||
header1:
|
||||
- value1
|
||||
header2:
|
||||
- value2
|
||||
required: false
|
||||
stubs: org.springframework:foo:stubs
|
||||
mailing:
|
||||
path: /path/where/mailing/has/registered/in/zookeeper
|
||||
loadBalancerType: ROUND_ROBIN
|
||||
contentTypeTemplate: application/vnd.mailing.$version+json
|
||||
version: v1
|
||||
required: true</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<simpara>The next few sections go through each part of the dependency one by one. The root property
|
||||
name is <literal>spring.cloud.zookeeper.dependencies</literal>.</simpara>
|
||||
<section xml:id="spring-cloud-zookeeper-dependencies-setting-up-aliases">
|
||||
<title>Aliases</title>
|
||||
<simpara>Below the root property you have to represent each dependency as an alias. This is due to
|
||||
the constraints of Ribbon, which requires that the application ID be placed in the URL.
|
||||
Consequently, you cannot pass any complex path, suchas <literal>/myApp/myRoute/name</literal>). The alias
|
||||
is the name you use instead of the <literal>serviceId</literal> for <literal>DiscoveryClient</literal>, <literal>Feign</literal>, or
|
||||
<literal>RestTemplate</literal>.</simpara>
|
||||
<simpara>In the previous examples, the aliases are <literal>newsletter</literal> and <literal>mailing</literal>. The following
|
||||
example shows Feign usage with a <literal>newsletter</literal> alias:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">@FeignClient("newsletter")
|
||||
public interface NewsletterService {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/newsletter")
|
||||
String getNewsletters();
|
||||
}</programlisting>
|
||||
</section>
|
||||
<section xml:id="_path">
|
||||
<title>Path</title>
|
||||
<simpara>The path is represented by the <literal>path</literal> YAML property and is the path under which the
|
||||
dependency is registered under Zookeeper. As described in the
|
||||
<link linkend="spring-cloud-zookeeper-dependencies-setting-up-aliases">previous section</link>, Ribbon
|
||||
operates on URLs. As a result, this path is not compliant with its requirement.
|
||||
That is why Spring Cloud Zookeeper maps the alias to the proper path.</simpara>
|
||||
</section>
|
||||
<section xml:id="_load_balancer_type">
|
||||
<title>Load Balancer Type</title>
|
||||
<simpara>The load balancer type is represented by <literal>loadBalancerType</literal> YAML property.</simpara>
|
||||
<simpara>If you know what kind of load-balancing strategy has to be applied when calling this
|
||||
particular dependency, you can provide it in the YAML file, and it is automatically
|
||||
applied. You can choose one of the following load balancing strategies:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>STICKY: Once chosen, the instance is always called.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>RANDOM: Picks an instance randomly.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>ROUND_ROBIN: Iterates over instances over and over again.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="_content_type_template_and_version">
|
||||
<title><literal>Content-Type</literal> Template and Version</title>
|
||||
<simpara>The <literal>Content-Type</literal> template and version are represented by the <literal>contentTypeTemplate</literal> and
|
||||
<literal>version</literal> YAML properties.</simpara>
|
||||
<simpara>If you version your API in the <literal>Content-Type</literal> header, you do not want to add this header
|
||||
to each of your requests. Also, if you want to call a new version of the API, you do not
|
||||
want to roam around your code to bump up the API version. That is why you can provide a
|
||||
<literal>contentTypeTemplate</literal> with a special <literal>$version</literal> placeholder. That placeholder will be filled by the value of the
|
||||
<literal>version</literal> YAML property. Consider the following example of a <literal>contentTypeTemplate</literal>:</simpara>
|
||||
<screen>application/vnd.newsletter.$version+json</screen>
|
||||
<simpara>Further consider the following <literal>version</literal>:</simpara>
|
||||
<screen>v1</screen>
|
||||
<simpara>The combination of <literal>contentTypeTemplate</literal> and version results in the creation of a
|
||||
<literal>Content-Type</literal> header for each request, as follows:</simpara>
|
||||
<screen>application/vnd.newsletter.v1+json</screen>
|
||||
</section>
|
||||
<section xml:id="_default_headers">
|
||||
<title>Default Headers</title>
|
||||
<simpara>Default headers are represented by the <literal>headers</literal> map in YAML.</simpara>
|
||||
<simpara>Sometimes, each call to a dependency requires setting up of some default headers. To not
|
||||
do that in code, you can set them up in the YAML file, as shown in the following example
|
||||
<literal>headers</literal> section:</simpara>
|
||||
<programlisting language="yml" linenumbering="unnumbered">headers:
|
||||
Accept:
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
Cache-Control:
|
||||
- no-cache</programlisting>
|
||||
<simpara>That <literal>headers</literal> section results in adding the <literal>Accept</literal> and <literal>Cache-Control</literal> headers with
|
||||
appropriate list of values in your HTTP request.</simpara>
|
||||
</section>
|
||||
<section xml:id="_required_dependencies">
|
||||
<title>Required Dependencies</title>
|
||||
<simpara>Required dependencies are represented by <literal>required</literal> property in YAML.</simpara>
|
||||
<simpara>If one of your dependencies is required to be up when your application boots, you can set
|
||||
the <literal>required: true</literal> property in the YAML file.</simpara>
|
||||
<simpara>If your application cannot localize the required dependency during boot time, it throws an
|
||||
exception, and the Spring Context fails to set up. In other words, your application cannot
|
||||
start if the required dependency is not registered in Zookeeper.</simpara>
|
||||
<simpara>You can read more about Spring Cloud Zookeeper Presence Checker
|
||||
<link linkend="spring-cloud-zookeeper-dependency-watcher-presence-checker">later in this document</link>.</simpara>
|
||||
</section>
|
||||
<section xml:id="_stubs">
|
||||
<title>Stubs</title>
|
||||
<simpara>You can provide a colon-separated path to the JAR containing stubs of the dependency, as
|
||||
shown in the following example:</simpara>
|
||||
<simpara><literal>stubs: org.springframework:myApp:stubs</literal></simpara>
|
||||
<simpara>where:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><literal>org.springframework</literal> is the <literal>groupId</literal>.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>myApp</literal> is the <literal>artifactId</literal>.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>stubs</literal> is the classifier. (Note that <literal>stubs</literal> is the default value.)</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>Because <literal>stubs</literal> is the default classifier, the preceding example is equal to the following
|
||||
example:</simpara>
|
||||
<simpara><literal>stubs: org.springframework:myApp</literal></simpara>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="spring-cloud-zookeeper-dependencies-configuring">
|
||||
<title>Configuring Spring Cloud Zookeeper Dependencies</title>
|
||||
<simpara>You can set the following properties to enable or disable parts of Zookeeper Dependencies
|
||||
functionalities:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><literal>spring.cloud.zookeeper.dependencies</literal>: If you do not set this property, you cannot use
|
||||
Zookeeper Dependencies.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>spring.cloud.zookeeper.dependency.ribbon.enabled</literal> (enabled by default): Ribbon requires
|
||||
either explicit global configuration or a particular one for a dependency. By turning on
|
||||
this property, runtime load balancing strategy resolution is possible, and you can use the
|
||||
<literal>loadBalancerType</literal> section of the Zookeeper Dependencies. The configuration that needs
|
||||
this property has an implementation of <literal>LoadBalancerClient</literal> that delegates to the
|
||||
<literal>ILoadBalancer</literal> presented in the next bullet.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>spring.cloud.zookeeper.dependency.ribbon.loadbalancer</literal> (enabled by default): Thanks to
|
||||
this property, the custom <literal>ILoadBalancer</literal> knows that the part of the URI passed to Ribbon
|
||||
might actually be the alias that has to be resolved to a proper path in Zookeeper. Without
|
||||
this property, you cannot register applications under nested paths.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>spring.cloud.zookeeper.dependency.headers.enabled</literal> (enabled by default): This property
|
||||
registers a <literal>RibbonClient</literal> that automatically appends appropriate headers and content
|
||||
types with their versions, as presented in the Dependency configuration. Without this
|
||||
setting, those two parameters do not work.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>spring.cloud.zookeeper.dependency.resttemplate.enabled</literal> (enabled by default): When
|
||||
enabled, this property modifies the request headers of a <literal>@LoadBalanced</literal>-annotated
|
||||
<literal>RestTemplate</literal> such that it passes headers and content type with the version set in
|
||||
dependency configuration. Without this setting, those two parameters do not work.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</chapter>
|
||||
<chapter xml:id="spring-cloud-zookeeper-dependency-watcher">
|
||||
<title>Spring Cloud Zookeeper Dependency Watcher</title>
|
||||
<simpara>The Dependency Watcher mechanism lets you register listeners to your dependencies. The
|
||||
functionality is, in fact, an implementation of the <literal>Observator</literal> pattern. When a
|
||||
dependency changes, its state (to either UP or DOWN), some custom logic can be applied.</simpara>
|
||||
<section xml:id="_activating_2">
|
||||
<title>Activating</title>
|
||||
<simpara>Spring Cloud Zookeeper Dependencies functionality needs to be enabled for you to use the
|
||||
Dependency Watcher mechanism.</simpara>
|
||||
</section>
|
||||
<section xml:id="_registering_a_listener">
|
||||
<title>Registering a Listener</title>
|
||||
<simpara>To register a listener, you must implement an interface called
|
||||
<literal>org.springframework.cloud.zookeeper.discovery.watcher.DependencyWatcherListener</literal> and
|
||||
register it as a bean. The interface gives you one method:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">void stateChanged(String dependencyName, DependencyState newState);</programlisting>
|
||||
<simpara>If you want to register a listener for a particular dependency, the <literal>dependencyName</literal> would
|
||||
be the discriminator for your concrete implementation. <literal>newState</literal> provides you with
|
||||
information about whether your dependency has changed to <literal>CONNECTED</literal> or <literal>DISCONNECTED</literal>.</simpara>
|
||||
</section>
|
||||
<section xml:id="spring-cloud-zookeeper-dependency-watcher-presence-checker">
|
||||
<title>Using the Presence Checker</title>
|
||||
<simpara>Bound with the Dependency Watcher is the functionality called Presence Checker. It lets
|
||||
you provide custom behavior when your application boots, to react according to the state
|
||||
of your dependencies.</simpara>
|
||||
<simpara>The default implementation of the abstract
|
||||
<literal>org.springframework.cloud.zookeeper.discovery.watcher.presence.DependencyPresenceOnStartupVerifier</literal>
|
||||
class is the
|
||||
<literal>org.springframework.cloud.zookeeper.discovery.watcher.presence.DefaultDependencyPresenceOnStartupVerifier</literal>,
|
||||
which works in the following way.</simpara>
|
||||
<orderedlist numeration="arabic">
|
||||
<listitem>
|
||||
<simpara>If the dependency is marked us <literal>required</literal> and is not in Zookeeper, when your application
|
||||
boots, it throws an exception and shuts down.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>If the dependency is not <literal>required</literal>, the
|
||||
<literal>org.springframework.cloud.zookeeper.discovery.watcher.presence.LogMissingDependencyChecker</literal>
|
||||
logs that the dependency is missing at the <literal>WARN</literal> level.</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<simpara>Because the <literal>DefaultDependencyPresenceOnStartupVerifier</literal> is registered only when there is
|
||||
no bean of type <literal>DependencyPresenceOnStartupVerifier</literal>, this functionality can be
|
||||
overridden.</simpara>
|
||||
</section>
|
||||
</chapter>
|
||||
<chapter xml:id="spring-cloud-zookeeper-config">
|
||||
<title>Distributed Configuration with Zookeeper</title>
|
||||
<simpara>Zookeeper provides a
|
||||
<link xl:href="https://zookeeper.apache.org/doc/current/zookeeperOver.html#sc_dataModelNameSpace">hierarchical namespace</link>
|
||||
that lets clients store arbitrary data, such as configuration data. Spring Cloud Zookeeper
|
||||
Config is an alternative to the
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-config">Config Server and Client</link>.
|
||||
Configuration is loaded into the Spring Environment during the special <quote>bootstrap</quote>
|
||||
phase. Configuration is stored in the <literal>/config</literal> namespace by default. Multiple
|
||||
<literal>PropertySource</literal> instances are created, based on the application’s name and the active
|
||||
profiles, to mimic the Spring Cloud Config order of resolving properties. For example, an
|
||||
application with a name of <literal>testApp</literal> and with the <literal>dev</literal> profile has the following property
|
||||
sources created for it:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><literal>config/testApp,dev</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>config/testApp</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>config/application,dev</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>config/application</literal></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>The most specific property source is at the top, with the least specific at the bottom.
|
||||
Properties in the <literal>config/application</literal> namespace apply to all applications that use
|
||||
zookeeper for configuration. Properties in the <literal>config/testApp</literal> namespace are available
|
||||
only to the instances of the service named <literal>testApp</literal>.</simpara>
|
||||
<simpara>Configuration is currently read on startup of the application. Sending a HTTP <literal>POST</literal>
|
||||
request to <literal>/refresh</literal> causes the configuration to be reloaded. Watching the configuration
|
||||
namespace (which Zookeeper supports) is not currently implemented.</simpara>
|
||||
<section xml:id="_activating_3">
|
||||
<title>Activating</title>
|
||||
<simpara>Including a dependency on
|
||||
<literal>org.springframework.cloud:spring-cloud-starter-zookeeper-config</literal> enables
|
||||
autoconfiguration that sets up Spring Cloud Zookeeper Config.</simpara>
|
||||
<caution>
|
||||
<simpara>When working with version 3.4 of Zookeeper you need to change
|
||||
the way you include the dependency as described <link linkend="spring-cloud-zookeeper-install">here</link>.</simpara>
|
||||
</caution>
|
||||
</section>
|
||||
<section xml:id="_customizing">
|
||||
<title>Customizing</title>
|
||||
<simpara>Zookeeper Config may be customized by setting the following properties:</simpara>
|
||||
<formalpara>
|
||||
<title>bootstrap.yml</title>
|
||||
<para>
|
||||
<programlisting language="yml" linenumbering="unnumbered">spring:
|
||||
cloud:
|
||||
zookeeper:
|
||||
config:
|
||||
enabled: true
|
||||
root: configuration
|
||||
defaultContext: apps
|
||||
profileSeparator: '::'</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><literal>enabled</literal>: Setting this value to <literal>false</literal> disables Zookeeper Config.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>root</literal>: Sets the base namespace for configuration values.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>defaultContext</literal>: Sets the name used by all applications.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>profileSeparator</literal>: Sets the value of the separator used to separate the profile name in
|
||||
property sources with profiles.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="_access_control_lists_acls">
|
||||
<title>Access Control Lists (ACLs)</title>
|
||||
<simpara>You can add authentication information for Zookeeper ACLs by calling the <literal>addAuthInfo</literal>
|
||||
method of a <literal>CuratorFramework</literal> bean. One way to accomplish this is to provide your own
|
||||
<literal>CuratorFramework</literal> bean, as shown in the following example:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">@BoostrapConfiguration
|
||||
public class CustomCuratorFrameworkConfig {
|
||||
|
||||
@Bean
|
||||
public CuratorFramework curatorFramework() {
|
||||
CuratorFramework curator = new CuratorFramework();
|
||||
curator.addAuthInfo("digest", "user:password".getBytes());
|
||||
return curator;
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
<simpara>Consult
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-zookeeper/blob/master/spring-cloud-zookeeper-core/src/main/java/org/springframework/cloud/zookeeper/ZookeeperAutoConfiguration.java">the ZookeeperAutoConfiguration class</link>
|
||||
to see how the <literal>CuratorFramework</literal> bean’s default configuration.</simpara>
|
||||
<simpara>Alternatively, you can add your credentials from a class that depends on the existing
|
||||
<literal>CuratorFramework</literal> bean, as shown in the following example:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">@BoostrapConfiguration
|
||||
public class DefaultCuratorFrameworkConfig {
|
||||
|
||||
public ZookeeperConfig(CuratorFramework curator) {
|
||||
curator.addAuthInfo("digest", "user:password".getBytes());
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
<simpara>The creation of this bean must occur during the boostrapping phase. You can register
|
||||
configuration classes to run during this phase by annotating them with
|
||||
<literal>@BootstrapConfiguration</literal> and including them in a comma-separated list that you set as the
|
||||
value of the <literal>org.springframework.cloud.bootstrap.BootstrapConfiguration</literal> property in the
|
||||
<literal>resources/META-INF/spring.factories</literal> file, as shown in the following example:</simpara>
|
||||
<formalpara>
|
||||
<title>resources/META-INF/spring.factories</title>
|
||||
<para>
|
||||
<screen>org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
my.project.CustomCuratorFrameworkConfig,\
|
||||
my.project.DefaultCuratorFrameworkConfig</screen>
|
||||
</para>
|
||||
</formalpara>
|
||||
</section>
|
||||
</chapter>
|
||||
</book>
|
||||