diff --git a/spring-cloud-consul/2.1.0.M2/css/highlight.css b/spring-cloud-consul/2.1.0.M2/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/css/manual-multipage.css b/spring-cloud-consul/2.1.0.M2/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-consul/2.1.0.M2/css/manual-singlepage.css b/spring-cloud-consul/2.1.0.M2/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-consul/2.1.0.M2/css/manual.css b/spring-cloud-consul/2.1.0.M2/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-consul/2.1.0.M2/ghpages.sh b/spring-cloud-consul/2.1.0.M2/ghpages.sh new file mode 100644 index 00000000..57c5da3a --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/ghpages.sh @@ -0,0 +1,330 @@ +#!/bin/bash -x + +set -e + +# Set default props like MAVEN_PATH, ROOT_FOLDER etc. +function set_default_props() { + # The script should be executed from the root folder + ROOT_FOLDER=`pwd` + echo "Current folder is ${ROOT_FOLDER}" + + if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then + echo "You're not in the root folder of the project!" + exit 1 + fi + + # Prop that will let commit the changes + COMMIT_CHANGES="no" + MAVEN_PATH=${MAVEN_PATH:-} + echo "Path to Maven is [${MAVEN_PATH}]" + REPO_NAME=${PWD##*/} + echo "Repo name is [${REPO_NAME}]" + SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git} + echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}" +} + +# Check if gh-pages exists and docs have been built +function check_if_anything_to_sync() { + git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'` + + if ! (git remote set-branches --add origin gh-pages && git fetch -q); then + echo "No gh-pages, so not syncing" + exit 0 + fi + + if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then + echo "No gh-pages sources in docs/target/generated-docs, so not syncing" + exit 0 + fi +} + +function retrieve_current_branch() { + # Code getting the name of the current branch. For master we want to publish as we did until now + # http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch + # If there is a branch already passed will reuse it - otherwise will try to find it + CURRENT_BRANCH=${BRANCH} + if [[ -z "${CURRENT_BRANCH}" ]] ; then + CURRENT_BRANCH=$(git symbolic-ref -q HEAD) + CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/} + CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD} + fi + echo "Current branch is [${CURRENT_BRANCH}]" + git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" +} + +# Switches to the provided value of the release version. We always prefix it with `v` +function switch_to_tag() { + git checkout v${VERSION} +} + +# Build the docs if switch is on +function build_docs_if_applicable() { + if [[ "${BUILD}" == "yes" ]] ; then + ./mvnw clean install -P docs -pl docs -DskipTests + fi +} + +# Get the name of the `docs.main` property +# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile +function retrieve_doc_properties() { + MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \ + -Dexec.executable="echo" \ + -Dexec.args='${docs.main}' \ + --non-recursive \ + org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) + echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]" + + + WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"} + WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \ + -Dexec.executable="echo" \ + -Dexec.args="\${${WHITELIST_PROPERTY}}" \ + org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \ + -P docs \ + -pl docs) + echo "Extracted '${WHITELIST_PROPERTY}' from Maven build [${WHITELISTED_BRANCHES_VALUE}]" +} + +# Stash any outstanding changes +function stash_changes() { + git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1") + if [ "$dirty" != "0" ]; then git stash; fi +} + +# Switch to gh-pages branch to sync it with current branch +function add_docs_from_target() { + local DESTINATION_REPO_FOLDER + if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then + DESTINATION_REPO_FOLDER=${ROOT_FOLDER} + elif [[ "${CLONE}" == "yes" ]]; then + mkdir -p ${ROOT_FOLDER}/target + local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static + if [[ ! -e "${clonedStatic}/.git" ]]; then + echo "Cloning Spring Cloud Static to target" + git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages + else + echo "Spring Cloud Static already cloned - will pull changes" + cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages + fi + DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME} + mkdir -p ${DESTINATION_REPO_FOLDER} + else + if [[ ! -e "${DESTINATION}/.git" ]]; then + echo "[${DESTINATION}] is not a git repository" + exit 1 + fi + DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME} + mkdir -p ${DESTINATION_REPO_FOLDER} + echo "Destination was provided [${DESTINATION}]" + fi + cd ${DESTINATION_REPO_FOLDER} + git checkout gh-pages + git pull origin gh-pages + + # Add git branches + ################################################################### + if [[ -z "${VERSION}" ]] ; then + copy_docs_for_current_version + else + copy_docs_for_provided_version + fi + commit_changes_if_applicable +} + + +# Copies the docs by using the retrieved properties from Maven build +function copy_docs_for_current_version() { + if [[ "${CURRENT_BRANCH}" == "master" ]] ; then + echo -e "Current branch is master - will copy the current docs only to the root folder" + for f in docs/target/generated-docs/*; do + file=${f#docs/target/generated-docs/*} + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then + # Not ignored... + cp -rf $f ${ROOT_FOLDER}/ + git add -A ${ROOT_FOLDER}/$file + fi + done + COMMIT_CHANGES="yes" + else + echo -e "Current branch is [${CURRENT_BRANCH}]" + # http://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin + if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then + mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH} + echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder" + for f in docs/target/generated-docs/*; do + file=${f#docs/target/generated-docs/*} + if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then + # Not ignored... + # We want users to access 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 </` +- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will + switch to gh-pages of that repo and copy the generated docs to `docs//` + +USAGE: + +You can use the following options: + +-v|--version - the script will apply the whole procedure for a particular library version +-d|--destination - the root of destination folder where the docs should be copied. You have to use the full path. + E.g. point to spring-cloud-static folder. Can't be used with (-c) +-b|--build - will run the standard build process after checking out the branch +-c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination. + Obviously can't be used with (-d) + +EOF +} + + +# ========================================== +# ____ ____ _____ _____ _____ _______ +# / ____|/ ____| __ \|_ _| __ \__ __| +# | (___ | | | |__) | | | | |__) | | | +# \___ \| | | _ / | | | ___/ | | +# ____) | |____| | \ \ _| |_| | | | +# |_____/ \_____|_| \_\_____|_| |_| +# +# ========================================== + +while [[ $# > 0 ]] +do +key="$1" +case ${key} in + -v|--version) + VERSION="$2" + shift # past argument + ;; + -d|--destination) + DESTINATION="$2" + shift # past argument + ;; + -b|--build) + BUILD="yes" + ;; + -c|--clone) + CLONE="yes" + ;; + -h|--help) + print_usage + exit 0 + ;; + *) + echo "Invalid option: [$1]" + print_usage + exit 1 + ;; +esac +shift # past argument or value +done + +assert_properties +set_default_props +check_if_anything_to_sync +if [[ -z "${VERSION}" ]] ; then + retrieve_current_branch +else + switch_to_tag +fi +build_docs_if_applicable +retrieve_doc_properties +stash_changes +add_docs_from_target +checkout_previous_branch \ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/images/.gitkeep b/spring-cloud-consul/2.1.0.M2/images/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/spring-cloud-consul/2.1.0.M2/images/background.png b/spring-cloud-consul/2.1.0.M2/images/background.png new file mode 100644 index 00000000..15dca6fb Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/background.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/callouts/1.png b/spring-cloud-consul/2.1.0.M2/images/callouts/1.png new file mode 100644 index 00000000..7d473430 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/callouts/1.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/callouts/2.png b/spring-cloud-consul/2.1.0.M2/images/callouts/2.png new file mode 100644 index 00000000..5d09341b Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/callouts/2.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/callouts/3.png b/spring-cloud-consul/2.1.0.M2/images/callouts/3.png new file mode 100644 index 00000000..ef7b7004 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/callouts/3.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/caution.png b/spring-cloud-consul/2.1.0.M2/images/caution.png new file mode 100644 index 00000000..8a5e4fca Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/caution.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/important.png b/spring-cloud-consul/2.1.0.M2/images/important.png new file mode 100644 index 00000000..ec54df65 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/important.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/logo.png b/spring-cloud-consul/2.1.0.M2/images/logo.png new file mode 100644 index 00000000..ade2ce6e Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/logo.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/note.png b/spring-cloud-consul/2.1.0.M2/images/note.png new file mode 100644 index 00000000..88d997b1 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/note.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/tip.png b/spring-cloud-consul/2.1.0.M2/images/tip.png new file mode 100644 index 00000000..6530abb4 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/tip.png differ diff --git a/spring-cloud-consul/2.1.0.M2/images/warning.png b/spring-cloud-consul/2.1.0.M2/images/warning.png new file mode 100644 index 00000000..0d5b5244 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/images/warning.png differ diff --git a/spring-cloud-consul/2.1.0.M2/index.html b/spring-cloud-consul/2.1.0.M2/index.html new file mode 100644 index 00000000..324295bc --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/index.html @@ -0,0 +1,117 @@ + + + + + + + +spring-cloud-consul + + + + + + + + +
+
+
+
+

2.1.0.M2

+
+
+
+
+

Pick The Documentation Option

+
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/css/highlight.css b/spring-cloud-consul/2.1.0.M2/multi/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/css/manual-multipage.css b/spring-cloud-consul/2.1.0.M2/multi/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-consul/2.1.0.M2/multi/css/manual-singlepage.css b/spring-cloud-consul/2.1.0.M2/multi/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-consul/2.1.0.M2/multi/css/manual.css b/spring-cloud-consul/2.1.0.M2/multi/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/background.png b/spring-cloud-consul/2.1.0.M2/multi/images/background.png new file mode 100644 index 00000000..15dca6fb Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/background.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/callouts/1.png b/spring-cloud-consul/2.1.0.M2/multi/images/callouts/1.png new file mode 100644 index 00000000..7d473430 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/callouts/1.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/callouts/2.png b/spring-cloud-consul/2.1.0.M2/multi/images/callouts/2.png new file mode 100644 index 00000000..5d09341b Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/callouts/2.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/callouts/3.png b/spring-cloud-consul/2.1.0.M2/multi/images/callouts/3.png new file mode 100644 index 00000000..ef7b7004 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/callouts/3.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/caution.png b/spring-cloud-consul/2.1.0.M2/multi/images/caution.png new file mode 100644 index 00000000..8a5e4fca Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/caution.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/important.png b/spring-cloud-consul/2.1.0.M2/multi/images/important.png new file mode 100644 index 00000000..ec54df65 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/important.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/logo.png b/spring-cloud-consul/2.1.0.M2/multi/images/logo.png new file mode 100644 index 00000000..ade2ce6e Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/logo.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/note.png b/spring-cloud-consul/2.1.0.M2/multi/images/note.png new file mode 100644 index 00000000..88d997b1 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/note.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/tip.png b/spring-cloud-consul/2.1.0.M2/multi/images/tip.png new file mode 100644 index 00000000..6530abb4 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/tip.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/images/warning.png b/spring-cloud-consul/2.1.0.M2/multi/images/warning.png new file mode 100644 index 00000000..0d5b5244 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/multi/images/warning.png differ diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_pr01.html b/spring-cloud-consul/2.1.0.M2/multi/multi_pr01.html new file mode 100644 index 00000000..e1bc11d9 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_pr01.html @@ -0,0 +1,9 @@ + + +

2.1.0.M2

This project provides Consul integrations for Spring Boot apps through autoconfiguration +and binding to the Spring Environment and other Spring programming model idioms. With a few +simple annotations you can quickly enable and configure the common patterns inside your +application and build large distributed systems with Consul based components. The +patterns provided include Service Discovery, Control Bus and Configuration. +Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Breaker +(Hystrix) are provided by integration with Spring Cloud Netflix.

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-agent.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-agent.html new file mode 100644 index 00000000..0238a3fb --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-agent.html @@ -0,0 +1,3 @@ + + + 2. Consul Agent

2. Consul Agent

A Consul Agent client must be available to all Spring Cloud Consul applications. By default, the Agent client is expected to be at localhost:8500. See the Agent documentation for specifics on how to start an Agent client and how to connect to a cluster of Consul Agent Servers. For development, after you have installed consul, you may start a Consul Agent using the following command:

./src/main/bash/local_run_consul.sh

This will start an agent in server mode on port 8500, with the ui available at http://localhost:8500

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-bus.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-bus.html new file mode 100644 index 00000000..680090bd --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-bus.html @@ -0,0 +1,3 @@ + + + 6. Spring Cloud Bus with Consul

6. Spring Cloud Bus with Consul

6.1 How to activate

To get started with the Consul Bus use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-bus. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

See the Spring Cloud Bus documentation for the available actuator endpoints and howto send custom messages.

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-config.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-config.html new file mode 100644 index 00000000..7d17e08c --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-config.html @@ -0,0 +1,38 @@ + + + 4. Distributed Configuration with Consul

4. Distributed Configuration with Consul

Consul provides a Key/Value Store for storing configuration and other metadata. Spring Cloud Consul Config is an alternative to the Config Server and Client. Configuration is loaded into the Spring Environment during the special "bootstrap" phase. Configuration is stored in the /config folder by default. Multiple PropertySource instances are created based on the application’s name and the active profiles that mimicks the Spring Cloud Config order of resolving properties. For example, an application with the name "testApp" and with the "dev" profile will have the following property sources created:

config/testApp,dev/
+config/testApp/
+config/application,dev/
+config/application/

The most specific property source is at the top, with the least specific at the bottom. Properties in the config/application folder are applicable to all applications using consul for configuration. Properties in the config/testApp folder are only available to the instances of the service named "testApp".

Configuration is currently read on startup of the application. Sending a HTTP POST to /refresh will cause the configuration to be reloaded. Section 4.3, “Config Watch” will also automatically detect changes and reload the application context.

4.1 How to activate

To get started with Consul Configuration use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-config. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

This will enable auto-configuration that will setup Spring Cloud Consul Config.

4.2 Customizing

Consul Config may be customized using the following properties:

bootstrap.yml.  +

spring:
+  cloud:
+    consul:
+      config:
+        enabled: true
+        prefix: configuration
+        defaultContext: apps
+        profileSeparator: '::'

+

  • enabled setting this value to "false" disables Consul Config
  • prefix sets the base folder for configuration values
  • defaultContext sets the folder name used by all applications
  • profileSeparator sets the value of the separator used to separate the profile name in property sources with profiles

4.3 Config Watch

The Consul Config Watch takes advantage of the ability of consul to watch a key prefix. The Config Watch makes a blocking Consul HTTP API call to determine if any relevant configuration data has changed for the current application. If there is new configuration data a Refresh Event is published. This is equivalent to calling the /refresh actuator endpoint.

To change the frequency of when the Config Watch is called change spring.cloud.consul.config.watch.delay. The default value is 1000, which is in milliseconds. The delay is the amount of time after the end of the previous invocation and the start of the next.

To disable the Config Watch set spring.cloud.consul.config.watch.enabled=false.

The watch uses a Spring TaskScheduler to schedule the call to consul. By default it is a ThreadPoolTaskScheduler with a poolSize of 1. To change the TaskScheduler, create a bean of type TaskScheduler named with the ConsulConfigAutoConfiguration.CONFIG_WATCH_TASK_SCHEDULER_NAME constant.

4.4 YAML or Properties with Config

It may be more convenient to store a blob of properties in YAML or Properties format as opposed to individual key/value pairs. Set the spring.cloud.consul.config.format property to YAML or PROPERTIES. For example to use YAML:

bootstrap.yml.  +

spring:
+  cloud:
+    consul:
+      config:
+        format: YAML

+

YAML must be set in the appropriate data key in consul. Using the defaults above the keys would look like:

config/testApp,dev/data
+config/testApp/data
+config/application,dev/data
+config/application/data

You could store a YAML document in any of the keys listed above.

You can change the data key using spring.cloud.consul.config.data-key.

4.5 git2consul with Config

git2consul is a Consul community project that loads files from a git repository to individual keys into Consul. By default the names of the keys are names of the files. YAML and Properties files are supported with file extensions of .yml and .properties respectively. Set the spring.cloud.consul.config.format property to FILES. For example:

bootstrap.yml.  +

spring:
+  cloud:
+    consul:
+      config:
+        format: FILES

+

Given the following keys in /config, the development profile and an application name of foo:

.gitignore
+application.yml
+bar.properties
+foo-development.properties
+foo-production.yml
+foo.properties
+master.ref

the following property sources would be created:

config/foo-development.properties
+config/foo.properties
+config/application.yml

The value of each key needs to be a properly formatted YAML or Properties file.

4.6 Fail Fast

It may be convenient in certain circumstances (like local development or certain test scenarios) to not fail if consul isn’t available for configuration. Setting spring.cloud.consul.config.failFast=false in bootstrap.yml will cause the configuration module to log a warning rather than throw an exception. This will allow the application to continue startup normally.

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-discovery.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-discovery.html new file mode 100644 index 00000000..7b2f4535 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-discovery.html @@ -0,0 +1,78 @@ + + + 3. Service Discovery with Consul

3. Service Discovery with Consul

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 very difficult to do and can be very brittle. Consul provides Service Discovery services via an HTTP API and DNS. Spring Cloud Consul leverages the HTTP API for service registration and discovery. This does not prevent non-Spring Cloud applications from leveraging the DNS interface. Consul Agents servers are run in a cluster that communicates via a gossip protocol and uses the Raft consensus protocol.

3.1 How to activate

To activate Consul Service Discovery use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-discovery. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

3.2 Registering with Consul

When a client registers with Consul, it provides meta-data about itself such as host and port, id, name and tags. An HTTP Check is created by default that Consul hits the /health endpoint every 10 seconds. If the health check fails, the service instance is marked as critical.

Example Consul client:

@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);
+    }
+
+}

(i.e. utterly normal Spring Boot app). If the Consul client is located somewhere other than localhost:8500, the configuration is required to locate the client. Example:

application.yml.  +

spring:
+  cloud:
+    consul:
+      host: localhost
+      port: 8500

+

[Caution]Caution

If you use Spring Cloud Consul Config, the above values will need to be placed in bootstrap.yml instead of application.yml.

The default service name, instance id and port, taken from the Environment, are ${spring.application.name}, the Spring Context ID and ${server.port} respectively.

To disable the Consul Discovery Client you can set spring.cloud.consul.discovery.enabled to false.

To disable the service registration you can set spring.cloud.consul.discovery.register to false.

3.3 HTTP Health Check

The health check for a Consul instance defaults to "/health", which is the default locations of a useful endpoint in a Spring Boot Actuator application. You need to change these, even for an Actuator application if you use a non-default context path or servlet path (e.g. server.servletPath=/foo) or management endpoint path (e.g. management.server.servlet.context-path=/admin). The interval that Consul uses to check the health endpoint may also be configured. "10s" and "1m" represent 10 seconds and 1 minute respectively. Example:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        healthCheckPath: ${management.server.servlet.context-path}/health
+        healthCheckInterval: 15s

+

You can disable the health check by setting management.health.consul.enabled=false.

3.3.1 Metadata and Consul tags

Consul does not yet support metadata on services. Spring Cloud’s ServiceInstance has a Map<String, String> metadata field. Spring Cloud Consul uses Consul tags to approximate metadata until Consul officially supports metadata. Tags with the form key=value will be split and used as a Map key and value respectively. Tags without the equal = sign, will be used as both the key and value.

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        tags: foo=bar, baz

+

The above configuration will result in a map with foo→bar and baz→baz.

3.3.2 Making the Consul Instance ID Unique

By default a consul instance is registered with an ID that is equal to its Spring Application Context ID. By default, the Spring Application Context ID is ${spring.application.name}:comma,separated,profiles:${server.port}. For most cases, this will allow multiple instances of one service to run on one machine. If further uniqueness is required, Using Spring Cloud you can override this by providing a unique identifier in spring.cloud.consul.discovery.instanceId. For example:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

+

With this metadata, and multiple service instances deployed on localhost, the random value will kick in there to make the instance unique. In Cloudfoundry the vcap.application.instance_id will be populated automatically in a Spring Boot application, so the random value will not be needed.

3.3.3 Applying Headers to Health Check Requests

Headers can be applied to health check requests. For example, if you’re trying to register a Spring Cloud Config server that uses Vault Backend:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        health-check-headers:
+          X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722

+

According to the HTTP standard, each header can have more than one values, in which case, an array can be supplied:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        health-check-headers:
+          X-Config-Token:
+            - "6442e58b-d1ea-182e-cfa5-cf9cddef0722"
+            - "Some other value"

+

3.4 Looking up services

3.4.1 Using Ribbon

Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate +for looking up services using the logical service names/ids instead of physical URLs. Both Feign and the discovery-aware RestTemplate utilize Ribbon for client-side load balancing.

If you want to access service STORES using the RestTemplate simply declare:

@LoadBalanced
+@Bean
+public RestTemplate loadbalancedRestTemplate() {
+     new RestTemplate();
+}

and use it like this (notice how we use the STORES service name/id from Consul instead of a fully qualified domainname):

@Autowired
+RestTemplate restTemplate;
+
+public String getFirstProduct() {
+   return this.restTemplate.getForObject("https://STORES/products/1", String.class);
+}

If you have Consul clusters in multiple datacenters and you want to access a service in another datacenter a service name/id alone is not enough. In that case +you use property spring.cloud.consul.discovery.datacenters.STORES=dc-west where STORES is the service name/id and dc-west is the datacenter +where the STORES service lives.

3.4.2 Using the DiscoveryClient

You can also use the org.springframework.cloud.client.discovery.DiscoveryClient which provides a simple API for discovery clients that is not specific to Netflix, e.g.

@Autowired
+private DiscoveryClient discoveryClient;
+
+public String serviceUrl() {
+    List<ServiceInstance> list = discoveryClient.getInstances("STORES");
+    if (list != null && list.size() > 0 ) {
+        return list.get(0).getUri();
+    }
+    return null;
+}

3.5 Consul Catalog Watch

The Consul Catalog Watch takes advantage of the ability of consul to watch services. The Catalog Watch makes a blocking Consul HTTP API call to determine if any services have changed. If there is new service data a Heartbeat Event is published.

To change the frequency of when the Config Watch is called change spring.cloud.consul.config.discovery.catalog-services-watch-delay. The default value is 1000, which is in milliseconds. The delay is the amount of time after the end of the previous invocation and the start of the next.

To disable the Catalog Watch set spring.cloud.consul.discovery.catalogServicesWatch.enabled=false.

The watch uses a Spring TaskScheduler to schedule the call to consul. By default it is a ThreadPoolTaskScheduler with a poolSize of 1. To change the TaskScheduler, create a bean of type TaskScheduler named with the ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME constant.

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-hystrix.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-hystrix.html new file mode 100644 index 00000000..89b0e340 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-hystrix.html @@ -0,0 +1,3 @@ + + + 7. Circuit Breaker with Hystrix

7. Circuit Breaker with Hystrix

Applications can use the Hystrix Circuit Breaker provided by the Spring Cloud Netflix project by including this starter in the projects pom.xml: spring-cloud-starter-hystrix. Hystrix doesn’t depend on the Netflix Discovery Client. The @EnableHystrix annotation should be placed on a configuration class (usually the main class). Then methods can be annotated with @HystrixCommand to be protected by a circuit breaker. See the documentation for more details.

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-install.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-install.html new file mode 100644 index 00000000..ab2bd249 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-install.html @@ -0,0 +1,3 @@ + + + 1. Install Consul

1. Install Consul

Please see the installation documentation for instructions on how to install Consul.

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-retry.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-retry.html new file mode 100644 index 00000000..65d2dc4c --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-retry.html @@ -0,0 +1,11 @@ + + + 5. Consul Retry

5. Consul Retry

If you expect that the consul agent may occasionally be unavailable when +your app starts, you can ask it to keep trying after a failure. You need to add +spring-retry and spring-boot-starter-aop to your classpath. The default +behaviour is to retry 6 times with an initial backoff interval of 1000ms and an +exponential multiplier of 1.1 for subsequent backoffs. You can configure these +properties (and others) using spring.cloud.consul.retry.* configuration properties. +This works with both Spring Cloud Consul Config and Discovery registration.

[Tip]Tip

To take full control of the retry add a @Bean of type +RetryOperationsInterceptor with id "consulRetryInterceptor". Spring +Retry has a RetryInterceptorBuilder that makes it easy to create one.

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-turbine.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-turbine.html new file mode 100644 index 00000000..6dd41ee9 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul-turbine.html @@ -0,0 +1,27 @@ + + + 8. Hystrix metrics aggregation with Turbine and Consul

8. Hystrix metrics aggregation with Turbine and Consul

Turbine (provided by the Spring Cloud Netflix project), aggregates multiple instances Hystrix metrics streams, so the dashboard can display an aggregate view. Turbine uses the DiscoveryClient interface to lookup relevant instances. To use Turbine with Spring Cloud Consul, configure the Turbine application in a manner similar to the following examples:

pom.xml.  +

<dependency>
+    <groupId>org.springframework.cloud</groupId>
+    <artifactId>spring-cloud-netflix-turbine</artifactId>
+</dependency>
+<dependency>
+    <groupId>org.springframework.cloud</groupId>
+    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
+</dependency>

+

Notice that the Turbine dependency is not a starter. The turbine starter includes support for Netflix Eureka.

application.yml.  +

spring.application.name: turbine
+applications: consulhystrixclient
+turbine:
+  aggregator:
+    clusterConfig: ${applications}
+  appConfig: ${applications}

+

The clusterConfig and appConfig sections must match, so it’s useful to put the comma-separated list of service ID’s into a separate configuration property.

Turbine.java.  +

@EnableTurbine
+@SpringBootApplication
+public class Turbine {
+    public static void main(String[] args) {
+        SpringApplication.run(DemoturbinecommonsApplication.class, args);
+    }
+}

+

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul.html b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul.html new file mode 100644 index 00000000..c1a09520 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/multi/multi_spring-cloud-consul.html @@ -0,0 +1,3 @@ + + + Spring Cloud Consul \ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/single/css/highlight.css b/spring-cloud-consul/2.1.0.M2/single/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/single/css/highlight.css @@ -0,0 +1,35 @@ +/* + code highlight CSS resemblign the Eclipse IDE default color schema + @author Costin Leau +*/ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/single/css/manual-multipage.css b/spring-cloud-consul/2.1.0.M2/single/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/single/css/manual-multipage.css @@ -0,0 +1,9 @@ +@IMPORT url("manual.css"); + +body.firstpage { + background: url("../images/background.png") no-repeat center top; +} + +div.part h1 { + border-top: none; +} diff --git a/spring-cloud-consul/2.1.0.M2/single/css/manual-singlepage.css b/spring-cloud-consul/2.1.0.M2/single/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/single/css/manual-singlepage.css @@ -0,0 +1,6 @@ +@IMPORT url("manual.css"); + +body { + background: url("../images/background.png") no-repeat center top; +} + diff --git a/spring-cloud-consul/2.1.0.M2/single/css/manual.css b/spring-cloud-consul/2.1.0.M2/single/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/single/css/manual.css @@ -0,0 +1,344 @@ +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + color: #333333; + margin: 15px 30px; + font-family: Helvetica, Arial, Freesans, Clean, Sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +code { + font-size: 16px; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +:not(a)>code { + color: #6D180B; +} + +:not(pre)>code { + background-color: #F2F2F2; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 1px 3px 0; + text-shadow: none; + white-space: nowrap; +} + +body>*:first-child { + margin-top: 0 !important; +} + +div { + margin: 0pt; +} + +hr { + border: 1px solid #CCCCCC; + background: #CCCCCC; +} + +h1,h2,h3,h4,h5,h6 { + color: #000000; + cursor: text; + font-weight: bold; + margin: 30px 0 10px; + padding: 0; +} + +h1,h2,h3 { + margin: 40px 0 10px; +} + +h1 { + margin: 70px 0 30px; + padding-top: 20px; +} + +div.part h1 { + border-top: 1px dotted #CCCCCC; +} + +h1,h1 code { + font-size: 32px; +} + +h2,h2 code { + font-size: 24px; +} + +h3,h3 code { + font-size: 20px; +} + +h4,h1 code,h5,h5 code,h6,h6 code { + font-size: 18px; +} + +div.book,div.chapter,div.appendix,div.part,div.preface { + min-width: 300px; + max-width: 1200px; + margin: 0 auto; +} + +p.releaseinfo { + font-weight: bold; + margin-bottom: 40px; + margin-top: 40px; +} + +div.authorgroup { + line-height: 1; +} + +p.copyright { + line-height: 1; + margin-bottom: -5px; +} + +.legalnotice p { + font-style: italic; + font-size: 14px; + line-height: 1; +} + +div.titlepage+p,div.titlepage+p { + margin-top: 0; +} + +pre { + line-height: 1.0; + color: black; +} + +a { + color: #4183C4; + text-decoration: none; +} + +p { + margin: 15px 0; + text-align: left; +} + +ul,ol { + padding-left: 30px; +} + +li p { + margin: 0; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table,div.informaltable table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} + +.sidebar { + line-height: 1.4; + padding: 0 20px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; +} + +.sidebar p.title { + color: #6D180B; +} + +pre.programlisting,pre.screen { + font-size: 15px; + padding: 6px 10px; + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + clear: both; + overflow: auto; + line-height: 1.4; + font-family: Consolas, "Liberation Mono", Courier, monospace; +} + +table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #DDDDDD !important; + border-radius: 4px !important; + border-collapse: separate !important; + line-height: 1.6; +} + +table thead { + background: #F5F5F5; +} + +table tr { + border: none; + border-bottom: none; +} + +table th { + font-weight: bold; +} + +table th,table td { + border: none !important; + padding: 6px 13px; +} + +table tr:nth-child(2n) { + background-color: #F8F8F8; +} + +td p { + margin: 0 0 15px 0; +} + +div.table-contents td p { + margin: 0; +} + +div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist * + { + border: none !important; + background: none !important; + margin: 0; +} + +div.important p,div.note p,div.tip p,div.warning p { + color: #6F6F6F; + line-height: 1.6; +} + +div.important code,div.note code,div.tip code,div.warning code { + background-color: #F2F2F2 !important; + border: 1px solid #CCCCCC !important; + border-radius: 4px !important; + padding: 1px 3px 0 !important; + text-shadow: none !important; + white-space: nowrap !important; +} + +.note th,.tip th,.warning th { + display: none; +} + +.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td + { + border-right: 1px solid #CCCCCC !important; + padding-top: 10px; +} + +div.calloutlist p,div.calloutlist td { + padding: 0; + margin: 0; +} + +div.calloutlist>table>tbody>tr>td:first-child { + padding-left: 10px; + width: 30px !important; +} + +div.important,div.note,div.tip,div.warning { + margin-left: 0px !important; + margin-right: 20px !important; + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; +} + +div.toc { + line-height: 1.2; +} + +dl,dt { + margin-top: 1px; + margin-bottom: 0; +} + +div.toc>dl>dt { + font-size: 32px; + font-weight: bold; + margin: 30px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dt { + font-size: 24px; + font-weight: bold; + margin: 20px 0 10px 0; + display: block; +} + +div.toc>dl>dd>dl>dd>dl>dt { + font-weight: bold; + font-size: 20px; + margin: 10px 0 0 0; +} + +tbody.footnotes * { + border: none !important; +} + +div.footnote p { + margin: 0; + line-height: 1; +} + +div.footnote p sup { + margin-right: 6px; + vertical-align: middle; +} + +div.navheader { + border-bottom: 1px solid #CCCCCC; +} + +div.navfooter { + border-top: 1px solid #CCCCCC; +} + +.title { + margin-left: -1em; + padding-left: 1em; +} + +.title>a { + position: absolute; + visibility: hidden; + display: block; + font-size: 0.85em; + margin-top: 0.05em; + margin-left: -1em; + vertical-align: text-top; + color: black; +} + +.title>a:before { + content: "\00A7"; +} + +.title:hover>a,.title>a:hover,.title:hover>a:hover { + visibility: visible; +} + +.title:focus>a,.title>a:focus,.title:focus>a:focus { + outline: 0; +} diff --git a/spring-cloud-consul/2.1.0.M2/single/images/background.png b/spring-cloud-consul/2.1.0.M2/single/images/background.png new file mode 100644 index 00000000..15dca6fb Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/background.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/callouts/1.png b/spring-cloud-consul/2.1.0.M2/single/images/callouts/1.png new file mode 100644 index 00000000..7d473430 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/callouts/1.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/callouts/2.png b/spring-cloud-consul/2.1.0.M2/single/images/callouts/2.png new file mode 100644 index 00000000..5d09341b Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/callouts/2.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/callouts/3.png b/spring-cloud-consul/2.1.0.M2/single/images/callouts/3.png new file mode 100644 index 00000000..ef7b7004 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/callouts/3.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/caution.png b/spring-cloud-consul/2.1.0.M2/single/images/caution.png new file mode 100644 index 00000000..8a5e4fca Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/caution.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/important.png b/spring-cloud-consul/2.1.0.M2/single/images/important.png new file mode 100644 index 00000000..ec54df65 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/important.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/logo.png b/spring-cloud-consul/2.1.0.M2/single/images/logo.png new file mode 100644 index 00000000..ade2ce6e Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/logo.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/note.png b/spring-cloud-consul/2.1.0.M2/single/images/note.png new file mode 100644 index 00000000..88d997b1 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/note.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/tip.png b/spring-cloud-consul/2.1.0.M2/single/images/tip.png new file mode 100644 index 00000000..6530abb4 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/tip.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/images/warning.png b/spring-cloud-consul/2.1.0.M2/single/images/warning.png new file mode 100644 index 00000000..0d5b5244 Binary files /dev/null and b/spring-cloud-consul/2.1.0.M2/single/images/warning.png differ diff --git a/spring-cloud-consul/2.1.0.M2/single/spring-cloud-consul.html b/spring-cloud-consul/2.1.0.M2/single/spring-cloud-consul.html new file mode 100644 index 00000000..1d6a02b6 --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/single/spring-cloud-consul.html @@ -0,0 +1,151 @@ + + + Spring Cloud Consul

Spring Cloud Consul


2.1.0.M2

This project provides Consul integrations for Spring Boot apps through autoconfiguration +and binding to the Spring Environment and other Spring programming model idioms. With a few +simple annotations you can quickly enable and configure the common patterns inside your +application and build large distributed systems with Consul based components. The +patterns provided include Service Discovery, Control Bus and Configuration. +Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Breaker +(Hystrix) are provided by integration with Spring Cloud Netflix.

1. Install Consul

Please see the installation documentation for instructions on how to install Consul.

2. Consul Agent

A Consul Agent client must be available to all Spring Cloud Consul applications. By default, the Agent client is expected to be at localhost:8500. See the Agent documentation for specifics on how to start an Agent client and how to connect to a cluster of Consul Agent Servers. For development, after you have installed consul, you may start a Consul Agent using the following command:

./src/main/bash/local_run_consul.sh

This will start an agent in server mode on port 8500, with the ui available at http://localhost:8500

3. Service Discovery with Consul

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 very difficult to do and can be very brittle. Consul provides Service Discovery services via an HTTP API and DNS. Spring Cloud Consul leverages the HTTP API for service registration and discovery. This does not prevent non-Spring Cloud applications from leveraging the DNS interface. Consul Agents servers are run in a cluster that communicates via a gossip protocol and uses the Raft consensus protocol.

3.1 How to activate

To activate Consul Service Discovery use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-discovery. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

3.2 Registering with Consul

When a client registers with Consul, it provides meta-data about itself such as host and port, id, name and tags. An HTTP Check is created by default that Consul hits the /health endpoint every 10 seconds. If the health check fails, the service instance is marked as critical.

Example Consul client:

@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);
+    }
+
+}

(i.e. utterly normal Spring Boot app). If the Consul client is located somewhere other than localhost:8500, the configuration is required to locate the client. Example:

application.yml.  +

spring:
+  cloud:
+    consul:
+      host: localhost
+      port: 8500

+

[Caution]Caution

If you use Spring Cloud Consul Config, the above values will need to be placed in bootstrap.yml instead of application.yml.

The default service name, instance id and port, taken from the Environment, are ${spring.application.name}, the Spring Context ID and ${server.port} respectively.

To disable the Consul Discovery Client you can set spring.cloud.consul.discovery.enabled to false.

To disable the service registration you can set spring.cloud.consul.discovery.register to false.

3.3 HTTP Health Check

The health check for a Consul instance defaults to "/health", which is the default locations of a useful endpoint in a Spring Boot Actuator application. You need to change these, even for an Actuator application if you use a non-default context path or servlet path (e.g. server.servletPath=/foo) or management endpoint path (e.g. management.server.servlet.context-path=/admin). The interval that Consul uses to check the health endpoint may also be configured. "10s" and "1m" represent 10 seconds and 1 minute respectively. Example:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        healthCheckPath: ${management.server.servlet.context-path}/health
+        healthCheckInterval: 15s

+

You can disable the health check by setting management.health.consul.enabled=false.

3.3.1 Metadata and Consul tags

Consul does not yet support metadata on services. Spring Cloud’s ServiceInstance has a Map<String, String> metadata field. Spring Cloud Consul uses Consul tags to approximate metadata until Consul officially supports metadata. Tags with the form key=value will be split and used as a Map key and value respectively. Tags without the equal = sign, will be used as both the key and value.

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        tags: foo=bar, baz

+

The above configuration will result in a map with foo→bar and baz→baz.

3.3.2 Making the Consul Instance ID Unique

By default a consul instance is registered with an ID that is equal to its Spring Application Context ID. By default, the Spring Application Context ID is ${spring.application.name}:comma,separated,profiles:${server.port}. For most cases, this will allow multiple instances of one service to run on one machine. If further uniqueness is required, Using Spring Cloud you can override this by providing a unique identifier in spring.cloud.consul.discovery.instanceId. For example:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

+

With this metadata, and multiple service instances deployed on localhost, the random value will kick in there to make the instance unique. In Cloudfoundry the vcap.application.instance_id will be populated automatically in a Spring Boot application, so the random value will not be needed.

3.3.3 Applying Headers to Health Check Requests

Headers can be applied to health check requests. For example, if you’re trying to register a Spring Cloud Config server that uses Vault Backend:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        health-check-headers:
+          X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722

+

According to the HTTP standard, each header can have more than one values, in which case, an array can be supplied:

application.yml.  +

spring:
+  cloud:
+    consul:
+      discovery:
+        health-check-headers:
+          X-Config-Token:
+            - "6442e58b-d1ea-182e-cfa5-cf9cddef0722"
+            - "Some other value"

+

3.4 Looking up services

3.4.1 Using Ribbon

Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate +for looking up services using the logical service names/ids instead of physical URLs. Both Feign and the discovery-aware RestTemplate utilize Ribbon for client-side load balancing.

If you want to access service STORES using the RestTemplate simply declare:

@LoadBalanced
+@Bean
+public RestTemplate loadbalancedRestTemplate() {
+     new RestTemplate();
+}

and use it like this (notice how we use the STORES service name/id from Consul instead of a fully qualified domainname):

@Autowired
+RestTemplate restTemplate;
+
+public String getFirstProduct() {
+   return this.restTemplate.getForObject("https://STORES/products/1", String.class);
+}

If you have Consul clusters in multiple datacenters and you want to access a service in another datacenter a service name/id alone is not enough. In that case +you use property spring.cloud.consul.discovery.datacenters.STORES=dc-west where STORES is the service name/id and dc-west is the datacenter +where the STORES service lives.

3.4.2 Using the DiscoveryClient

You can also use the org.springframework.cloud.client.discovery.DiscoveryClient which provides a simple API for discovery clients that is not specific to Netflix, e.g.

@Autowired
+private DiscoveryClient discoveryClient;
+
+public String serviceUrl() {
+    List<ServiceInstance> list = discoveryClient.getInstances("STORES");
+    if (list != null && list.size() > 0 ) {
+        return list.get(0).getUri();
+    }
+    return null;
+}

3.5 Consul Catalog Watch

The Consul Catalog Watch takes advantage of the ability of consul to watch services. The Catalog Watch makes a blocking Consul HTTP API call to determine if any services have changed. If there is new service data a Heartbeat Event is published.

To change the frequency of when the Config Watch is called change spring.cloud.consul.config.discovery.catalog-services-watch-delay. The default value is 1000, which is in milliseconds. The delay is the amount of time after the end of the previous invocation and the start of the next.

To disable the Catalog Watch set spring.cloud.consul.discovery.catalogServicesWatch.enabled=false.

The watch uses a Spring TaskScheduler to schedule the call to consul. By default it is a ThreadPoolTaskScheduler with a poolSize of 1. To change the TaskScheduler, create a bean of type TaskScheduler named with the ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME constant.

4. Distributed Configuration with Consul

Consul provides a Key/Value Store for storing configuration and other metadata. Spring Cloud Consul Config is an alternative to the Config Server and Client. Configuration is loaded into the Spring Environment during the special "bootstrap" phase. Configuration is stored in the /config folder by default. Multiple PropertySource instances are created based on the application’s name and the active profiles that mimicks the Spring Cloud Config order of resolving properties. For example, an application with the name "testApp" and with the "dev" profile will have the following property sources created:

config/testApp,dev/
+config/testApp/
+config/application,dev/
+config/application/

The most specific property source is at the top, with the least specific at the bottom. Properties in the config/application folder are applicable to all applications using consul for configuration. Properties in the config/testApp folder are only available to the instances of the service named "testApp".

Configuration is currently read on startup of the application. Sending a HTTP POST to /refresh will cause the configuration to be reloaded. Section 4.3, “Config Watch” will also automatically detect changes and reload the application context.

4.1 How to activate

To get started with Consul Configuration use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-config. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

This will enable auto-configuration that will setup Spring Cloud Consul Config.

4.2 Customizing

Consul Config may be customized using the following properties:

bootstrap.yml.  +

spring:
+  cloud:
+    consul:
+      config:
+        enabled: true
+        prefix: configuration
+        defaultContext: apps
+        profileSeparator: '::'

+

  • enabled setting this value to "false" disables Consul Config
  • prefix sets the base folder for configuration values
  • defaultContext sets the folder name used by all applications
  • profileSeparator sets the value of the separator used to separate the profile name in property sources with profiles

4.3 Config Watch

The Consul Config Watch takes advantage of the ability of consul to watch a key prefix. The Config Watch makes a blocking Consul HTTP API call to determine if any relevant configuration data has changed for the current application. If there is new configuration data a Refresh Event is published. This is equivalent to calling the /refresh actuator endpoint.

To change the frequency of when the Config Watch is called change spring.cloud.consul.config.watch.delay. The default value is 1000, which is in milliseconds. The delay is the amount of time after the end of the previous invocation and the start of the next.

To disable the Config Watch set spring.cloud.consul.config.watch.enabled=false.

The watch uses a Spring TaskScheduler to schedule the call to consul. By default it is a ThreadPoolTaskScheduler with a poolSize of 1. To change the TaskScheduler, create a bean of type TaskScheduler named with the ConsulConfigAutoConfiguration.CONFIG_WATCH_TASK_SCHEDULER_NAME constant.

4.4 YAML or Properties with Config

It may be more convenient to store a blob of properties in YAML or Properties format as opposed to individual key/value pairs. Set the spring.cloud.consul.config.format property to YAML or PROPERTIES. For example to use YAML:

bootstrap.yml.  +

spring:
+  cloud:
+    consul:
+      config:
+        format: YAML

+

YAML must be set in the appropriate data key in consul. Using the defaults above the keys would look like:

config/testApp,dev/data
+config/testApp/data
+config/application,dev/data
+config/application/data

You could store a YAML document in any of the keys listed above.

You can change the data key using spring.cloud.consul.config.data-key.

4.5 git2consul with Config

git2consul is a Consul community project that loads files from a git repository to individual keys into Consul. By default the names of the keys are names of the files. YAML and Properties files are supported with file extensions of .yml and .properties respectively. Set the spring.cloud.consul.config.format property to FILES. For example:

bootstrap.yml.  +

spring:
+  cloud:
+    consul:
+      config:
+        format: FILES

+

Given the following keys in /config, the development profile and an application name of foo:

.gitignore
+application.yml
+bar.properties
+foo-development.properties
+foo-production.yml
+foo.properties
+master.ref

the following property sources would be created:

config/foo-development.properties
+config/foo.properties
+config/application.yml

The value of each key needs to be a properly formatted YAML or Properties file.

4.6 Fail Fast

It may be convenient in certain circumstances (like local development or certain test scenarios) to not fail if consul isn’t available for configuration. Setting spring.cloud.consul.config.failFast=false in bootstrap.yml will cause the configuration module to log a warning rather than throw an exception. This will allow the application to continue startup normally.

5. Consul Retry

If you expect that the consul agent may occasionally be unavailable when +your app starts, you can ask it to keep trying after a failure. You need to add +spring-retry and spring-boot-starter-aop to your classpath. The default +behaviour is to retry 6 times with an initial backoff interval of 1000ms and an +exponential multiplier of 1.1 for subsequent backoffs. You can configure these +properties (and others) using spring.cloud.consul.retry.* configuration properties. +This works with both Spring Cloud Consul Config and Discovery registration.

[Tip]Tip

To take full control of the retry add a @Bean of type +RetryOperationsInterceptor with id "consulRetryInterceptor". Spring +Retry has a RetryInterceptorBuilder that makes it easy to create one.

6. Spring Cloud Bus with Consul

6.1 How to activate

To get started with the Consul Bus use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-bus. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

See the Spring Cloud Bus documentation for the available actuator endpoints and howto send custom messages.

7. Circuit Breaker with Hystrix

Applications can use the Hystrix Circuit Breaker provided by the Spring Cloud Netflix project by including this starter in the projects pom.xml: spring-cloud-starter-hystrix. Hystrix doesn’t depend on the Netflix Discovery Client. The @EnableHystrix annotation should be placed on a configuration class (usually the main class). Then methods can be annotated with @HystrixCommand to be protected by a circuit breaker. See the documentation for more details.

8. Hystrix metrics aggregation with Turbine and Consul

Turbine (provided by the Spring Cloud Netflix project), aggregates multiple instances Hystrix metrics streams, so the dashboard can display an aggregate view. Turbine uses the DiscoveryClient interface to lookup relevant instances. To use Turbine with Spring Cloud Consul, configure the Turbine application in a manner similar to the following examples:

pom.xml.  +

<dependency>
+    <groupId>org.springframework.cloud</groupId>
+    <artifactId>spring-cloud-netflix-turbine</artifactId>
+</dependency>
+<dependency>
+    <groupId>org.springframework.cloud</groupId>
+    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
+</dependency>

+

Notice that the Turbine dependency is not a starter. The turbine starter includes support for Netflix Eureka.

application.yml.  +

spring.application.name: turbine
+applications: consulhystrixclient
+turbine:
+  aggregator:
+    clusterConfig: ${applications}
+  appConfig: ${applications}

+

The clusterConfig and appConfig sections must match, so it’s useful to put the comma-separated list of service ID’s into a separate configuration property.

Turbine.java.  +

@EnableTurbine
+@SpringBootApplication
+public class Turbine {
+    public static void main(String[] args) {
+        SpringApplication.run(DemoturbinecommonsApplication.class, args);
+    }
+}

+

\ No newline at end of file diff --git a/spring-cloud-consul/2.1.0.M2/spring-cloud-consul.xml b/spring-cloud-consul/2.1.0.M2/spring-cloud-consul.xml new file mode 100644 index 00000000..1f48214c --- /dev/null +++ b/spring-cloud-consul/2.1.0.M2/spring-cloud-consul.xml @@ -0,0 +1,368 @@ + + + + + +Spring Cloud Consul +2018-11-18 + + + +2.1.0.M2 +This project provides Consul integrations for Spring Boot apps through autoconfiguration +and binding to the Spring Environment and other Spring programming model idioms. With a few +simple annotations you can quickly enable and configure the common patterns inside your +application and build large distributed systems with Consul based components. The +patterns provided include Service Discovery, Control Bus and Configuration. +Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Breaker +(Hystrix) are provided by integration with Spring Cloud Netflix. + + +Install Consul +Please see the installation documentation for instructions on how to install Consul. + + +Consul Agent +A Consul Agent client must be available to all Spring Cloud Consul applications. By default, the Agent client is expected to be at localhost:8500. See the Agent documentation for specifics on how to start an Agent client and how to connect to a cluster of Consul Agent Servers. For development, after you have installed consul, you may start a Consul Agent using the following command: +./src/main/bash/local_run_consul.sh +This will start an agent in server mode on port 8500, with the ui available at http://localhost:8500 + + +Service Discovery with Consul +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 very difficult to do and can be very brittle. Consul provides Service Discovery services via an HTTP API and DNS. Spring Cloud Consul leverages the HTTP API for service registration and discovery. This does not prevent non-Spring Cloud applications from leveraging the DNS interface. Consul Agents servers are run in a cluster that communicates via a gossip protocol and uses the Raft consensus protocol. +
+How to activate +To activate Consul Service Discovery use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-discovery. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train. +
+
+Registering with Consul +When a client registers with Consul, it provides meta-data about itself such as host and port, id, name and tags. An HTTP Check is created by default that Consul hits the /health endpoint every 10 seconds. If the health check fails, the service instance is marked as critical. +Example Consul client: +@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); + } + +} +(i.e. utterly normal Spring Boot app). If the Consul client is located somewhere other than localhost:8500, the configuration is required to locate the client. Example: + +application.yml + +spring: + cloud: + consul: + host: localhost + port: 8500 + + + +If you use Spring Cloud Consul Config, the above values will need to be placed in bootstrap.yml instead of application.yml. + +The default service name, instance id and port, taken from the Environment, are ${spring.application.name}, the Spring Context ID and ${server.port} respectively. +To disable the Consul Discovery Client you can set spring.cloud.consul.discovery.enabled to false. +To disable the service registration you can set spring.cloud.consul.discovery.register to false. +
+
+HTTP Health Check +The health check for a Consul instance defaults to "/health", which is the default locations of a useful endpoint in a Spring Boot Actuator application. You need to change these, even for an Actuator application if you use a non-default context path or servlet path (e.g. server.servletPath=/foo) or management endpoint path (e.g. management.server.servlet.context-path=/admin). The interval that Consul uses to check the health endpoint may also be configured. "10s" and "1m" represent 10 seconds and 1 minute respectively. Example: + +application.yml + +spring: + cloud: + consul: + discovery: + healthCheckPath: ${management.server.servlet.context-path}/health + healthCheckInterval: 15s + + +You can disable the health check by setting management.health.consul.enabled=false. +
+Metadata and Consul tags +Consul does not yet support metadata on services. Spring Cloud’s ServiceInstance has a Map<String, String> metadata field. Spring Cloud Consul uses Consul tags to approximate metadata until Consul officially supports metadata. Tags with the form key=value will be split and used as a Map key and value respectively. Tags without the equal = sign, will be used as both the key and value. + +application.yml + +spring: + cloud: + consul: + discovery: + tags: foo=bar, baz + + +The above configuration will result in a map with foo→bar and baz→baz. +
+
+Making the Consul Instance ID Unique +By default a consul instance is registered with an ID that is equal to its Spring Application Context ID. By default, the Spring Application Context ID is ${spring.application.name}:comma,separated,profiles:${server.port}. For most cases, this will allow multiple instances of one service to run on one machine. If further uniqueness is required, Using Spring Cloud you can override this by providing a unique identifier in spring.cloud.consul.discovery.instanceId. For example: + +application.yml + +spring: + cloud: + consul: + discovery: + instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}} + + +With this metadata, and multiple service instances deployed on localhost, the random value will kick in there to make the instance unique. In Cloudfoundry the vcap.application.instance_id will be populated automatically in a Spring Boot application, so the random value will not be needed. +
+
+Applying Headers to Health Check Requests +Headers can be applied to health check requests. For example, if you’re trying to register a Spring Cloud Config server that uses Vault Backend: + +application.yml + +spring: + cloud: + consul: + discovery: + health-check-headers: + X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722 + + +According to the HTTP standard, each header can have more than one values, in which case, an array can be supplied: + +application.yml + +spring: + cloud: + consul: + discovery: + health-check-headers: + X-Config-Token: + - "6442e58b-d1ea-182e-cfa5-cf9cddef0722" + - "Some other value" + + +
+
+
+Looking up services +
+Using Ribbon +Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate +for looking up services using the logical service names/ids instead of physical URLs. Both Feign and the discovery-aware RestTemplate utilize Ribbon for client-side load balancing. +If you want to access service STORES using the RestTemplate simply declare: +@LoadBalanced +@Bean +public RestTemplate loadbalancedRestTemplate() { + new RestTemplate(); +} +and use it like this (notice how we use the STORES service name/id from Consul instead of a fully qualified domainname): +@Autowired +RestTemplate restTemplate; + +public String getFirstProduct() { + return this.restTemplate.getForObject("https://STORES/products/1", String.class); +} +If you have Consul clusters in multiple datacenters and you want to access a service in another datacenter a service name/id alone is not enough. In that case +you use property spring.cloud.consul.discovery.datacenters.STORES=dc-west where STORES is the service name/id and dc-west is the datacenter +where the STORES service lives. +
+
+Using the DiscoveryClient +You can also use the org.springframework.cloud.client.discovery.DiscoveryClient which provides a simple API for discovery clients that is not specific to Netflix, e.g. +@Autowired +private DiscoveryClient discoveryClient; + +public String serviceUrl() { + List<ServiceInstance> list = discoveryClient.getInstances("STORES"); + if (list != null && list.size() > 0 ) { + return list.get(0).getUri(); + } + return null; +} +
+
+
+Consul Catalog Watch +The Consul Catalog Watch takes advantage of the ability of consul to watch services. The Catalog Watch makes a blocking Consul HTTP API call to determine if any services have changed. If there is new service data a Heartbeat Event is published. +To change the frequency of when the Config Watch is called change spring.cloud.consul.config.discovery.catalog-services-watch-delay. The default value is 1000, which is in milliseconds. The delay is the amount of time after the end of the previous invocation and the start of the next. +To disable the Catalog Watch set spring.cloud.consul.discovery.catalogServicesWatch.enabled=false. +The watch uses a Spring TaskScheduler to schedule the call to consul. By default it is a ThreadPoolTaskScheduler with a poolSize of 1. To change the TaskScheduler, create a bean of type TaskScheduler named with the ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME constant. +
+
+ +Distributed Configuration with Consul +Consul provides a Key/Value Store for storing configuration and other metadata. Spring Cloud Consul Config is an alternative to the Config Server and Client. Configuration is loaded into the Spring Environment during the special "bootstrap" phase. Configuration is stored in the /config folder by default. Multiple PropertySource instances are created based on the application’s name and the active profiles that mimicks the Spring Cloud Config order of resolving properties. For example, an application with the name "testApp" and with the "dev" profile will have the following property sources created: +config/testApp,dev/ +config/testApp/ +config/application,dev/ +config/application/ +The most specific property source is at the top, with the least specific at the bottom. Properties in the config/application folder are applicable to all applications using consul for configuration. Properties in the config/testApp folder are only available to the instances of the service named "testApp". +Configuration is currently read on startup of the application. Sending a HTTP POST to /refresh will cause the configuration to be reloaded. will also automatically detect changes and reload the application context. +
+How to activate +To get started with Consul Configuration use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-config. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train. +This will enable auto-configuration that will setup Spring Cloud Consul Config. +
+
+Customizing +Consul Config may be customized using the following properties: + +bootstrap.yml + +spring: + cloud: + consul: + config: + enabled: true + prefix: configuration + defaultContext: apps + profileSeparator: '::' + + + + +enabled setting this value to "false" disables Consul Config + + +prefix sets the base folder for configuration values + + +defaultContext sets the folder name used by all applications + + +profileSeparator sets the value of the separator used to separate the profile name in property sources with profiles + + +
+
+Config Watch +The Consul Config Watch takes advantage of the ability of consul to watch a key prefix. The Config Watch makes a blocking Consul HTTP API call to determine if any relevant configuration data has changed for the current application. If there is new configuration data a Refresh Event is published. This is equivalent to calling the /refresh actuator endpoint. +To change the frequency of when the Config Watch is called change spring.cloud.consul.config.watch.delay. The default value is 1000, which is in milliseconds. The delay is the amount of time after the end of the previous invocation and the start of the next. +To disable the Config Watch set spring.cloud.consul.config.watch.enabled=false. +The watch uses a Spring TaskScheduler to schedule the call to consul. By default it is a ThreadPoolTaskScheduler with a poolSize of 1. To change the TaskScheduler, create a bean of type TaskScheduler named with the ConsulConfigAutoConfiguration.CONFIG_WATCH_TASK_SCHEDULER_NAME constant. +
+
+YAML or Properties with Config +It may be more convenient to store a blob of properties in YAML or Properties format as opposed to individual key/value pairs. Set the spring.cloud.consul.config.format property to YAML or PROPERTIES. For example to use YAML: + +bootstrap.yml + +spring: + cloud: + consul: + config: + format: YAML + + +YAML must be set in the appropriate data key in consul. Using the defaults above the keys would look like: +config/testApp,dev/data +config/testApp/data +config/application,dev/data +config/application/data +You could store a YAML document in any of the keys listed above. +You can change the data key using spring.cloud.consul.config.data-key. +
+
+git2consul with Config +git2consul is a Consul community project that loads files from a git repository to individual keys into Consul. By default the names of the keys are names of the files. YAML and Properties files are supported with file extensions of .yml and .properties respectively. Set the spring.cloud.consul.config.format property to FILES. For example: + +bootstrap.yml + +spring: + cloud: + consul: + config: + format: FILES + + +Given the following keys in /config, the development profile and an application name of foo: +.gitignore +application.yml +bar.properties +foo-development.properties +foo-production.yml +foo.properties +master.ref +the following property sources would be created: +config/foo-development.properties +config/foo.properties +config/application.yml +The value of each key needs to be a properly formatted YAML or Properties file. +
+
+Fail Fast +It may be convenient in certain circumstances (like local development or certain test scenarios) to not fail if consul isn’t available for configuration. Setting spring.cloud.consul.config.failFast=false in bootstrap.yml will cause the configuration module to log a warning rather than throw an exception. This will allow the application to continue startup normally. +
+
+ +Consul Retry +If you expect that the consul agent may occasionally be unavailable when +your app starts, you can ask it to keep trying after a failure. You need to add +spring-retry and spring-boot-starter-aop to your classpath. The default +behaviour is to retry 6 times with an initial backoff interval of 1000ms and an +exponential multiplier of 1.1 for subsequent backoffs. You can configure these +properties (and others) using spring.cloud.consul.retry.* configuration properties. +This works with both Spring Cloud Consul Config and Discovery registration. + +To take full control of the retry add a @Bean of type +RetryOperationsInterceptor with id "consulRetryInterceptor". Spring +Retry has a RetryInterceptorBuilder that makes it easy to create one. + + + +Spring Cloud Bus with Consul +
+How to activate +To get started with the Consul Bus use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-bus. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train. +See the Spring Cloud Bus documentation for the available actuator endpoints and howto send custom messages. +
+
+ +Circuit Breaker with Hystrix +Applications can use the Hystrix Circuit Breaker provided by the Spring Cloud Netflix project by including this starter in the projects pom.xml: spring-cloud-starter-hystrix. Hystrix doesn’t depend on the Netflix Discovery Client. The @EnableHystrix annotation should be placed on a configuration class (usually the main class). Then methods can be annotated with @HystrixCommand to be protected by a circuit breaker. See the documentation for more details. + + +Hystrix metrics aggregation with Turbine and Consul +Turbine (provided by the Spring Cloud Netflix project), aggregates multiple instances Hystrix metrics streams, so the dashboard can display an aggregate view. Turbine uses the DiscoveryClient interface to lookup relevant instances. To use Turbine with Spring Cloud Consul, configure the Turbine application in a manner similar to the following examples: + +pom.xml + +<dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-netflix-turbine</artifactId> +</dependency> +<dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-starter-consul-discovery</artifactId> +</dependency> + + +Notice that the Turbine dependency is not a starter. The turbine starter includes support for Netflix Eureka. + +application.yml + +spring.application.name: turbine +applications: consulhystrixclient +turbine: + aggregator: + clusterConfig: ${applications} + appConfig: ${applications} + + +The clusterConfig and appConfig sections must match, so it’s useful to put the comma-separated list of service ID’s into a separate configuration property. + +Turbine.java + +@EnableTurbine +@SpringBootApplication +public class Turbine { + public static void main(String[] args) { + SpringApplication.run(DemoturbinecommonsApplication.class, args); + } +} + + + +
\ No newline at end of file