From b176b54c7f5f7e104f61d1b9daf983cc9c5a0b05 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Thu, 28 Jun 2018 20:06:14 +0000 Subject: [PATCH] Sync docs from v1.4.4.RELEASE to gh-pages --- .../1.4.4.RELEASE/css/highlight.css | 35 + .../1.4.4.RELEASE/css/manual-multipage.css | 9 + .../1.4.4.RELEASE/css/manual-singlepage.css | 6 + .../1.4.4.RELEASE/css/manual.css | 344 ++++ spring-cloud-config/1.4.4.RELEASE/ghpages.sh | 330 ++++ .../1.4.4.RELEASE/images/background.png | Bin 0 -> 18255 bytes .../1.4.4.RELEASE/images/callouts/1.png | Bin 0 -> 329 bytes .../1.4.4.RELEASE/images/callouts/2.png | Bin 0 -> 353 bytes .../1.4.4.RELEASE/images/callouts/3.png | Bin 0 -> 350 bytes .../1.4.4.RELEASE/images/caution.png | Bin 0 -> 2099 bytes .../1.4.4.RELEASE/images/important.png | Bin 0 -> 2085 bytes .../1.4.4.RELEASE/images/logo.png | Bin 0 -> 4387 bytes .../1.4.4.RELEASE/images/note.png | Bin 0 -> 2257 bytes .../1.4.4.RELEASE/images/tip.png | Bin 0 -> 931 bytes .../1.4.4.RELEASE/images/warning.png | Bin 0 -> 2130 bytes spring-cloud-config/1.4.4.RELEASE/index.html | 117 ++ .../1.4.4.RELEASE/multi/css/highlight.css | 35 + .../multi/css/manual-multipage.css | 9 + .../multi/css/manual-singlepage.css | 6 + .../1.4.4.RELEASE/multi/css/manual.css | 344 ++++ .../1.4.4.RELEASE/multi/images/background.png | Bin 0 -> 18255 bytes .../1.4.4.RELEASE/multi/images/callouts/1.png | Bin 0 -> 329 bytes .../1.4.4.RELEASE/multi/images/callouts/2.png | Bin 0 -> 353 bytes .../1.4.4.RELEASE/multi/images/callouts/3.png | Bin 0 -> 350 bytes .../1.4.4.RELEASE/multi/images/caution.png | Bin 0 -> 2099 bytes .../1.4.4.RELEASE/multi/images/important.png | Bin 0 -> 2085 bytes .../1.4.4.RELEASE/multi/images/logo.png | Bin 0 -> 4387 bytes .../1.4.4.RELEASE/multi/images/note.png | Bin 0 -> 2257 bytes .../1.4.4.RELEASE/multi/images/tip.png | Bin 0 -> 931 bytes .../1.4.4.RELEASE/multi/images/warning.png | Bin 0 -> 2130 bytes .../multi__embedding_the_config_server.html | 21 + ...sh_notifications_and_spring_cloud_bus.html | 30 + .../multi/multi__quick_start.html | 105 ++ .../multi__serving_alternative_formats.html | 25 + .../multi/multi__serving_plain_text.html | 40 + .../multi__spring_cloud_config_client.html | 117 ++ .../multi__spring_cloud_config_server.html | 598 +++++++ .../1.4.4.RELEASE/multi/multi_pr01.html | 3 + .../multi/multi_spring-cloud-config.html | 3 + .../1.4.4.RELEASE/single/css/highlight.css | 35 + .../single/css/manual-multipage.css | 9 + .../single/css/manual-singlepage.css | 6 + .../1.4.4.RELEASE/single/css/manual.css | 344 ++++ .../single/images/background.png | Bin 0 -> 18255 bytes .../single/images/callouts/1.png | Bin 0 -> 329 bytes .../single/images/callouts/2.png | Bin 0 -> 353 bytes .../single/images/callouts/3.png | Bin 0 -> 350 bytes .../1.4.4.RELEASE/single/images/caution.png | Bin 0 -> 2099 bytes .../1.4.4.RELEASE/single/images/important.png | Bin 0 -> 2085 bytes .../1.4.4.RELEASE/single/images/logo.png | Bin 0 -> 4387 bytes .../1.4.4.RELEASE/single/images/note.png | Bin 0 -> 2257 bytes .../1.4.4.RELEASE/single/images/tip.png | Bin 0 -> 931 bytes .../1.4.4.RELEASE/single/images/warning.png | Bin 0 -> 2130 bytes .../single/spring-cloud-config.html | 918 ++++++++++ .../1.4.4.RELEASE/spring-cloud-config.xml | 1528 +++++++++++++++++ 55 files changed, 5017 insertions(+) create mode 100644 spring-cloud-config/1.4.4.RELEASE/css/highlight.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/css/manual-multipage.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/css/manual-singlepage.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/css/manual.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/ghpages.sh create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/background.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/callouts/1.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/callouts/2.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/callouts/3.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/caution.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/important.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/logo.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/note.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/tip.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/images/warning.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/index.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/css/highlight.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/css/manual-multipage.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/css/manual-singlepage.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/css/manual.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/background.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/callouts/1.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/callouts/2.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/callouts/3.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/caution.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/important.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/logo.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/note.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/tip.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/images/warning.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi__embedding_the_config_server.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi__push_notifications_and_spring_cloud_bus.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi__quick_start.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_alternative_formats.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_plain_text.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_client.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_server.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi_pr01.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/multi/multi_spring-cloud-config.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/css/highlight.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/css/manual-multipage.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/css/manual-singlepage.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/css/manual.css create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/background.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/callouts/1.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/callouts/2.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/callouts/3.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/caution.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/important.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/logo.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/note.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/tip.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/images/warning.png create mode 100644 spring-cloud-config/1.4.4.RELEASE/single/spring-cloud-config.html create mode 100644 spring-cloud-config/1.4.4.RELEASE/spring-cloud-config.xml diff --git a/spring-cloud-config/1.4.4.RELEASE/css/highlight.css b/spring-cloud-config/1.4.4.RELEASE/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/css/manual-multipage.css b/spring-cloud-config/1.4.4.RELEASE/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/css/manual-singlepage.css b/spring-cloud-config/1.4.4.RELEASE/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/css/manual.css b/spring-cloud-config/1.4.4.RELEASE/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/ghpages.sh b/spring-cloud-config/1.4.4.RELEASE/ghpages.sh new file mode 100644 index 00000000..57c5da3a --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/images/background.png b/spring-cloud-config/1.4.4.RELEASE/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..15dca6fbe2669fae3609605e49c69cc414f1b6ed GIT binary patch literal 18255 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 EKU&lfD*ylh literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/images/callouts/1.png b/spring-cloud-config/1.4.4.RELEASE/images/callouts/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d473430b7bec514f7de12f5769fe7c5859e8c5d GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}^nQC}X^4DKU-G|w_t}fLBA)Suv#nrW z!^h2QnY_`l!BOq-UXEX{m2up>JTQkX)2m zTvF+fTUlI^nXH#utd~++ke^qgmzgTe~DWM4ffP81J literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/images/callouts/2.png b/spring-cloud-config/1.4.4.RELEASE/images/callouts/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5d09341b2f6d2ea2d1d5dad5d980f14b4b05dfd2 GIT binary patch literal 353 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 literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/images/logo.png b/spring-cloud-config/1.4.4.RELEASE/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ade2ce6ed9d9e9f2f4d9c5729a252ee618a0a5a7 GIT binary patch literal 4387 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 FV1jwin)(0$ literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/images/warning.png b/spring-cloud-config/1.4.4.RELEASE/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5b5244605adbb7ab05a1549746a9c35490f95b GIT binary patch literal 2130 zcmbVNYg7|w8V(4q($)50y>JmGlLW#g$xLn}Vd2Si)}#|ptPAQp3Bp-3!-lL0;i^LY?;i#f0m5s49g z3h?3rDQg~EDPlm?FKkgKIcWEK-3X6YU0uzs7H|nq84s39r2!5;pF?SI$QqXy^Ko1x zV~zpENvp@<_Bsd`5MabC#3rvCq&$5dg43yGR zAdy0-rWjC#a1N_+kzUMY#pmogD7!DP(9dEKr3c5ngvUq_6>}Y+w-a81v=eSXnIi_+ zI?U>D1q2C!0zHox#XXKH+@|&rPT*OF5yvY$5J|)WwLqnU)c-5;=UChSlQkaY3@^|g z|J5#YBB}=i+n3Ex9bS$P?xJSKLk)-HHII@;3qG#TG^!+aj>0QkO~7kB0+|yM;YrGB zF>Ge@isQ#73%Tp#k_(tInh3U$uJWY-+DND*o}L-CB5g@#9YWWw~pxZ!Obm>yN#ZHFvL0zA3vNCTJ=t?)~`2O1M{L6un=ml<2x zQEYfifmA?Pz0tqRs^2Utt1pU0BQB1eIY0U_I}c1Y#PP7Ci5s7#IJn}xK{G+{_v^Z+1V#$Erodv>d}ew>RP0wzw+GWkGCBlS1Oj5Z!5NK zUuSR6>pa}RSEZ;qE_w1l#`hQX4E67U6NeP zHZ`T&wj0_H)t|Y1thUqnhub?%e)Y07;a^Tq%FO&iQkR&`qG!dh*2WfW(HuRQj*_DI zeCD1bUA|tMwjOb8E|FRIn$pzEU!2j_N}1Z2ig)vbr5xA0rjC70cmI6*%Uf->hWzaZ z{33HABO5q)vRhzDly2l691@+q3O{}NbSzx+I*k@|L4&3leK#$>u+T#TvTELfKb|IH zc23atf3vmfCa0&TWY@iuoA_Pm<0~ttEC*ut`isb^jXS>X^Sp=l?RXN_OJ*&usGXg$ zTlTv;Ch^vhLDf&+62jl64*&D+=+`sN_dap_1W%p|KQVYIdgPL5uRE9(c4On)DXndL zLNq?%!-u*zmMxyYc4m4Nr>>=A=s}PkJkqr&E^b9>5g+}c1%X}3|WKcg&spcJQ)05zI<<5LTBhNKRg$XRTi2{j)yl_ zj4~kKOvr+m(;vw~9zVh(zC-y9jqQnguz5r7FRq^MyKuXAENp(TAzUVtg&Ts+B_s7) zGn+fN0sG>9GjsPLKTRrvCd`71IZulJ1_1jO9KWbD&_@2UC+LTNpxxrdz#E|j|2nA9 zzB!UTyfAEJ&#%$pQ>QX#8vk@_a5iqukMF;8`wRKe{BI}5$H%OROs4J1#j)|?p|YSh z_SpR^e`VE#F52;WL{!+L(yZLRh40*KS;@box;9(-tE)`mcVp27O*>Z{_Lb*5T3cJA yr~0nPHtg2+UHi&&$8ha;`+hiaUmw&!n@8(?5PqF(KE5>Ym)EG)p&uyBP5%a8^# + + + + + + +spring-cloud-config + + + + + + + +

+
+
+
+
+

1.4.4.RELEASE

+
+
+
+
+

Pick The Documentation Option

+
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/css/highlight.css b/spring-cloud-config/1.4.4.RELEASE/multi/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/multi/css/manual-multipage.css b/spring-cloud-config/1.4.4.RELEASE/multi/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/multi/css/manual-singlepage.css b/spring-cloud-config/1.4.4.RELEASE/multi/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/multi/css/manual.css b/spring-cloud-config/1.4.4.RELEASE/multi/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/multi/images/background.png b/spring-cloud-config/1.4.4.RELEASE/multi/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..15dca6fbe2669fae3609605e49c69cc414f1b6ed GIT binary patch literal 18255 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 EKU&lfD*ylh literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/images/callouts/1.png b/spring-cloud-config/1.4.4.RELEASE/multi/images/callouts/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d473430b7bec514f7de12f5769fe7c5859e8c5d GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}^nQC}X^4DKU-G|w_t}fLBA)Suv#nrW z!^h2QnY_`l!BOq-UXEX{m2up>JTQkX)2m zTvF+fTUlI^nXH#utd~++ke^qgmzgTe~DWM4ffP81J literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/images/callouts/2.png b/spring-cloud-config/1.4.4.RELEASE/multi/images/callouts/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5d09341b2f6d2ea2d1d5dad5d980f14b4b05dfd2 GIT binary patch literal 353 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 literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/images/logo.png b/spring-cloud-config/1.4.4.RELEASE/multi/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ade2ce6ed9d9e9f2f4d9c5729a252ee618a0a5a7 GIT binary patch literal 4387 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 FV1jwin)(0$ literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/images/warning.png b/spring-cloud-config/1.4.4.RELEASE/multi/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5b5244605adbb7ab05a1549746a9c35490f95b GIT binary patch literal 2130 zcmbVNYg7|w8V(4q($)50y>JmGlLW#g$xLn}Vd2Si)}#|ptPAQp3Bp-3!-lL0;i^LY?;i#f0m5s49g z3h?3rDQg~EDPlm?FKkgKIcWEK-3X6YU0uzs7H|nq84s39r2!5;pF?SI$QqXy^Ko1x zV~zpENvp@<_Bsd`5MabC#3rvCq&$5dg43yGR zAdy0-rWjC#a1N_+kzUMY#pmogD7!DP(9dEKr3c5ngvUq_6>}Y+w-a81v=eSXnIi_+ zI?U>D1q2C!0zHox#XXKH+@|&rPT*OF5yvY$5J|)WwLqnU)c-5;=UChSlQkaY3@^|g z|J5#YBB}=i+n3Ex9bS$P?xJSKLk)-HHII@;3qG#TG^!+aj>0QkO~7kB0+|yM;YrGB zF>Ge@isQ#73%Tp#k_(tInh3U$uJWY-+DND*o}L-CB5g@#9YWWw~pxZ!Obm>yN#ZHFvL0zA3vNCTJ=t?)~`2O1M{L6un=ml<2x zQEYfifmA?Pz0tqRs^2Utt1pU0BQB1eIY0U_I}c1Y#PP7Ci5s7#IJn}xK{G+{_v^Z+1V#$Erodv>d}ew>RP0wzw+GWkGCBlS1Oj5Z!5NK zUuSR6>pa}RSEZ;qE_w1l#`hQX4E67U6NeP zHZ`T&wj0_H)t|Y1thUqnhub?%e)Y07;a^Tq%FO&iQkR&`qG!dh*2WfW(HuRQj*_DI zeCD1bUA|tMwjOb8E|FRIn$pzEU!2j_N}1Z2ig)vbr5xA0rjC70cmI6*%Uf->hWzaZ z{33HABO5q)vRhzDly2l691@+q3O{}NbSzx+I*k@|L4&3leK#$>u+T#TvTELfKb|IH zc23atf3vmfCa0&TWY@iuoA_Pm<0~ttEC*ut`isb^jXS>X^Sp=l?RXN_OJ*&usGXg$ zTlTv;Ch^vhLDf&+62jl64*&D+=+`sN_dap_1W%p|KQVYIdgPL5uRE9(c4On)DXndL zLNq?%!-u*zmMxyYc4m4Nr>>=A=s}PkJkqr&E^b9>5g+}c1%X}3|WKcg&spcJQ)05zI<<5LTBhNKRg$XRTi2{j)yl_ zj4~kKOvr+m(;vw~9zVh(zC-y9jqQnguz5r7FRq^MyKuXAENp(TAzUVtg&Ts+B_s7) zGn+fN0sG>9GjsPLKTRrvCd`71IZulJ1_1jO9KWbD&_@2UC+LTNpxxrdz#E|j|2nA9 zzB!UTyfAEJ&#%$pQ>QX#8vk@_a5iqukMF;8`wRKe{BI}5$H%OROs4J1#j)|?p|YSh z_SpR^e`VE#F52;WL{!+L(yZLRh40*KS;@box;9(-tE)`mcVp27O*>Z{_Lb*5T3cJA yr~0nPHtg2+UHi&&$8ha;`+hiaUmw&!n@8(?5PqF(KE5>Ym)EG)p&uyBP5%a8^# + + 5. Embedding the Config Server

5. Embedding the Config Server

The Config Server runs best as a standalone application, but if you +need to you can embed it in another application. Just use the +@EnableConfigServer annotation. An optional property that can be +useful in this case is spring.cloud.config.server.bootstrap which is +a flag to indicate that the server should configure itself from its +own remote repository. The flag is off by default because it can delay +startup, but when embedded in another application it makes sense to +initialize the same way as any other application.

[Note]Note

It should be obvious, but remember that if you use the bootstrap +flag the config server will need to have its name and repository URI +configured in bootstrap.yml.

To change the location of the server endpoints you can (optionally) +set spring.cloud.config.server.prefix, e.g. "/config", to serve the +resources under a prefix. The prefix should start but not end with a +"/". It is applied to the @RequestMappings in the Config Server +(i.e. underneath the Spring Boot prefixes server.servletPath and +server.contextPath).

If you want to read the configuration for an application directly from +the backend repository (instead of from the config server) that’s +basically an embedded config server with no endpoints. You can switch +off the endpoints entirely if you don’t use the @EnableConfigServer +annotation (just set spring.cloud.config.server.bootstrap=true).

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi__push_notifications_and_spring_cloud_bus.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi__push_notifications_and_spring_cloud_bus.html new file mode 100644 index 00000000..2f484e3e --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi__push_notifications_and_spring_cloud_bus.html @@ -0,0 +1,30 @@ + + + 6. Push Notifications and Spring Cloud Bus

6. Push Notifications and Spring Cloud Bus

Many source code repository providers (like Github, Gitlab or Bitbucket +for instance) will notify you of changes in a repository through a +webhook. You can configure the webhook via the provider’s user +interface as a URL and a set of events in which you are +interested. For instance +Github +will POST to the webhook with a JSON body containing a list of +commits, and a header "X-Github-Event" equal to "push". If you add a +dependency on the spring-cloud-config-monitor library and activate +the Spring Cloud Bus in your Config Server, then a "/monitor" endpoint +is enabled.

When the webhook is activated the Config Server will send a +RefreshRemoteApplicationEvent targeted at the applications it thinks +might have changed. The change detection can be strategized, but by +default it just looks for changes in files that match the application +name (e.g. "foo.properties" is targeted at the "foo" application, and +"application.properties" is targeted at all applications). The strategy +if you want to override the behaviour is PropertyPathNotificationExtractor +which accepts the request headers and body as parameters and returns a list +of file paths that changed.

The default configuration works out of the box with Github, Gitlab or +Bitbucket. In addition to the JSON notifications from Github, Gitlab +or Bitbucket you can trigger a change notification by POSTing to +"/monitor" with a form-encoded body parameters path={name}. This will +broadcast to applications matching the "{name}" pattern (can contain +wildcards).

[Note]Note

the RefreshRemoteApplicationEvent will only be transmitted if +the spring-cloud-bus is activated in the Config Server and in the +client application.

[Note]Note

the default configuration also detects filesystem changes in +local git repositories (the webhook is not used in that case but as +soon as you edit a config file a refresh will be broadcast).

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi__quick_start.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi__quick_start.html new file mode 100644 index 00000000..2f6f6e17 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi__quick_start.html @@ -0,0 +1,105 @@ + + + 1. Quick Start

1. Quick Start

Start the server:

$ cd spring-cloud-config-server
+$ ../mvnw spring-boot:run

The server is a Spring Boot application so you can run it from your +IDE instead if you prefer (the main class is +ConfigServerApplication). Then try out a client:

$ curl localhost:8888/foo/development
+{"name":"foo","label":"master","propertySources":[
+  {"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}},
+  {"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}}
+]}

The default strategy for locating property sources is to clone a git +repository (at spring.cloud.config.server.git.uri) and use it to +initialize a mini SpringApplication. The mini-application’s +Environment is used to enumerate property sources and publish them +via a JSON endpoint.

The HTTP service has resources in the form:

/{application}/{profile}[/{label}]
+/{application}-{profile}.yml
+/{label}/{application}-{profile}.yml
+/{application}-{profile}.properties
+/{label}/{application}-{profile}.properties

where the "application" is injected as the spring.config.name in the +SpringApplication (i.e. what is normally "application" in a regular +Spring Boot app), "profile" is an active profile (or comma-separated +list of properties), and "label" is an optional git label (defaults to +"master".)

Spring Cloud Config Server pulls configuration for remote clients +from a git repository (which must be provided):

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo

1.1 Client Side Usage

To use these features in an application, just build it as a Spring +Boot application that depends on spring-cloud-config-client (e.g. see +the test cases for the config-client, or the sample app). The most +convenient way to add the dependency is via a Spring Boot starter +org.springframework.cloud:spring-cloud-starter-config. There is also a +parent pom and BOM (spring-cloud-starter-parent) for Maven users and a +Spring IO version management properties file for Gradle and Spring CLI +users. Example Maven configuration:

pom.xml.  +

   <parent>
+       <groupId>org.springframework.boot</groupId>
+       <artifactId>spring-boot-starter-parent</artifactId>
+       <version>1.5.10.RELEASE</version>
+       <relativePath /> <!-- lookup parent from repository -->
+   </parent>
+
+<dependencyManagement>
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-dependencies</artifactId>
+			<version>Edgware.SR2</version>
+			<type>pom</type>
+			<scope>import</scope>
+		</dependency>
+	</dependencies>
+</dependencyManagement>
+
+<dependencies>
+	<dependency>
+		<groupId>org.springframework.cloud</groupId>
+		<artifactId>spring-cloud-starter-config</artifactId>
+	</dependency>
+	<dependency>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-test</artifactId>
+		<scope>test</scope>
+	</dependency>
+</dependencies>
+
+<build>
+	<plugins>
+           <plugin>
+               <groupId>org.springframework.boot</groupId>
+               <artifactId>spring-boot-maven-plugin</artifactId>
+           </plugin>
+	</plugins>
+</build>
+
+   <!-- repositories also needed for snapshots and milestones -->

+

Then you can create a standard Spring Boot application, like this simple HTTP server:

@SpringBootApplication
+@RestController
+public class Application {
+
+    @RequestMapping("/")
+    public String home() {
+        return "Hello World!";
+    }
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+
+}

When it runs it will pick up the external configuration from the +default local config server on port 8888 if it is running. To modify +the startup behaviour you can change the location of the config server +using bootstrap.properties (like application.properties but for +the bootstrap phase of an application context), e.g.

spring.cloud.config.uri: http://myconfigserver.com

The bootstrap properties will show up in the /env endpoint as a +high-priority property source, e.g.

$ curl localhost:8080/env
+{
+  "profiles":[],
+  "configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"},
+  "servletContextInitParams":{},
+  "systemProperties":{...},
+  ...
+}

(a property source called "configService:<URL of remote +repository>/<file name>" contains the property "foo" with value +"bar" and is highest priority).

[Note]Note

the URL in the property source name is the git repository not +the config server URL.

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_alternative_formats.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_alternative_formats.html new file mode 100644 index 00000000..d89facda --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_alternative_formats.html @@ -0,0 +1,25 @@ + + + 3. Serving Alternative Formats

3. Serving Alternative Formats

The default JSON format from the environment endpoints is perfect for +consumption by Spring applications because it maps directly onto the +Environment abstraction. If you prefer you can consume the same data +as YAML or Java properties by adding a suffix to the resource path +(".yml", ".yaml" or ".properties"). This can be useful for consumption +by applications that do not care about the structure of the JSON +endpoints, or the extra metadata they provide, for example an +application that is not using Spring might benefit from the simplicity +of this approach.

The YAML and properties representations have an additional flag +(provided as a boolean query parameter resolvePlaceholders) to +signal that placeholders in the source documents, in the standard +Spring ${…​} form, should be resolved in the output where possible +before rendering. This is a useful feature for consumers that don’t +know about the Spring placeholder conventions.

[Note]Note

there are limitations in using the YAML or properties formats, +mainly in relation to the loss of metadata. The JSON is structured as +an ordered list of property sources, for example, with names that +correlate with the source. The YAML and properties forms are coalesced +into a single map, even if the origin of the values has multiple +sources, and the names of the original source files are lost. The YAML +representation is not necessarily a faithful representation of the +YAML source in a backing repository either: it is constructed from a +list of flat property sources, and assumptions have to be made about +the form of the keys.

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_plain_text.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_plain_text.html new file mode 100644 index 00000000..1d2e02af --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi__serving_plain_text.html @@ -0,0 +1,40 @@ + + + 4. Serving Plain Text

4. Serving Plain Text

Instead of using the Environment abstraction (or one of the +alternative representations of it in YAML or properties format) your +applications might need generic plain text configuration files, +tailored to their environment. The Config Server provides these +through an additional endpoint at /{name}/{profile}/{label}/{path} +where "name", "profile" and "label" have the same meaning as the +regular environment endpoint, but "path" is a file name +(e.g. log.xml). The source files for this endpoint are located in +the same way as for the environment endpoints: the same search path is +used as for properties or YAML files, but instead of aggregating all +matching resources, only the first one to match is returned.

After a resource is located, placeholders in the normal format +(${…​}) are resolved using the effective Environment for the +application name, profile and label supplied. In this way the resource +endpoint is tightly integrated with the environment +endpoints. Example, if you have this layout for a GIT (or SVN) +repository:

application.yml
+nginx.conf

where nginx.conf looks like this:

server {
+    listen              80;
+    server_name         ${nginx.server.name};
+}

and application.yml like this:

nginx:
+  server:
+    name: example.com
+---
+spring:
+  profiles: development
+nginx:
+  server:
+    name: develop.com

then the /foo/default/master/nginx.conf resource looks like this:

server {
+    listen              80;
+    server_name         example.com;
+}

and /foo/development/master/nginx.conf like this:

server {
+    listen              80;
+    server_name         develop.com;
+}
[Note]Note

Just like the source files for environment configuration, the +"profile" is used to resolve the file name, so if you want a +profile-specific file then /*/development/*/logback.xml will be +resolved by a file called logback-development.xml (in preference +to logback.xml).

[Note]Note

If you do not want to supply the label and let the server use the default label, you can supply a useDefaultLabel request parameter. So, the above example for the default profile could look like /foo/default/nginx.conf?useDefaultLabel.

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_client.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_client.html new file mode 100644 index 00000000..c7d52c01 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_client.html @@ -0,0 +1,117 @@ + + + 7. Spring Cloud Config Client

7. Spring Cloud Config Client

A Spring Boot application can take immediate advantage of the Spring +Config Server (or other external property sources provided by the +application developer), and it will also pick up some additional +useful features related to Environment change events.

7.1 Config First Bootstrap

This is the default behaviour for any application which has the Spring +Cloud Config Client on the classpath. When a config client starts up +it binds to the Config Server (via the bootstrap configuration +property spring.cloud.config.uri) and initializes Spring +Environment with remote property sources.

The net result of this is that all client apps that want to consume +the Config Server need a bootstrap.yml (or an environment variable) +with the server address in spring.cloud.config.uri (defaults to +"http://localhost:8888").

7.2 Discovery First Bootstrap

If you are using a `DiscoveryClient implementation, such as Spring Cloud Netflix +and Eureka Service Discovery or Spring Cloud Consul (Spring Cloud Zookeeper does +not support this yet), then you can have the Config Server register with the +Discovery Service if you want to, but in the default "Config First" mode, +clients won’t be able to take advantage of the registration.

If you prefer to use DiscoveryClient to locate the Config Server, you can do +that by setting spring.cloud.config.discovery.enabled=true (default +"false"). The net result of that is that client apps all need a +bootstrap.yml (or an environment variable) with the appropriate discovery +configuration. For example, with Spring Cloud Netflix, you need to define the +Eureka server address, e.g. in eureka.client.serviceUrl.defaultZone. The +price for using this option is an extra network round trip on start up to +locate the service registration. The benefit is that the Config Server +can change its co-ordinates, as long as the Discovery Service is a fixed point. The +default service id is "configserver" but you can change that on the +client with spring.cloud.config.discovery.serviceId (and on the server +in the usual way for a service, e.g. by setting spring.application.name).

The discovery client implementations all support some kind of metadata +map (e.g. for Eureka we have eureka.instance.metadataMap). Some +additional properties of the Config Server may need to be configured +in its service registration metadata so that clients can connect +correctly. If the Config Server is secured with HTTP Basic you can +configure the credentials as "username" and "password". And if the +Config Server has a context path you can set "configPath". Example, +for a Config Server that is a Eureka client:

bootstrap.yml.  +

eureka:
+  instance:
+    ...
+    metadataMap:
+      user: osufhalskjrtl
+      password: lviuhlszvaorhvlo5847
+      configPath: /config

+

7.3 Config Client Fail Fast

In some cases, it may be desirable to fail startup of a service if +it cannot connect to the Config Server. If this is the desired +behavior, set the bootstrap configuration property +spring.cloud.config.failFast=true and the client will halt with +an Exception.

7.4 Config Client Retry

If you expect that the config server may occasionally be unavailable when +your app starts, you can ask it to keep trying after a failure. First you need +to set spring.cloud.config.failFast=true, and then 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.config.retry.* configuration properties.

[Tip]Tip

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

7.5 Locating Remote Configuration Resources

The Config Service serves property sources from /{name}/{profile}/{label}, where the default bindings in the client app are

  • "name" = ${spring.application.name}
  • "profile" = ${spring.profiles.active} (actually Environment.getActiveProfiles())
  • "label" = "master"

All of them can be overridden by setting spring.cloud.config.* +(where * is "name", "profile" or "label"). The "label" is useful for +rolling back to previous versions of configuration; with the default +Config Server implementation it can be a git label, branch name or +commit id. Label can also be provided as a comma-separated list, in +which case the items in the list are tried on-by-one until one succeeds. +This can be useful when working on a feature branch, for instance, +when you might want to align the config label with your branch, but +make it optional (e.g. spring.cloud.config.label=myfeature,develop).

7.6 Security

If you use HTTP Basic security on the server then clients just need to +know the password (and username if it isn’t the default). You can do +that via the config server URI, or via separate username and password +properties, e.g.

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+     uri: https://user:secret@myconfig.mycompany.com

+

or

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+     uri: https://myconfig.mycompany.com
+     username: user
+     password: secret

+

The spring.cloud.config.password and spring.cloud.config.username +values override anything that is provided in the URI.

If you deploy your apps on Cloud Foundry then the best way to provide +the password is through service credentials, e.g. in the URI, since +then it doesn’t even need to be in a config file. An example which +works locally and for a user-provided service on Cloud Foundry named +"configserver":

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+     uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}

+

If you use another form of security you might need to provide a +RestTemplate to the ConfigServicePropertySourceLocator (e.g. by +grabbing it in the bootstrap context and injecting one).

7.6.1 Health Indicator

The Config Client supplies a Spring Boot Health Indicator that attempts to load configuration from Config Server. The health indicator can be disabled by setting health.config.enabled=false. The response is also cached for performance reasons. The default cache time to live is 5 minutes. To change that value set the health.config.time-to-live property (in milliseconds).

7.6.2 Providing A Custom RestTemplate

In some cases you might need to customize the requests made to the config server from +the client. Typically this involves passing special Authorization headers to +authenticate requests to the server. To provide a custom RestTemplate follow the +steps below.

  1. Create a new configuration bean with an implementation of PropertySourceLocator.

CustomConfigServiceBootstrapConfiguration.java.  +

@Configuration
+public class CustomConfigServiceBootstrapConfiguration {
+    @Bean
+    public ConfigServicePropertySourceLocator configServicePropertySourceLocator() {
+        ConfigClientProperties clientProperties = configClientProperties();
+       ConfigServicePropertySourceLocator configServicePropertySourceLocator =  new ConfigServicePropertySourceLocator(clientProperties);
+        configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties));
+        return configServicePropertySourceLocator;
+    }
+}

+

  1. In resources/META-INF create a file called +spring.factories and specify your custom configuration.

spring.factories.  +

org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration

+

7.6.3 Vault

When using Vault as a backend to your config server the client will need to +supply a token for the server to retrieve values from Vault. This token +can be provided within the client by setting spring.cloud.config.token +in bootstrap.yml.

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+      token: YourVaultToken

+

7.7 Vault

7.7.1 Nested Keys In Vault

Vault supports the ability to nest keys in a value stored in Vault. For example

echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp -

This command will write a JSON object to your Vault. To access these values in Spring +you would use the traditional dot(.) annotation. For example

@Value("${appA.secret}")
+String name = "World";

The above code would set the name variable to appAsecret.

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_server.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_server.html new file mode 100644 index 00000000..59a02dcf --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi__spring_cloud_config_server.html @@ -0,0 +1,598 @@ + + + 2. Spring Cloud Config Server

2. Spring Cloud Config Server

The Server provides an HTTP, resource-based API for external +configuration (name-value pairs, or equivalent YAML content). The +server is easily embeddable in a Spring Boot application using the +@EnableConfigServer annotation. So this app is a config server:

ConfigServer.java.  +

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

+

Like all Spring Boot apps it runs on port 8080 by default, but you +can switch it to the conventional port 8888 in various ways. The +easiest, which also sets a default configuration repository, +is by launching it with spring.config.name=configserver (there +is a configserver.yml in the Config Server jar). Another is +to use your own application.properties, e.g.

application.properties.  +

server.port: 8888
+spring.cloud.config.server.git.uri: file://${user.home}/config-repo

+

where ${user.home}/config-repo is a git repository containing +YAML and properties files.

[Note]Note

in Windows you need an extra "/" in the file URL if it is +absolute with a drive prefix, e.g. file:///${user.home}/config-repo.

[Tip]Tip

Here’s a recipe for creating the git repository in the example +above:

$ cd $HOME
+$ mkdir config-repo
+$ cd config-repo
+$ git init .
+$ echo info.foo: bar > application.properties
+$ git add -A .
+$ git commit -m "Add application.properties"
[Warning]Warning

using the local filesystem for your git repository is +intended for testing only. Use a server to host your +configuration repositories in production.

[Warning]Warning

the initial clone of your configuration repository will +be quick and efficient if you only keep text files in it. If you start +to store binary files, especially large ones, you may experience +delays on the first request for configuration and/or out of memory +errors in the server.

2.1 Environment Repository

Where do you want to store the configuration data for the Config +Server? The strategy that governs this behaviour is the +EnvironmentRepository, serving Environment objects. This +Environment is a shallow copy of the domain from the Spring +Environment (including propertySources as the main feature). The +Environment resources are parametrized by three variables:

  • {application} maps to "spring.application.name" on the client side;
  • {profile} maps to "spring.profiles.active" on the client (comma separated list); and
  • {label} which is a server side feature labelling a "versioned" set of config files.

Repository implementations generally behave just like a Spring Boot +application loading configuration files from a "spring.config.name" +equal to the {application} parameter, and "spring.profiles.active" +equal to the {profiles} parameter. Precedence rules for profiles are +also the same as in a regular Boot application: active profiles take +precedence over defaults, and if there are multiple profiles the last +one wins (like adding entries to a Map).

Example: a client application has this bootstrap configuration:

bootstrap.yml.  +

spring:
+  application:
+    name: foo
+  profiles:
+    active: dev,mysql

+

(as usual with a Spring Boot application, these properties could also +be set as environment variables or command line arguments).

If the repository is file-based, the server will create an +Environment from application.yml (shared between all clients), and +foo.yml (with foo.yml taking precedence). If the YAML files have +documents inside them that point to Spring profiles, those are applied +with higher precedence (in order of the profiles listed), and if +there are profile-specific YAML (or properties) files these are also +applied with higher precedence than the defaults. Higher precedence +translates to a PropertySource listed earlier in the +Environment. (These are the same rules as apply in a standalone +Spring Boot application.)

2.1.1 Git Backend

The default implementation of EnvironmentRepository uses a Git +backend, which is very convenient for managing upgrades and physical +environments, and also for auditing changes. To change the location of +the repository you can set the "spring.cloud.config.server.git.uri" +configuration property in the Config Server (e.g. in +application.yml). If you set it with a file: prefix it should work +from a local repository so you can get started quickly and easily +without a server, but in that case the server operates directly on the +local repository without cloning it (it doesn’t matter if it’s not +bare because the Config Server never makes changes to the "remote" +repository). To scale the Config Server up and make it highly +available, you would need to have all instances of the server pointing +to the same repository, so only a shared file system would work. Even +in that case it is better to use the ssh: protocol for a shared +filesystem repository, so that the server can clone it and use a local +working copy as a cache.

This repository implementation maps the {label} parameter of the +HTTP resource to a git label (commit id, branch name or tag). If the +git branch or tag name contains a slash ("/") then the label in the +HTTP URL should be specified with the special string "(_)" instead (to +avoid ambiguity with other URL paths). For example, if the label is +foo/bar, replacing the slash would result in a label that looks like +foo(_)bar. The inclusion of the special string "(_)" can also be +applied to the {application} parameter. Be careful with the brackets +in the URL if you are using a command line client like curl (e.g. +escape them from the shell with quotes '').

Placeholders in Git URI

Spring Cloud Config Server supports a git repository URL with +placeholders for the {application} and {profile} (and {label} if +you need it, but remember that the label is applied as a git label +anyway). So you can easily support a "one repo per application" policy +using (for example):

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/myorg/{application}

or a "one repo per profile" policy using a similar pattern but with +{profile}.

Additionally, using the special string "(_)" within your +{application} parameters can enable support for multiple +organizations (for example):

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/{application}

where {application} is provided at request time in the format +"organization(_)application".

Pattern Matching and Multiple Repositories

There is also support for more complex requirements with pattern +matching on the application and profile name. The pattern format is a +comma-separated list of {application}/{profile} names with wildcards +(where a pattern beginning with a wildcard may need to be +quoted). Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          repos:
+            simple: https://github.com/simple/config-repo
+            special:
+              pattern: special*/dev*,*special*/dev*
+              uri: https://github.com/special/config-repo
+            local:
+              pattern: local*
+              uri: file:/home/configsvc/config-repo

If {application}/{profile} does not match any of the patterns, it +will use the default uri defined under +"spring.cloud.config.server.git.uri". In the above example, for the +"simple" repository, the pattern is simple/* (i.e. it only matches +one application named "simple" in all profiles). The "local" +repository matches all application names beginning with "local" in all +profiles (the /* suffix is added automatically to any pattern that +doesn’t have a profile matcher).

[Note]Note

the "one-liner" short cut used in the "simple" example above can +only be used if the only property to be set is the URI. If you need to +set anything else (credentials, pattern, etc.) you need to use the full +form.

The pattern property in the repo is actually an array, so you can +use a YAML array (or [0], [1], etc. suffixes in properties files) +to bind to multiple patterns. You may need to do this if you are going +to run apps with multiple profiles. Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          repos:
+            development:
+              pattern:
+                - '*/development'
+                - '*/staging'
+              uri: https://github.com/development/config-repo
+            staging:
+              pattern:
+                - '*/qa'
+                - '*/production'
+              uri: https://github.com/staging/config-repo
[Note]Note

Spring Cloud will guess that a pattern containing a profile that +doesn’t end in * implies that you actually want to match a list of +profiles starting with this pattern (so */staging is a shortcut for +["*/staging", "*/staging,*"]). This is common where you need to run +apps in the "development" profile locally but also the "cloud" profile +remotely, for instance.

Every repository can also optionally store config files in +sub-directories, and patterns to search for those directories can be +specified as searchPaths. For example at the top level:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          searchPaths: foo,bar*

In this example the server searches for config files in the top level +and in the "foo/" sub-directory and also any sub-directory whose name +begins with "bar".

By default the server clones remote repositories when configuration +is first requested. The server can be configured to clone the repositories +at startup. For example at the top level:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://git/common/config-repo.git
+          repos:
+            team-a:
+                pattern: team-a-*
+                cloneOnStart: true
+                uri: http://git/team-a/config-repo.git
+            team-b:
+                pattern: team-b-*
+                cloneOnStart: false
+                uri: http://git/team-b/config-repo.git
+            team-c:
+                pattern: team-c-*
+                uri: http://git/team-a/config-repo.git

In this example the server clones team-a’s config-repo on startup before it +accepts any requests. All other repositories will not be cloned until +configuration from the repository is requested.

[Note]Note

Setting a repository to be cloned when the Config Server starts up can +help to identify a misconfigured configuration source (e.g., an invalid +repository URI) quickly, while the Config Server is starting up. With +cloneOnStart not enabled for a configuration source, the Config Server may +start successfully with a misconfigured or invalid configuration source and +not detect an error until an application requests configuration from that +configuration source.

Authentication

To use HTTP basic authentication on the remote repository add the +"username" and "password" properties separately (not in the URL), +e.g.

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          username: trolley
+          password: strongpassword

If you don’t use HTTPS and user credentials, SSH should also work out +of the box when you store keys in the default directories (~/.ssh) +and the uri points to an SSH location, +e.g. "git@github.com:configuration/cloud-configuration". It is important that an entry for the Git server be present in the ~/.ssh/known_hosts file and that it is in ssh-rsa format. Other formats (like ecdsa-sha2-nistp256) are not supported. To avoid surprises, you should ensure that only one entry is present in the known_hosts file for the Git server and that it is matching with the URL you provided to the config server. If you used a hostname in the URL, you want to have exactly that in the known_hosts file, not the IP. +The repository is accessed using JGit, so any documentation you find on +that should be applicable. HTTPS proxy settings can be set in +~/.git/config or in the same way as for any other JVM process via +system properties (-Dhttps.proxyHost and -Dhttps.proxyPort).

[Tip]Tip

If you don’t know where your ~/.git directory is use git config +--global to manipulate the settings (e.g. git config --global +http.sslVerify false).

Authentication with AWS CodeCommit

AWS CodeCommit authentication can also be +done. AWS CodeCommit uses an authentication helper when using Git from the command line. This helper is not +used with the JGit library, so a JGit CredentialProvider for AWS CodeCommit will be created if the Git +URI matches the AWS CodeCommit pattern. AWS CodeCommit URIs always look like +https://git-codecommit.${AWS_REGION}.amazonaws.com/${repopath}.

If you provide a username and password with an AWS CodeCommit URI, then these must be +the AWS accessKeyId and secretAccessKey +to be used to access the repository. If you do not specify a username and password, +then the accessKeyId and secretAccessKey will be retrieved using the +AWS Default Credential Provider Chain.

If your Git URI matches the CodeCommit URI pattern (above) then you must provide +valid AWS credentials in the username and password, or in one of the locations supported +by the default credential provider chain. AWS EC2 instances may use +IAM Roles for EC2 Instances.

Note: The aws-java-sdk-core jar is an optional dependency. If the aws-java-sdk-core jar is not on your +classpath, then the AWS Code Commit credential provider will not be created regardless of the git server URI.

Git SSH configuration using properties

By default, the JGit library used by Spring Cloud Config Server uses SSH configuration files such as ~/.ssh/known_hosts and /etc/ssh/ssh_config when connecting to Git repositories using an SSH URI. +In cloud environments such as Cloud Foundry, the local filesystem may be ephemeral or not easily accessible. For cases such as these, SSH configuration can be set using +Java properties. In order to activate property based SSH configuration, the property spring.cloud.config.server.git.ignoreLocalSshSettings must be set to true. +Example:

  spring:
+    cloud:
+      config:
+        server:
+          git:
+            uri: git@gitserver.com:team/repo1.git
+            ignoreLocalSshSettings: true
+            hostKey: someHostKey
+            hostKeyAlgorithm: ssh-rsa
+            privateKey: |
+                         -----BEGIN RSA PRIVATE KEY-----
+                         MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX
+                         IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF
+                         ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud
+                         1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i
+                         oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W
+                         DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd
+                         fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b
+                         BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG
+                         EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj
+                         5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8
+                         +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe
+                         pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG
+                         ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ
+                         xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW
+                         dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi
+                         PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX
+                         VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z
+                         FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R
+                         gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4
+                         VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV
+                         cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee
+                         KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N
+                         CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs
+                         q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J
+                         69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT
+                         -----END RSA PRIVATE KEY-----

Table 2.1. SSH Configuration properties

Property NameRemarks

ignoreLocalSshSettings

If true, use property based SSH config instead of file based. Must be set at as spring.cloud.config.server.git.ignoreLocalSshSettings, not inside a repository definition.

privateKey

Valid SSH private key. Must be set if ignoreLocalSshSettings is true and Git URI is SSH format

hostKey

Valid SSH host key. Must be set if hostKeyAlgorithm is also set

hostKeyAlgorithm

One of ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 ,ecdsa-sha2-nistp521. Must be set if hostKey is also set

proxyHost

Hostname for the ssh proxy connection. Is optional and used only when ignoreLocalSshSettings is true

proxyPort

Port for the ssh proxy connection. Must be set if proxyHost is also set

strictHostKeyChecking

true or false. If false, ignore errors with host key

knownHostsFile

Location of custom .known_hosts file

preferredAuthentications

Override server authentication method order. This should allow evade login prompts if server has keyboard-interactive authentication before publickey method.


Placeholders in Git Search Paths

Spring Cloud Config Server also supports a search path with +placeholders for the {application} and {profile} (and {label} if +you need it). Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          searchPaths: '{application}'

searches the repository for files in the same name as the directory +(as well as the top level). Wildcards are also valid in a search +path with placeholders (any matching directory is included in the +search).

Force pull in Git Repositories

As mentioned before Spring Cloud Config Server makes a clone of the +remote git repository and if somehow the local copy gets dirty (e.g. +folder content changes by OS process) so Spring Cloud Config Server +cannot update the local copy from remote repository.

To solve this there is a force-pull property that will make Spring Cloud +Config Server force pull from remote repository if the local copy is dirty. +Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          force-pull: true

If you have a multiple repositories configuration you can configure the +force-pull property per repository. Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://git/common/config-repo.git
+          force-pull: true
+          repos:
+            team-a:
+                pattern: team-a-*
+                uri: http://git/team-a/config-repo.git
+                force-pull: true
+            team-b:
+                pattern: team-b-*
+                uri: http://git/team-b/config-repo.git
+                force-pull: true
+            team-c:
+                pattern: team-c-*
+                uri: http://git/team-a/config-repo.git
[Note]Note

The default value for force-pull property is false.

Deleting untracked branches in Git Repositories

As Spring Cloud Config Server has a clone of the remote git repository +after check-outing branch to local repo (e.g fetching properties by label) it will keep this branch +forever or till the next server restart (which creates new local repo). +So there could be a case when remote branch is deleted but local copy of it is still available for fetching. +And if Spring Cloud Config Server client service starts with --spring.cloud.config.label=deletedRemoteBranch,master +it will fetch properties from deletedRemoteBranch local branch, but not from master.

In order to keep local repository branches clean and up to remote - deleteUntrackedBranches property could be set. +It will make Spring Cloud Config Server force delete untracked branches from local repository. +Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          deleteUntrackedBranches: true
[Note]Note

The default value for deleteUntrackedBranches property is false.

2.1.2 Version Control Backend Filesystem Use

[Warning]Warning

With VCS based backends (git, svn) files are checked out or cloned to the local filesystem. By default they are put in the system temporary directory with a prefix of config-repo-. On linux, for example it could be /tmp/config-repo-<randomid>. Some operating systems routinely clean out temporary directories. This can lead to unexpected behaviour such as missing properties. To avoid this problem, change the directory Config Server uses, by setting spring.cloud.config.server.git.basedir or spring.cloud.config.server.svn.basedir to a directory that does not reside in the system temp structure.

2.1.3 File System Backend

There is also a "native" profile in the Config Server that doesn’t use +Git, but just loads the config files from the local classpath or file +system (any static URL you want to point to with +"spring.cloud.config.server.native.searchLocations"). To use the +native profile just launch the Config Server with +"spring.profiles.active=native".

[Note]Note

Remember to use the file: prefix for file resources (the +default without a prefix is usually the classpath). Just as with any +Spring Boot configuration you can embed ${}-style environment +placeholders, but remember that absolute paths in Windows require an +extra "/", e.g. file:///${user.home}/config-repo

[Warning]Warning

The default value of the searchLocations is identical to a +local Spring Boot application (so [classpath:/, classpath:/config, +file:./, file:./config]). This does not expose the +application.properties from the server to all clients because any +property sources present in the server are removed before being sent +to the client.

[Tip]Tip

A filesystem backend is great for getting started quickly and +for testing. To use it in production you need to be sure that the +file system is reliable, and shared across all instances of the +Config Server.

The search locations can contain placeholders for {application}, +{profile} and {label}. In this way you can segregate the +directories in the path, and choose a strategy that makes sense for +you (e.g. sub-directory per application, or sub-directory per +profile).

If you don’t use placeholders in the search locations, this repository +also appends the {label} parameter of the HTTP resource to a suffix +on the search path, so properties files are loaded from each search +location and a subdirectory with the same name as the label (the +labelled properties take precedence in the Spring Environment). Thus +the default behaviour with no placeholders is the same as adding a +search location ending with /{label}/. For example file:/tmp/config +is the same as file:/tmp/config,file:/tmp/config/{label}. This behavior can be +disabled by setting spring.cloud.config.server.native.addLabelLocations=false.

2.1.4 Vault Backend

Spring Cloud Config Server also supports Vault as a backend.

For more information on Vault see the Vault quickstart guide.

To enable the config server to use a Vault backend you can run your config server +with the vault profile. For example in your config server’s application.properties +you can add spring.profiles.active=vault.

By default the config server will assume your Vault server is running at +http://127.0.0.1:8200. It also will assume that the name of backend +is secret and the key is application. All of these defaults can be +configured in your config server’s application.properties. Below is a +table of configurable Vault properties. All properties are prefixed with +spring.cloud.config.server.vault.

NameDefault Value

host

127.0.0.1

port

8200

scheme

http

backend

secret

defaultKey

application

profileSeparator

,

All configurable properties can be found in +org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.

With your config server running you can make HTTP requests to the server to retrieve +values from the Vault backend. To do this you will need a token for your Vault server.

First place some data in you Vault. For example

$ vault write secret/application foo=bar baz=bam
+$ vault write secret/myapp foo=myappsbar

Now make the HTTP request to your config server to retrieve the values.

$ curl -X "GET" "http://localhost:8888/myapp/default" -H "X-Config-Token: yourtoken"

You should see a response similar to this after making the above request.

{
+   "name":"myapp",
+   "profiles":[
+      "default"
+   ],
+   "label":null,
+   "version":null,
+   "state":null,
+   "propertySources":[
+      {
+         "name":"vault:myapp",
+         "source":{
+            "foo":"myappsbar"
+         }
+      },
+      {
+         "name":"vault:application",
+         "source":{
+            "baz":"bam",
+            "foo":"bar"
+         }
+      }
+   ]
+}

Multiple Properties Sources

When using Vault you can provide your applications with multiple properties sources. +For example, assume you have written data to the following paths in Vault.

secret/myApp,dev
+secret/myApp
+secret/application,dev
+secret/application

Properties written to secret/application are available to +all applications using the Config Server. An +application with the name myApp would have any properties +written to secret/myApp and secret/application available to it. +When myApp has the dev profile enabled then properties written to +all of the above paths would be available to it, with properties in +the first path in the list taking priority over the others.

2.1.5 Sharing Configuration With All Applications

File Based Repositories

With file-based (i.e. git, svn and native) repositories, resources +with file names in application* are shared between all client +applications (so application.properties, application.yml, +application-*.properties etc.). You can use resources with these +file names to configure global defaults and have them overridden by +application-specific files as necessary.

The #_property_overrides[property overrides] feature can also be used +for setting global defaults, and with placeholders applications are +allowed to override them locally.

[Tip]Tip

With the "native" profile (local file system backend) it is +recommended that you use an explicit search location that isn’t part +of the server’s own configuration. Otherwise the application* +resources in the default search locations are removed because they are +part of the server.

Vault Server

When using Vault as a backend you can share configuration with +all applications by placing configuration in +secret/application. For example, if you run this Vault command

$ vault write secret/application foo=bar baz=bam

All applications using the config server will have the properties +foo and baz available to them.

2.1.6 JDBC Backend

Spring Cloud Config Server supports JDBC (relation database) as a +backend for configuration properties. You can enable this feature by +adding spring-jdbc to the classpath, and using the "jdbc" profile, +or by adding a bean of type JdbcEnvironmentRepository. Spring Boot +will configure a data source if you include the right dependencies on +the classpath (see the user guide for more details on that).

The database needs to have a table called "PROPERTIES" with columns +"APPLICATION", "PROFILE", "LABEL" (with the usual Environment +meaning), plus "KEY" and "VALUE" for the key and value pairs in +Properties style. All fields are of type String in Java, so you can +make them VARCHAR of whatever length you need. Property values +behave in the same way as they would if they came from Spring Boot +properties files named {application}-{profile}.properties, including +all the encryption and decryption, which will be applied as +post-processing steps (i.e. not in the repository implementation +directly).

2.1.7 Composite Environment Repositories

In some scenarios you may wish to pull configuration data from multiple +environment repositories. To do this you can just enable +multiple profiles in your config server’s application properties or YAML file. +If, for example, you want to pull configuration data from a Git repository +as well as a SVN repository you would set the following properties for your +configuration server.

spring:
+  profiles:
+    active: git, svn
+  cloud:
+    config:
+      server:
+        svn:
+          uri: file:///path/to/svn/repo
+          order: 2
+        git:
+          uri: file:///path/to/git/repo
+          order: 1

In addition to each repo specifying a URI, you can also specify an order property. +The order property allows you to specify the priority order for all your repositories. +The lower the numerical value of the order property the higher priority it will have. +The priority order of a repository will help resolve any potential conflicts between +repositories that contain values for the same properties.

[Note]Note

Any type of failure when retrieving values from an environment repositoy +will result in a failure for the entire composite environment.

[Note]Note

When using a composite environment it is important that all repos contain +the same label(s). If you have an environment similar to the one above and you request +configuration data with the label master but the SVN +repo does not contain a branch called master the entire request will fail.

Custom Composite Environment Repositories

It is also possible to provide your own EnvironmentRepository bean +to be included as part of a composite environment in addition to +using one of the environment repositories from Spring Cloud. To do this your bean +must implement the EnvironmentRepository interface. If you would like to control +the priority of you custom EnvironmentRepository within the composite +environment you should also implement the Ordered interface and override the +getOrdered method. If you do not implement the Ordered interface then your +EnvironmentRepository will be given the lowest priority.

2.1.8 Property Overrides

The Config Server has an "overrides" feature that allows the operator +to provide configuration properties to all applications that cannot be +accidentally changed by the application using the normal Spring Boot +hooks. To declare overrides just add a map of name-value pairs to +spring.cloud.config.server.overrides. For example

spring:
+  cloud:
+    config:
+      server:
+        overrides:
+          foo: bar

will cause all applications that are config clients to read foo=bar +independent of their own configuration. (Of course an application can +use the data in the Config Server in any way it likes, so overrides +are not enforceable, but they do provide useful default behaviour if +they are Spring Cloud Config clients.)

[Tip]Tip

Normal, Spring environment placeholders with "${}" can be escaped +(and resolved on the client) by using backslash ("\") to escape the +"$" or the "{", e.g. \${app.foo:bar} resolves to "bar" unless the +app provides its own "app.foo". Note that in YAML you don’t need to +escape the backslash itself, but in properties files you do, when you +configure the overrides on the server.

You can change the priority of all overrides in the client to be more +like default values, allowing applications to supply their own values +in environment variables or System properties, by setting the flag +spring.cloud.config.overrideNone=true (default is false) in the +remote repository.

2.2 Health Indicator

Config Server comes with a Health Indicator that checks if the configured +EnvironmentRepository is working. By default it asks the EnvironmentRepository +for an application named app, the default profile and the default +label provided by the EnvironmentRepository implementation.

You can configure the Health Indicator to check more applications +along with custom profiles and custom labels, e.g.

spring:
+  cloud:
+    config:
+      server:
+        health:
+          repositories:
+            myservice:
+              label: mylabel
+            myservice-dev:
+              name: myservice
+              profiles: development

You can disable the Health Indicator by setting spring.cloud.config.server.health.enabled=false.

2.3 Security

You are free to secure your Config Server in any way that makes sense +to you (from physical network security to OAuth2 bearer +tokens), and Spring Security and Spring Boot make it easy to do pretty +much anything.

To use the default Spring Boot configured HTTP Basic security, just +include Spring Security on the classpath (e.g. through +spring-boot-starter-security). The default is a username of "user" +and a randomly generated password, which isn’t going to be very useful +in practice, so we recommend you configure the password (via +security.user.password) and encrypt it (see below for instructions +on how to do that).

2.4 Encryption and Decryption

[Important]Important

Prerequisites: to use the encryption and decryption features +you need the full-strength JCE installed in your JVM (it’s not there by default). +You can download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" +from Oracle, and follow instructions for installation (essentially replace the 2 policy files +in the JRE lib/security directory with the ones that you downloaded).

If the remote property sources contain encrypted content (values +starting with {cipher}) they will be decrypted before sending to +clients over HTTP. The main advantage of this set up is that the +property values don’t have to be in plain text when they are "at rest" +(e.g. in a git repository). If a value cannot be decrypted it is +removed from the property source and an additional property is added +with the same key, but prefixed with "invalid." and a value that means +"not applicable" (usually "<n/a>"). This is largely to prevent cipher +text being used as a password and accidentally leaking.

If you are setting up a remote config repository for config client +applications it might contain an application.yml like this, for +instance:

application.yml.  +

spring:
+  datasource:
+    username: dbuser
+    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

+

Encrypted values in a .properties file must not be wrapped in quotes, otherwise the value will not be decrypted:

application.properties.  +

spring.datasource.username: dbuser
+spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

+

You can safely push this plain text to a shared git repository and the +secret password is protected.

The server also exposes /encrypt and /decrypt endpoints (on the +assumption that these will be secured and only accessed by authorized +agents). If you are editing a remote config file you can use the Config Server +to encrypt values by POSTing to the /encrypt endpoint, e.g.

$ curl localhost:8888/encrypt -d mysecret
+682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
[Note]Note

If the value you are encrypting has characters in it that need to be URL encoded you should use +the --data-urlencode option to curl to make sure they are encoded properly.

[Tip]Tip

Be sure not to include any of the curl command statistics in the encrypted value. +Outputting the value to a file can help avoid this problem.

The inverse operation is also available via /decrypt (provided the server is +configured with a symmetric key or a full key pair):

$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
+mysecret
[Tip]Tip

If you are testing like this with curl, then use +--data-urlencode (instead of -d) or set an explicit Content-Type: +text/plain to make sure curl encodes the data correctly when there +are special characters ('+' is particularly tricky).

Take the encrypted value and add the {cipher} prefix before you put +it in the YAML or properties file, and before you commit and push it +to a remote, potentially insecure store.

The /encrypt and /decrypt endpoints also both accept paths of the +form /*/{name}/{profiles} which can be used to control cryptography +per application (name) and profile when clients call into the main +Environment resource.

[Note]Note

to control the cryptography in this granular way you must also +provide a @Bean of type TextEncryptorLocator that creates a +different encryptor per name and profiles. The one that is provided +by default does not do this (so all encryptions use the same key).

The spring command line client (with Spring Cloud CLI extensions +installed) can also be used to encrypt and decrypt, e.g.

$ spring encrypt mysecret --key foo
+682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
+$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
+mysecret

To use a key in a file (e.g. an RSA public key for encryption) prepend +the key value with "@" and provide the file path, e.g.

$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
+AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...

The key argument is mandatory (despite having a -- prefix).

2.5 Key Management

The Config Server can use a symmetric (shared) key or an asymmetric +one (RSA key pair). The asymmetric choice is superior in terms of +security, but it is often more convenient to use a symmetric key since +it is just a single property value to configure in the bootstrap.properties.

To configure a symmetric key you just need to set encrypt.key to a +secret String (or use an enviroment variable ENCRYPT_KEY to keep it +out of plain text configuration files).

To configure an asymmetric key you can either set the key as a +PEM-encoded text value (in encrypt.key), or via a keystore (e.g. as +created by the keytool utility that comes with the JDK). The +keystore properties are encrypt.keyStore.* with * equal to

  • location (a Resource location),
  • password (to unlock the keystore) and
  • alias (to identify which key in the store is to be +used).

The encryption is done with the public key, and a private key is +needed for decryption. Thus in principle you can configure only the +public key in the server if you only want to do encryption (and are +prepared to decrypt the values yourself locally with the private +key). In practice you might not want to do that because it spreads the +key management process around all the clients, instead of +concentrating it in the server. On the other hand it’s a useful option +if your config server really is relatively insecure and only a +handful of clients need the encrypted properties.

2.6 Creating a Key Store for Testing

To create a keystore for testing you can do something like this:

$ keytool -genkeypair -alias mytestkey -keyalg RSA \
+  -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
+  -keypass changeme -keystore server.jks -storepass letmein

Put the server.jks file in the classpath (for instance) and then in +your bootstrap.yml for the Config Server:

encrypt:
+  keyStore:
+    location: classpath:/server.jks
+    password: letmein
+    alias: mytestkey
+    secret: changeme

2.7 Using Multiple Keys and Key Rotation

In addition to the {cipher} prefix in encrypted property values, the +Config Server looks for {name:value} prefixes (zero or many) before +the start of the (Base64 encoded) cipher text. The keys are passed to +a TextEncryptorLocator which can do whatever logic it needs to +locate a TextEncryptor for the cipher. If you have configured a +keystore (encrypt.keystore.location) the default locator will look +for keys in the store with aliases as supplied by the "key" prefix, +i.e. with a cipher text like this:

foo:
+  bar: `{cipher}{key:testkey}...`

the locator will look for a key named "testkey". A secret can also be +supplied via a {secret:…​} value in the prefix, but if it is not +the default is to use the keystore password (which is what you get +when you build a keytore and don’t specify a secret). If you do +supply a secret it is recommended that you also encrypt the secrets +using a custom SecretLocator.

Key rotation is hardly ever necessary on cryptographic grounds if the +keys are only being used to encrypt a few bytes of configuration data +(i.e. they are not being used elsewhere), but occasionally you might +need to change the keys if there is a security breach for instance. In +that case all the clients would need to change their source config +files (e.g. in git) and use a new {key:…​} prefix in all the +ciphers, checking beforehand of course that the key alias is available +in the Config Server keystore.

[Tip]Tip

the {name:value} prefixes can also be added to plaintext posted +to the /encrypt endpoint, if you want to let the Config Server +handle all encryption as well as decryption.

2.8 Serving Encrypted Properties

Sometimes you want the clients to decrypt the configuration locally, +instead of doing it in the server. In that case you can still have +/encrypt and /decrypt endpoints (if you provide the encrypt.* +configuration to locate a key), but you need to explicitly switch off +the decryption of outgoing properties by placing +spring.cloud.config.server.encrypt.enabled=false in bootstrap.[yml|properties]. +If you don’t care about the endpoints, then it should work if you configure neither the +key nor the enabled flag.

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi_pr01.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi_pr01.html new file mode 100644 index 00000000..d38d0aca --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi_pr01.html @@ -0,0 +1,3 @@ + + +

1.4.4.RELEASE

Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications, but can be used with any application running in any language. As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate. The default implementation of the server storage backend uses git so it easily supports labelled versions of configuration environments, as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with Spring configuration.

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/multi/multi_spring-cloud-config.html b/spring-cloud-config/1.4.4.RELEASE/multi/multi_spring-cloud-config.html new file mode 100644 index 00000000..09455401 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/multi/multi_spring-cloud-config.html @@ -0,0 +1,3 @@ + + + Spring Cloud Config \ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/single/css/highlight.css b/spring-cloud-config/1.4.4.RELEASE/single/css/highlight.css new file mode 100644 index 00000000..ffefef72 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/single/css/manual-multipage.css b/spring-cloud-config/1.4.4.RELEASE/single/css/manual-multipage.css new file mode 100644 index 00000000..0c484531 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/single/css/manual-singlepage.css b/spring-cloud-config/1.4.4.RELEASE/single/css/manual-singlepage.css new file mode 100644 index 00000000..4a7fd140 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/single/css/manual.css b/spring-cloud-config/1.4.4.RELEASE/single/css/manual.css new file mode 100644 index 00000000..0ecbe2e8 --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/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-config/1.4.4.RELEASE/single/images/background.png b/spring-cloud-config/1.4.4.RELEASE/single/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..15dca6fbe2669fae3609605e49c69cc414f1b6ed GIT binary patch literal 18255 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 EKU&lfD*ylh literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/single/images/callouts/1.png b/spring-cloud-config/1.4.4.RELEASE/single/images/callouts/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d473430b7bec514f7de12f5769fe7c5859e8c5d GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}^nQC}X^4DKU-G|w_t}fLBA)Suv#nrW z!^h2QnY_`l!BOq-UXEX{m2up>JTQkX)2m zTvF+fTUlI^nXH#utd~++ke^qgmzgTe~DWM4ffP81J literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/single/images/callouts/2.png b/spring-cloud-config/1.4.4.RELEASE/single/images/callouts/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5d09341b2f6d2ea2d1d5dad5d980f14b4b05dfd2 GIT binary patch literal 353 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 literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/single/images/logo.png b/spring-cloud-config/1.4.4.RELEASE/single/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ade2ce6ed9d9e9f2f4d9c5729a252ee618a0a5a7 GIT binary patch literal 4387 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 FV1jwin)(0$ literal 0 HcmV?d00001 diff --git a/spring-cloud-config/1.4.4.RELEASE/single/images/warning.png b/spring-cloud-config/1.4.4.RELEASE/single/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5b5244605adbb7ab05a1549746a9c35490f95b GIT binary patch literal 2130 zcmbVNYg7|w8V(4q($)50y>JmGlLW#g$xLn}Vd2Si)}#|ptPAQp3Bp-3!-lL0;i^LY?;i#f0m5s49g z3h?3rDQg~EDPlm?FKkgKIcWEK-3X6YU0uzs7H|nq84s39r2!5;pF?SI$QqXy^Ko1x zV~zpENvp@<_Bsd`5MabC#3rvCq&$5dg43yGR zAdy0-rWjC#a1N_+kzUMY#pmogD7!DP(9dEKr3c5ngvUq_6>}Y+w-a81v=eSXnIi_+ zI?U>D1q2C!0zHox#XXKH+@|&rPT*OF5yvY$5J|)WwLqnU)c-5;=UChSlQkaY3@^|g z|J5#YBB}=i+n3Ex9bS$P?xJSKLk)-HHII@;3qG#TG^!+aj>0QkO~7kB0+|yM;YrGB zF>Ge@isQ#73%Tp#k_(tInh3U$uJWY-+DND*o}L-CB5g@#9YWWw~pxZ!Obm>yN#ZHFvL0zA3vNCTJ=t?)~`2O1M{L6un=ml<2x zQEYfifmA?Pz0tqRs^2Utt1pU0BQB1eIY0U_I}c1Y#PP7Ci5s7#IJn}xK{G+{_v^Z+1V#$Erodv>d}ew>RP0wzw+GWkGCBlS1Oj5Z!5NK zUuSR6>pa}RSEZ;qE_w1l#`hQX4E67U6NeP zHZ`T&wj0_H)t|Y1thUqnhub?%e)Y07;a^Tq%FO&iQkR&`qG!dh*2WfW(HuRQj*_DI zeCD1bUA|tMwjOb8E|FRIn$pzEU!2j_N}1Z2ig)vbr5xA0rjC70cmI6*%Uf->hWzaZ z{33HABO5q)vRhzDly2l691@+q3O{}NbSzx+I*k@|L4&3leK#$>u+T#TvTELfKb|IH zc23atf3vmfCa0&TWY@iuoA_Pm<0~ttEC*ut`isb^jXS>X^Sp=l?RXN_OJ*&usGXg$ zTlTv;Ch^vhLDf&+62jl64*&D+=+`sN_dap_1W%p|KQVYIdgPL5uRE9(c4On)DXndL zLNq?%!-u*zmMxyYc4m4Nr>>=A=s}PkJkqr&E^b9>5g+}c1%X}3|WKcg&spcJQ)05zI<<5LTBhNKRg$XRTi2{j)yl_ zj4~kKOvr+m(;vw~9zVh(zC-y9jqQnguz5r7FRq^MyKuXAENp(TAzUVtg&Ts+B_s7) zGn+fN0sG>9GjsPLKTRrvCd`71IZulJ1_1jO9KWbD&_@2UC+LTNpxxrdz#E|j|2nA9 zzB!UTyfAEJ&#%$pQ>QX#8vk@_a5iqukMF;8`wRKe{BI}5$H%OROs4J1#j)|?p|YSh z_SpR^e`VE#F52;WL{!+L(yZLRh40*KS;@box;9(-tE)`mcVp27O*>Z{_Lb*5T3cJA yr~0nPHtg2+UHi&&$8ha;`+hiaUmw&!n@8(?5PqF(KE5>Ym)EG)p&uyBP5%a8^# + + Spring Cloud Config

Spring Cloud Config


1.4.4.RELEASE

Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications, but can be used with any application running in any language. As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate. The default implementation of the server storage backend uses git so it easily supports labelled versions of configuration environments, as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with Spring configuration.

1. Quick Start

Start the server:

$ cd spring-cloud-config-server
+$ ../mvnw spring-boot:run

The server is a Spring Boot application so you can run it from your +IDE instead if you prefer (the main class is +ConfigServerApplication). Then try out a client:

$ curl localhost:8888/foo/development
+{"name":"foo","label":"master","propertySources":[
+  {"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}},
+  {"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}}
+]}

The default strategy for locating property sources is to clone a git +repository (at spring.cloud.config.server.git.uri) and use it to +initialize a mini SpringApplication. The mini-application’s +Environment is used to enumerate property sources and publish them +via a JSON endpoint.

The HTTP service has resources in the form:

/{application}/{profile}[/{label}]
+/{application}-{profile}.yml
+/{label}/{application}-{profile}.yml
+/{application}-{profile}.properties
+/{label}/{application}-{profile}.properties

where the "application" is injected as the spring.config.name in the +SpringApplication (i.e. what is normally "application" in a regular +Spring Boot app), "profile" is an active profile (or comma-separated +list of properties), and "label" is an optional git label (defaults to +"master".)

Spring Cloud Config Server pulls configuration for remote clients +from a git repository (which must be provided):

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo

1.1 Client Side Usage

To use these features in an application, just build it as a Spring +Boot application that depends on spring-cloud-config-client (e.g. see +the test cases for the config-client, or the sample app). The most +convenient way to add the dependency is via a Spring Boot starter +org.springframework.cloud:spring-cloud-starter-config. There is also a +parent pom and BOM (spring-cloud-starter-parent) for Maven users and a +Spring IO version management properties file for Gradle and Spring CLI +users. Example Maven configuration:

pom.xml.  +

   <parent>
+       <groupId>org.springframework.boot</groupId>
+       <artifactId>spring-boot-starter-parent</artifactId>
+       <version>1.5.10.RELEASE</version>
+       <relativePath /> <!-- lookup parent from repository -->
+   </parent>
+
+<dependencyManagement>
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-dependencies</artifactId>
+			<version>Edgware.SR2</version>
+			<type>pom</type>
+			<scope>import</scope>
+		</dependency>
+	</dependencies>
+</dependencyManagement>
+
+<dependencies>
+	<dependency>
+		<groupId>org.springframework.cloud</groupId>
+		<artifactId>spring-cloud-starter-config</artifactId>
+	</dependency>
+	<dependency>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-test</artifactId>
+		<scope>test</scope>
+	</dependency>
+</dependencies>
+
+<build>
+	<plugins>
+           <plugin>
+               <groupId>org.springframework.boot</groupId>
+               <artifactId>spring-boot-maven-plugin</artifactId>
+           </plugin>
+	</plugins>
+</build>
+
+   <!-- repositories also needed for snapshots and milestones -->

+

Then you can create a standard Spring Boot application, like this simple HTTP server:

@SpringBootApplication
+@RestController
+public class Application {
+
+    @RequestMapping("/")
+    public String home() {
+        return "Hello World!";
+    }
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+
+}

When it runs it will pick up the external configuration from the +default local config server on port 8888 if it is running. To modify +the startup behaviour you can change the location of the config server +using bootstrap.properties (like application.properties but for +the bootstrap phase of an application context), e.g.

spring.cloud.config.uri: http://myconfigserver.com

The bootstrap properties will show up in the /env endpoint as a +high-priority property source, e.g.

$ curl localhost:8080/env
+{
+  "profiles":[],
+  "configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"},
+  "servletContextInitParams":{},
+  "systemProperties":{...},
+  ...
+}

(a property source called "configService:<URL of remote +repository>/<file name>" contains the property "foo" with value +"bar" and is highest priority).

[Note]Note

the URL in the property source name is the git repository not +the config server URL.

2. Spring Cloud Config Server

The Server provides an HTTP, resource-based API for external +configuration (name-value pairs, or equivalent YAML content). The +server is easily embeddable in a Spring Boot application using the +@EnableConfigServer annotation. So this app is a config server:

ConfigServer.java.  +

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

+

Like all Spring Boot apps it runs on port 8080 by default, but you +can switch it to the conventional port 8888 in various ways. The +easiest, which also sets a default configuration repository, +is by launching it with spring.config.name=configserver (there +is a configserver.yml in the Config Server jar). Another is +to use your own application.properties, e.g.

application.properties.  +

server.port: 8888
+spring.cloud.config.server.git.uri: file://${user.home}/config-repo

+

where ${user.home}/config-repo is a git repository containing +YAML and properties files.

[Note]Note

in Windows you need an extra "/" in the file URL if it is +absolute with a drive prefix, e.g. file:///${user.home}/config-repo.

[Tip]Tip

Here’s a recipe for creating the git repository in the example +above:

$ cd $HOME
+$ mkdir config-repo
+$ cd config-repo
+$ git init .
+$ echo info.foo: bar > application.properties
+$ git add -A .
+$ git commit -m "Add application.properties"
[Warning]Warning

using the local filesystem for your git repository is +intended for testing only. Use a server to host your +configuration repositories in production.

[Warning]Warning

the initial clone of your configuration repository will +be quick and efficient if you only keep text files in it. If you start +to store binary files, especially large ones, you may experience +delays on the first request for configuration and/or out of memory +errors in the server.

2.1 Environment Repository

Where do you want to store the configuration data for the Config +Server? The strategy that governs this behaviour is the +EnvironmentRepository, serving Environment objects. This +Environment is a shallow copy of the domain from the Spring +Environment (including propertySources as the main feature). The +Environment resources are parametrized by three variables:

  • {application} maps to "spring.application.name" on the client side;
  • {profile} maps to "spring.profiles.active" on the client (comma separated list); and
  • {label} which is a server side feature labelling a "versioned" set of config files.

Repository implementations generally behave just like a Spring Boot +application loading configuration files from a "spring.config.name" +equal to the {application} parameter, and "spring.profiles.active" +equal to the {profiles} parameter. Precedence rules for profiles are +also the same as in a regular Boot application: active profiles take +precedence over defaults, and if there are multiple profiles the last +one wins (like adding entries to a Map).

Example: a client application has this bootstrap configuration:

bootstrap.yml.  +

spring:
+  application:
+    name: foo
+  profiles:
+    active: dev,mysql

+

(as usual with a Spring Boot application, these properties could also +be set as environment variables or command line arguments).

If the repository is file-based, the server will create an +Environment from application.yml (shared between all clients), and +foo.yml (with foo.yml taking precedence). If the YAML files have +documents inside them that point to Spring profiles, those are applied +with higher precedence (in order of the profiles listed), and if +there are profile-specific YAML (or properties) files these are also +applied with higher precedence than the defaults. Higher precedence +translates to a PropertySource listed earlier in the +Environment. (These are the same rules as apply in a standalone +Spring Boot application.)

2.1.1 Git Backend

The default implementation of EnvironmentRepository uses a Git +backend, which is very convenient for managing upgrades and physical +environments, and also for auditing changes. To change the location of +the repository you can set the "spring.cloud.config.server.git.uri" +configuration property in the Config Server (e.g. in +application.yml). If you set it with a file: prefix it should work +from a local repository so you can get started quickly and easily +without a server, but in that case the server operates directly on the +local repository without cloning it (it doesn’t matter if it’s not +bare because the Config Server never makes changes to the "remote" +repository). To scale the Config Server up and make it highly +available, you would need to have all instances of the server pointing +to the same repository, so only a shared file system would work. Even +in that case it is better to use the ssh: protocol for a shared +filesystem repository, so that the server can clone it and use a local +working copy as a cache.

This repository implementation maps the {label} parameter of the +HTTP resource to a git label (commit id, branch name or tag). If the +git branch or tag name contains a slash ("/") then the label in the +HTTP URL should be specified with the special string "(_)" instead (to +avoid ambiguity with other URL paths). For example, if the label is +foo/bar, replacing the slash would result in a label that looks like +foo(_)bar. The inclusion of the special string "(_)" can also be +applied to the {application} parameter. Be careful with the brackets +in the URL if you are using a command line client like curl (e.g. +escape them from the shell with quotes '').

Placeholders in Git URI

Spring Cloud Config Server supports a git repository URL with +placeholders for the {application} and {profile} (and {label} if +you need it, but remember that the label is applied as a git label +anyway). So you can easily support a "one repo per application" policy +using (for example):

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/myorg/{application}

or a "one repo per profile" policy using a similar pattern but with +{profile}.

Additionally, using the special string "(_)" within your +{application} parameters can enable support for multiple +organizations (for example):

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/{application}

where {application} is provided at request time in the format +"organization(_)application".

Pattern Matching and Multiple Repositories

There is also support for more complex requirements with pattern +matching on the application and profile name. The pattern format is a +comma-separated list of {application}/{profile} names with wildcards +(where a pattern beginning with a wildcard may need to be +quoted). Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          repos:
+            simple: https://github.com/simple/config-repo
+            special:
+              pattern: special*/dev*,*special*/dev*
+              uri: https://github.com/special/config-repo
+            local:
+              pattern: local*
+              uri: file:/home/configsvc/config-repo

If {application}/{profile} does not match any of the patterns, it +will use the default uri defined under +"spring.cloud.config.server.git.uri". In the above example, for the +"simple" repository, the pattern is simple/* (i.e. it only matches +one application named "simple" in all profiles). The "local" +repository matches all application names beginning with "local" in all +profiles (the /* suffix is added automatically to any pattern that +doesn’t have a profile matcher).

[Note]Note

the "one-liner" short cut used in the "simple" example above can +only be used if the only property to be set is the URI. If you need to +set anything else (credentials, pattern, etc.) you need to use the full +form.

The pattern property in the repo is actually an array, so you can +use a YAML array (or [0], [1], etc. suffixes in properties files) +to bind to multiple patterns. You may need to do this if you are going +to run apps with multiple profiles. Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          repos:
+            development:
+              pattern:
+                - '*/development'
+                - '*/staging'
+              uri: https://github.com/development/config-repo
+            staging:
+              pattern:
+                - '*/qa'
+                - '*/production'
+              uri: https://github.com/staging/config-repo
[Note]Note

Spring Cloud will guess that a pattern containing a profile that +doesn’t end in * implies that you actually want to match a list of +profiles starting with this pattern (so */staging is a shortcut for +["*/staging", "*/staging,*"]). This is common where you need to run +apps in the "development" profile locally but also the "cloud" profile +remotely, for instance.

Every repository can also optionally store config files in +sub-directories, and patterns to search for those directories can be +specified as searchPaths. For example at the top level:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          searchPaths: foo,bar*

In this example the server searches for config files in the top level +and in the "foo/" sub-directory and also any sub-directory whose name +begins with "bar".

By default the server clones remote repositories when configuration +is first requested. The server can be configured to clone the repositories +at startup. For example at the top level:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://git/common/config-repo.git
+          repos:
+            team-a:
+                pattern: team-a-*
+                cloneOnStart: true
+                uri: http://git/team-a/config-repo.git
+            team-b:
+                pattern: team-b-*
+                cloneOnStart: false
+                uri: http://git/team-b/config-repo.git
+            team-c:
+                pattern: team-c-*
+                uri: http://git/team-a/config-repo.git

In this example the server clones team-a’s config-repo on startup before it +accepts any requests. All other repositories will not be cloned until +configuration from the repository is requested.

[Note]Note

Setting a repository to be cloned when the Config Server starts up can +help to identify a misconfigured configuration source (e.g., an invalid +repository URI) quickly, while the Config Server is starting up. With +cloneOnStart not enabled for a configuration source, the Config Server may +start successfully with a misconfigured or invalid configuration source and +not detect an error until an application requests configuration from that +configuration source.

Authentication

To use HTTP basic authentication on the remote repository add the +"username" and "password" properties separately (not in the URL), +e.g.

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          username: trolley
+          password: strongpassword

If you don’t use HTTPS and user credentials, SSH should also work out +of the box when you store keys in the default directories (~/.ssh) +and the uri points to an SSH location, +e.g. "git@github.com:configuration/cloud-configuration". It is important that an entry for the Git server be present in the ~/.ssh/known_hosts file and that it is in ssh-rsa format. Other formats (like ecdsa-sha2-nistp256) are not supported. To avoid surprises, you should ensure that only one entry is present in the known_hosts file for the Git server and that it is matching with the URL you provided to the config server. If you used a hostname in the URL, you want to have exactly that in the known_hosts file, not the IP. +The repository is accessed using JGit, so any documentation you find on +that should be applicable. HTTPS proxy settings can be set in +~/.git/config or in the same way as for any other JVM process via +system properties (-Dhttps.proxyHost and -Dhttps.proxyPort).

[Tip]Tip

If you don’t know where your ~/.git directory is use git config +--global to manipulate the settings (e.g. git config --global +http.sslVerify false).

Authentication with AWS CodeCommit

AWS CodeCommit authentication can also be +done. AWS CodeCommit uses an authentication helper when using Git from the command line. This helper is not +used with the JGit library, so a JGit CredentialProvider for AWS CodeCommit will be created if the Git +URI matches the AWS CodeCommit pattern. AWS CodeCommit URIs always look like +https://git-codecommit.${AWS_REGION}.amazonaws.com/${repopath}.

If you provide a username and password with an AWS CodeCommit URI, then these must be +the AWS accessKeyId and secretAccessKey +to be used to access the repository. If you do not specify a username and password, +then the accessKeyId and secretAccessKey will be retrieved using the +AWS Default Credential Provider Chain.

If your Git URI matches the CodeCommit URI pattern (above) then you must provide +valid AWS credentials in the username and password, or in one of the locations supported +by the default credential provider chain. AWS EC2 instances may use +IAM Roles for EC2 Instances.

Note: The aws-java-sdk-core jar is an optional dependency. If the aws-java-sdk-core jar is not on your +classpath, then the AWS Code Commit credential provider will not be created regardless of the git server URI.

Git SSH configuration using properties

By default, the JGit library used by Spring Cloud Config Server uses SSH configuration files such as ~/.ssh/known_hosts and /etc/ssh/ssh_config when connecting to Git repositories using an SSH URI. +In cloud environments such as Cloud Foundry, the local filesystem may be ephemeral or not easily accessible. For cases such as these, SSH configuration can be set using +Java properties. In order to activate property based SSH configuration, the property spring.cloud.config.server.git.ignoreLocalSshSettings must be set to true. +Example:

  spring:
+    cloud:
+      config:
+        server:
+          git:
+            uri: git@gitserver.com:team/repo1.git
+            ignoreLocalSshSettings: true
+            hostKey: someHostKey
+            hostKeyAlgorithm: ssh-rsa
+            privateKey: |
+                         -----BEGIN RSA PRIVATE KEY-----
+                         MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX
+                         IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF
+                         ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud
+                         1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i
+                         oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W
+                         DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd
+                         fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b
+                         BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG
+                         EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj
+                         5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8
+                         +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe
+                         pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG
+                         ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ
+                         xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW
+                         dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi
+                         PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX
+                         VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z
+                         FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R
+                         gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4
+                         VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV
+                         cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee
+                         KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N
+                         CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs
+                         q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J
+                         69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT
+                         -----END RSA PRIVATE KEY-----

Table 2.1. SSH Configuration properties

Property NameRemarks

ignoreLocalSshSettings

If true, use property based SSH config instead of file based. Must be set at as spring.cloud.config.server.git.ignoreLocalSshSettings, not inside a repository definition.

privateKey

Valid SSH private key. Must be set if ignoreLocalSshSettings is true and Git URI is SSH format

hostKey

Valid SSH host key. Must be set if hostKeyAlgorithm is also set

hostKeyAlgorithm

One of ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 ,ecdsa-sha2-nistp521. Must be set if hostKey is also set

proxyHost

Hostname for the ssh proxy connection. Is optional and used only when ignoreLocalSshSettings is true

proxyPort

Port for the ssh proxy connection. Must be set if proxyHost is also set

strictHostKeyChecking

true or false. If false, ignore errors with host key

knownHostsFile

Location of custom .known_hosts file

preferredAuthentications

Override server authentication method order. This should allow evade login prompts if server has keyboard-interactive authentication before publickey method.


Placeholders in Git Search Paths

Spring Cloud Config Server also supports a search path with +placeholders for the {application} and {profile} (and {label} if +you need it). Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          searchPaths: '{application}'

searches the repository for files in the same name as the directory +(as well as the top level). Wildcards are also valid in a search +path with placeholders (any matching directory is included in the +search).

Force pull in Git Repositories

As mentioned before Spring Cloud Config Server makes a clone of the +remote git repository and if somehow the local copy gets dirty (e.g. +folder content changes by OS process) so Spring Cloud Config Server +cannot update the local copy from remote repository.

To solve this there is a force-pull property that will make Spring Cloud +Config Server force pull from remote repository if the local copy is dirty. +Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          force-pull: true

If you have a multiple repositories configuration you can configure the +force-pull property per repository. Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://git/common/config-repo.git
+          force-pull: true
+          repos:
+            team-a:
+                pattern: team-a-*
+                uri: http://git/team-a/config-repo.git
+                force-pull: true
+            team-b:
+                pattern: team-b-*
+                uri: http://git/team-b/config-repo.git
+                force-pull: true
+            team-c:
+                pattern: team-c-*
+                uri: http://git/team-a/config-repo.git
[Note]Note

The default value for force-pull property is false.

Deleting untracked branches in Git Repositories

As Spring Cloud Config Server has a clone of the remote git repository +after check-outing branch to local repo (e.g fetching properties by label) it will keep this branch +forever or till the next server restart (which creates new local repo). +So there could be a case when remote branch is deleted but local copy of it is still available for fetching. +And if Spring Cloud Config Server client service starts with --spring.cloud.config.label=deletedRemoteBranch,master +it will fetch properties from deletedRemoteBranch local branch, but not from master.

In order to keep local repository branches clean and up to remote - deleteUntrackedBranches property could be set. +It will make Spring Cloud Config Server force delete untracked branches from local repository. +Example:

spring:
+  cloud:
+    config:
+      server:
+        git:
+          uri: https://github.com/spring-cloud-samples/config-repo
+          deleteUntrackedBranches: true
[Note]Note

The default value for deleteUntrackedBranches property is false.

2.1.2 Version Control Backend Filesystem Use

[Warning]Warning

With VCS based backends (git, svn) files are checked out or cloned to the local filesystem. By default they are put in the system temporary directory with a prefix of config-repo-. On linux, for example it could be /tmp/config-repo-<randomid>. Some operating systems routinely clean out temporary directories. This can lead to unexpected behaviour such as missing properties. To avoid this problem, change the directory Config Server uses, by setting spring.cloud.config.server.git.basedir or spring.cloud.config.server.svn.basedir to a directory that does not reside in the system temp structure.

2.1.3 File System Backend

There is also a "native" profile in the Config Server that doesn’t use +Git, but just loads the config files from the local classpath or file +system (any static URL you want to point to with +"spring.cloud.config.server.native.searchLocations"). To use the +native profile just launch the Config Server with +"spring.profiles.active=native".

[Note]Note

Remember to use the file: prefix for file resources (the +default without a prefix is usually the classpath). Just as with any +Spring Boot configuration you can embed ${}-style environment +placeholders, but remember that absolute paths in Windows require an +extra "/", e.g. file:///${user.home}/config-repo

[Warning]Warning

The default value of the searchLocations is identical to a +local Spring Boot application (so [classpath:/, classpath:/config, +file:./, file:./config]). This does not expose the +application.properties from the server to all clients because any +property sources present in the server are removed before being sent +to the client.

[Tip]Tip

A filesystem backend is great for getting started quickly and +for testing. To use it in production you need to be sure that the +file system is reliable, and shared across all instances of the +Config Server.

The search locations can contain placeholders for {application}, +{profile} and {label}. In this way you can segregate the +directories in the path, and choose a strategy that makes sense for +you (e.g. sub-directory per application, or sub-directory per +profile).

If you don’t use placeholders in the search locations, this repository +also appends the {label} parameter of the HTTP resource to a suffix +on the search path, so properties files are loaded from each search +location and a subdirectory with the same name as the label (the +labelled properties take precedence in the Spring Environment). Thus +the default behaviour with no placeholders is the same as adding a +search location ending with /{label}/. For example file:/tmp/config +is the same as file:/tmp/config,file:/tmp/config/{label}. This behavior can be +disabled by setting spring.cloud.config.server.native.addLabelLocations=false.

2.1.4 Vault Backend

Spring Cloud Config Server also supports Vault as a backend.

For more information on Vault see the Vault quickstart guide.

To enable the config server to use a Vault backend you can run your config server +with the vault profile. For example in your config server’s application.properties +you can add spring.profiles.active=vault.

By default the config server will assume your Vault server is running at +http://127.0.0.1:8200. It also will assume that the name of backend +is secret and the key is application. All of these defaults can be +configured in your config server’s application.properties. Below is a +table of configurable Vault properties. All properties are prefixed with +spring.cloud.config.server.vault.

NameDefault Value

host

127.0.0.1

port

8200

scheme

http

backend

secret

defaultKey

application

profileSeparator

,

All configurable properties can be found in +org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.

With your config server running you can make HTTP requests to the server to retrieve +values from the Vault backend. To do this you will need a token for your Vault server.

First place some data in you Vault. For example

$ vault write secret/application foo=bar baz=bam
+$ vault write secret/myapp foo=myappsbar

Now make the HTTP request to your config server to retrieve the values.

$ curl -X "GET" "http://localhost:8888/myapp/default" -H "X-Config-Token: yourtoken"

You should see a response similar to this after making the above request.

{
+   "name":"myapp",
+   "profiles":[
+      "default"
+   ],
+   "label":null,
+   "version":null,
+   "state":null,
+   "propertySources":[
+      {
+         "name":"vault:myapp",
+         "source":{
+            "foo":"myappsbar"
+         }
+      },
+      {
+         "name":"vault:application",
+         "source":{
+            "baz":"bam",
+            "foo":"bar"
+         }
+      }
+   ]
+}

Multiple Properties Sources

When using Vault you can provide your applications with multiple properties sources. +For example, assume you have written data to the following paths in Vault.

secret/myApp,dev
+secret/myApp
+secret/application,dev
+secret/application

Properties written to secret/application are available to +all applications using the Config Server. An +application with the name myApp would have any properties +written to secret/myApp and secret/application available to it. +When myApp has the dev profile enabled then properties written to +all of the above paths would be available to it, with properties in +the first path in the list taking priority over the others.

2.1.5 Sharing Configuration With All Applications

File Based Repositories

With file-based (i.e. git, svn and native) repositories, resources +with file names in application* are shared between all client +applications (so application.properties, application.yml, +application-*.properties etc.). You can use resources with these +file names to configure global defaults and have them overridden by +application-specific files as necessary.

The #_property_overrides[property overrides] feature can also be used +for setting global defaults, and with placeholders applications are +allowed to override them locally.

[Tip]Tip

With the "native" profile (local file system backend) it is +recommended that you use an explicit search location that isn’t part +of the server’s own configuration. Otherwise the application* +resources in the default search locations are removed because they are +part of the server.

Vault Server

When using Vault as a backend you can share configuration with +all applications by placing configuration in +secret/application. For example, if you run this Vault command

$ vault write secret/application foo=bar baz=bam

All applications using the config server will have the properties +foo and baz available to them.

2.1.6 JDBC Backend

Spring Cloud Config Server supports JDBC (relation database) as a +backend for configuration properties. You can enable this feature by +adding spring-jdbc to the classpath, and using the "jdbc" profile, +or by adding a bean of type JdbcEnvironmentRepository. Spring Boot +will configure a data source if you include the right dependencies on +the classpath (see the user guide for more details on that).

The database needs to have a table called "PROPERTIES" with columns +"APPLICATION", "PROFILE", "LABEL" (with the usual Environment +meaning), plus "KEY" and "VALUE" for the key and value pairs in +Properties style. All fields are of type String in Java, so you can +make them VARCHAR of whatever length you need. Property values +behave in the same way as they would if they came from Spring Boot +properties files named {application}-{profile}.properties, including +all the encryption and decryption, which will be applied as +post-processing steps (i.e. not in the repository implementation +directly).

2.1.7 Composite Environment Repositories

In some scenarios you may wish to pull configuration data from multiple +environment repositories. To do this you can just enable +multiple profiles in your config server’s application properties or YAML file. +If, for example, you want to pull configuration data from a Git repository +as well as a SVN repository you would set the following properties for your +configuration server.

spring:
+  profiles:
+    active: git, svn
+  cloud:
+    config:
+      server:
+        svn:
+          uri: file:///path/to/svn/repo
+          order: 2
+        git:
+          uri: file:///path/to/git/repo
+          order: 1

In addition to each repo specifying a URI, you can also specify an order property. +The order property allows you to specify the priority order for all your repositories. +The lower the numerical value of the order property the higher priority it will have. +The priority order of a repository will help resolve any potential conflicts between +repositories that contain values for the same properties.

[Note]Note

Any type of failure when retrieving values from an environment repositoy +will result in a failure for the entire composite environment.

[Note]Note

When using a composite environment it is important that all repos contain +the same label(s). If you have an environment similar to the one above and you request +configuration data with the label master but the SVN +repo does not contain a branch called master the entire request will fail.

Custom Composite Environment Repositories

It is also possible to provide your own EnvironmentRepository bean +to be included as part of a composite environment in addition to +using one of the environment repositories from Spring Cloud. To do this your bean +must implement the EnvironmentRepository interface. If you would like to control +the priority of you custom EnvironmentRepository within the composite +environment you should also implement the Ordered interface and override the +getOrdered method. If you do not implement the Ordered interface then your +EnvironmentRepository will be given the lowest priority.

2.1.8 Property Overrides

The Config Server has an "overrides" feature that allows the operator +to provide configuration properties to all applications that cannot be +accidentally changed by the application using the normal Spring Boot +hooks. To declare overrides just add a map of name-value pairs to +spring.cloud.config.server.overrides. For example

spring:
+  cloud:
+    config:
+      server:
+        overrides:
+          foo: bar

will cause all applications that are config clients to read foo=bar +independent of their own configuration. (Of course an application can +use the data in the Config Server in any way it likes, so overrides +are not enforceable, but they do provide useful default behaviour if +they are Spring Cloud Config clients.)

[Tip]Tip

Normal, Spring environment placeholders with "${}" can be escaped +(and resolved on the client) by using backslash ("\") to escape the +"$" or the "{", e.g. \${app.foo:bar} resolves to "bar" unless the +app provides its own "app.foo". Note that in YAML you don’t need to +escape the backslash itself, but in properties files you do, when you +configure the overrides on the server.

You can change the priority of all overrides in the client to be more +like default values, allowing applications to supply their own values +in environment variables or System properties, by setting the flag +spring.cloud.config.overrideNone=true (default is false) in the +remote repository.

2.2 Health Indicator

Config Server comes with a Health Indicator that checks if the configured +EnvironmentRepository is working. By default it asks the EnvironmentRepository +for an application named app, the default profile and the default +label provided by the EnvironmentRepository implementation.

You can configure the Health Indicator to check more applications +along with custom profiles and custom labels, e.g.

spring:
+  cloud:
+    config:
+      server:
+        health:
+          repositories:
+            myservice:
+              label: mylabel
+            myservice-dev:
+              name: myservice
+              profiles: development

You can disable the Health Indicator by setting spring.cloud.config.server.health.enabled=false.

2.3 Security

You are free to secure your Config Server in any way that makes sense +to you (from physical network security to OAuth2 bearer +tokens), and Spring Security and Spring Boot make it easy to do pretty +much anything.

To use the default Spring Boot configured HTTP Basic security, just +include Spring Security on the classpath (e.g. through +spring-boot-starter-security). The default is a username of "user" +and a randomly generated password, which isn’t going to be very useful +in practice, so we recommend you configure the password (via +security.user.password) and encrypt it (see below for instructions +on how to do that).

2.4 Encryption and Decryption

[Important]Important

Prerequisites: to use the encryption and decryption features +you need the full-strength JCE installed in your JVM (it’s not there by default). +You can download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" +from Oracle, and follow instructions for installation (essentially replace the 2 policy files +in the JRE lib/security directory with the ones that you downloaded).

If the remote property sources contain encrypted content (values +starting with {cipher}) they will be decrypted before sending to +clients over HTTP. The main advantage of this set up is that the +property values don’t have to be in plain text when they are "at rest" +(e.g. in a git repository). If a value cannot be decrypted it is +removed from the property source and an additional property is added +with the same key, but prefixed with "invalid." and a value that means +"not applicable" (usually "<n/a>"). This is largely to prevent cipher +text being used as a password and accidentally leaking.

If you are setting up a remote config repository for config client +applications it might contain an application.yml like this, for +instance:

application.yml.  +

spring:
+  datasource:
+    username: dbuser
+    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

+

Encrypted values in a .properties file must not be wrapped in quotes, otherwise the value will not be decrypted:

application.properties.  +

spring.datasource.username: dbuser
+spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

+

You can safely push this plain text to a shared git repository and the +secret password is protected.

The server also exposes /encrypt and /decrypt endpoints (on the +assumption that these will be secured and only accessed by authorized +agents). If you are editing a remote config file you can use the Config Server +to encrypt values by POSTing to the /encrypt endpoint, e.g.

$ curl localhost:8888/encrypt -d mysecret
+682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
[Note]Note

If the value you are encrypting has characters in it that need to be URL encoded you should use +the --data-urlencode option to curl to make sure they are encoded properly.

[Tip]Tip

Be sure not to include any of the curl command statistics in the encrypted value. +Outputting the value to a file can help avoid this problem.

The inverse operation is also available via /decrypt (provided the server is +configured with a symmetric key or a full key pair):

$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
+mysecret
[Tip]Tip

If you are testing like this with curl, then use +--data-urlencode (instead of -d) or set an explicit Content-Type: +text/plain to make sure curl encodes the data correctly when there +are special characters ('+' is particularly tricky).

Take the encrypted value and add the {cipher} prefix before you put +it in the YAML or properties file, and before you commit and push it +to a remote, potentially insecure store.

The /encrypt and /decrypt endpoints also both accept paths of the +form /*/{name}/{profiles} which can be used to control cryptography +per application (name) and profile when clients call into the main +Environment resource.

[Note]Note

to control the cryptography in this granular way you must also +provide a @Bean of type TextEncryptorLocator that creates a +different encryptor per name and profiles. The one that is provided +by default does not do this (so all encryptions use the same key).

The spring command line client (with Spring Cloud CLI extensions +installed) can also be used to encrypt and decrypt, e.g.

$ spring encrypt mysecret --key foo
+682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
+$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
+mysecret

To use a key in a file (e.g. an RSA public key for encryption) prepend +the key value with "@" and provide the file path, e.g.

$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
+AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...

The key argument is mandatory (despite having a -- prefix).

2.5 Key Management

The Config Server can use a symmetric (shared) key or an asymmetric +one (RSA key pair). The asymmetric choice is superior in terms of +security, but it is often more convenient to use a symmetric key since +it is just a single property value to configure in the bootstrap.properties.

To configure a symmetric key you just need to set encrypt.key to a +secret String (or use an enviroment variable ENCRYPT_KEY to keep it +out of plain text configuration files).

To configure an asymmetric key you can either set the key as a +PEM-encoded text value (in encrypt.key), or via a keystore (e.g. as +created by the keytool utility that comes with the JDK). The +keystore properties are encrypt.keyStore.* with * equal to

  • location (a Resource location),
  • password (to unlock the keystore) and
  • alias (to identify which key in the store is to be +used).

The encryption is done with the public key, and a private key is +needed for decryption. Thus in principle you can configure only the +public key in the server if you only want to do encryption (and are +prepared to decrypt the values yourself locally with the private +key). In practice you might not want to do that because it spreads the +key management process around all the clients, instead of +concentrating it in the server. On the other hand it’s a useful option +if your config server really is relatively insecure and only a +handful of clients need the encrypted properties.

2.6 Creating a Key Store for Testing

To create a keystore for testing you can do something like this:

$ keytool -genkeypair -alias mytestkey -keyalg RSA \
+  -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
+  -keypass changeme -keystore server.jks -storepass letmein

Put the server.jks file in the classpath (for instance) and then in +your bootstrap.yml for the Config Server:

encrypt:
+  keyStore:
+    location: classpath:/server.jks
+    password: letmein
+    alias: mytestkey
+    secret: changeme

2.7 Using Multiple Keys and Key Rotation

In addition to the {cipher} prefix in encrypted property values, the +Config Server looks for {name:value} prefixes (zero or many) before +the start of the (Base64 encoded) cipher text. The keys are passed to +a TextEncryptorLocator which can do whatever logic it needs to +locate a TextEncryptor for the cipher. If you have configured a +keystore (encrypt.keystore.location) the default locator will look +for keys in the store with aliases as supplied by the "key" prefix, +i.e. with a cipher text like this:

foo:
+  bar: `{cipher}{key:testkey}...`

the locator will look for a key named "testkey". A secret can also be +supplied via a {secret:…​} value in the prefix, but if it is not +the default is to use the keystore password (which is what you get +when you build a keytore and don’t specify a secret). If you do +supply a secret it is recommended that you also encrypt the secrets +using a custom SecretLocator.

Key rotation is hardly ever necessary on cryptographic grounds if the +keys are only being used to encrypt a few bytes of configuration data +(i.e. they are not being used elsewhere), but occasionally you might +need to change the keys if there is a security breach for instance. In +that case all the clients would need to change their source config +files (e.g. in git) and use a new {key:…​} prefix in all the +ciphers, checking beforehand of course that the key alias is available +in the Config Server keystore.

[Tip]Tip

the {name:value} prefixes can also be added to plaintext posted +to the /encrypt endpoint, if you want to let the Config Server +handle all encryption as well as decryption.

2.8 Serving Encrypted Properties

Sometimes you want the clients to decrypt the configuration locally, +instead of doing it in the server. In that case you can still have +/encrypt and /decrypt endpoints (if you provide the encrypt.* +configuration to locate a key), but you need to explicitly switch off +the decryption of outgoing properties by placing +spring.cloud.config.server.encrypt.enabled=false in bootstrap.[yml|properties]. +If you don’t care about the endpoints, then it should work if you configure neither the +key nor the enabled flag.

3. Serving Alternative Formats

The default JSON format from the environment endpoints is perfect for +consumption by Spring applications because it maps directly onto the +Environment abstraction. If you prefer you can consume the same data +as YAML or Java properties by adding a suffix to the resource path +(".yml", ".yaml" or ".properties"). This can be useful for consumption +by applications that do not care about the structure of the JSON +endpoints, or the extra metadata they provide, for example an +application that is not using Spring might benefit from the simplicity +of this approach.

The YAML and properties representations have an additional flag +(provided as a boolean query parameter resolvePlaceholders) to +signal that placeholders in the source documents, in the standard +Spring ${…​} form, should be resolved in the output where possible +before rendering. This is a useful feature for consumers that don’t +know about the Spring placeholder conventions.

[Note]Note

there are limitations in using the YAML or properties formats, +mainly in relation to the loss of metadata. The JSON is structured as +an ordered list of property sources, for example, with names that +correlate with the source. The YAML and properties forms are coalesced +into a single map, even if the origin of the values has multiple +sources, and the names of the original source files are lost. The YAML +representation is not necessarily a faithful representation of the +YAML source in a backing repository either: it is constructed from a +list of flat property sources, and assumptions have to be made about +the form of the keys.

4. Serving Plain Text

Instead of using the Environment abstraction (or one of the +alternative representations of it in YAML or properties format) your +applications might need generic plain text configuration files, +tailored to their environment. The Config Server provides these +through an additional endpoint at /{name}/{profile}/{label}/{path} +where "name", "profile" and "label" have the same meaning as the +regular environment endpoint, but "path" is a file name +(e.g. log.xml). The source files for this endpoint are located in +the same way as for the environment endpoints: the same search path is +used as for properties or YAML files, but instead of aggregating all +matching resources, only the first one to match is returned.

After a resource is located, placeholders in the normal format +(${…​}) are resolved using the effective Environment for the +application name, profile and label supplied. In this way the resource +endpoint is tightly integrated with the environment +endpoints. Example, if you have this layout for a GIT (or SVN) +repository:

application.yml
+nginx.conf

where nginx.conf looks like this:

server {
+    listen              80;
+    server_name         ${nginx.server.name};
+}

and application.yml like this:

nginx:
+  server:
+    name: example.com
+---
+spring:
+  profiles: development
+nginx:
+  server:
+    name: develop.com

then the /foo/default/master/nginx.conf resource looks like this:

server {
+    listen              80;
+    server_name         example.com;
+}

and /foo/development/master/nginx.conf like this:

server {
+    listen              80;
+    server_name         develop.com;
+}
[Note]Note

Just like the source files for environment configuration, the +"profile" is used to resolve the file name, so if you want a +profile-specific file then /*/development/*/logback.xml will be +resolved by a file called logback-development.xml (in preference +to logback.xml).

[Note]Note

If you do not want to supply the label and let the server use the default label, you can supply a useDefaultLabel request parameter. So, the above example for the default profile could look like /foo/default/nginx.conf?useDefaultLabel.

5. Embedding the Config Server

The Config Server runs best as a standalone application, but if you +need to you can embed it in another application. Just use the +@EnableConfigServer annotation. An optional property that can be +useful in this case is spring.cloud.config.server.bootstrap which is +a flag to indicate that the server should configure itself from its +own remote repository. The flag is off by default because it can delay +startup, but when embedded in another application it makes sense to +initialize the same way as any other application.

[Note]Note

It should be obvious, but remember that if you use the bootstrap +flag the config server will need to have its name and repository URI +configured in bootstrap.yml.

To change the location of the server endpoints you can (optionally) +set spring.cloud.config.server.prefix, e.g. "/config", to serve the +resources under a prefix. The prefix should start but not end with a +"/". It is applied to the @RequestMappings in the Config Server +(i.e. underneath the Spring Boot prefixes server.servletPath and +server.contextPath).

If you want to read the configuration for an application directly from +the backend repository (instead of from the config server) that’s +basically an embedded config server with no endpoints. You can switch +off the endpoints entirely if you don’t use the @EnableConfigServer +annotation (just set spring.cloud.config.server.bootstrap=true).

6. Push Notifications and Spring Cloud Bus

Many source code repository providers (like Github, Gitlab or Bitbucket +for instance) will notify you of changes in a repository through a +webhook. You can configure the webhook via the provider’s user +interface as a URL and a set of events in which you are +interested. For instance +Github +will POST to the webhook with a JSON body containing a list of +commits, and a header "X-Github-Event" equal to "push". If you add a +dependency on the spring-cloud-config-monitor library and activate +the Spring Cloud Bus in your Config Server, then a "/monitor" endpoint +is enabled.

When the webhook is activated the Config Server will send a +RefreshRemoteApplicationEvent targeted at the applications it thinks +might have changed. The change detection can be strategized, but by +default it just looks for changes in files that match the application +name (e.g. "foo.properties" is targeted at the "foo" application, and +"application.properties" is targeted at all applications). The strategy +if you want to override the behaviour is PropertyPathNotificationExtractor +which accepts the request headers and body as parameters and returns a list +of file paths that changed.

The default configuration works out of the box with Github, Gitlab or +Bitbucket. In addition to the JSON notifications from Github, Gitlab +or Bitbucket you can trigger a change notification by POSTing to +"/monitor" with a form-encoded body parameters path={name}. This will +broadcast to applications matching the "{name}" pattern (can contain +wildcards).

[Note]Note

the RefreshRemoteApplicationEvent will only be transmitted if +the spring-cloud-bus is activated in the Config Server and in the +client application.

[Note]Note

the default configuration also detects filesystem changes in +local git repositories (the webhook is not used in that case but as +soon as you edit a config file a refresh will be broadcast).

7. Spring Cloud Config Client

A Spring Boot application can take immediate advantage of the Spring +Config Server (or other external property sources provided by the +application developer), and it will also pick up some additional +useful features related to Environment change events.

7.1 Config First Bootstrap

This is the default behaviour for any application which has the Spring +Cloud Config Client on the classpath. When a config client starts up +it binds to the Config Server (via the bootstrap configuration +property spring.cloud.config.uri) and initializes Spring +Environment with remote property sources.

The net result of this is that all client apps that want to consume +the Config Server need a bootstrap.yml (or an environment variable) +with the server address in spring.cloud.config.uri (defaults to +"http://localhost:8888").

7.2 Discovery First Bootstrap

If you are using a `DiscoveryClient implementation, such as Spring Cloud Netflix +and Eureka Service Discovery or Spring Cloud Consul (Spring Cloud Zookeeper does +not support this yet), then you can have the Config Server register with the +Discovery Service if you want to, but in the default "Config First" mode, +clients won’t be able to take advantage of the registration.

If you prefer to use DiscoveryClient to locate the Config Server, you can do +that by setting spring.cloud.config.discovery.enabled=true (default +"false"). The net result of that is that client apps all need a +bootstrap.yml (or an environment variable) with the appropriate discovery +configuration. For example, with Spring Cloud Netflix, you need to define the +Eureka server address, e.g. in eureka.client.serviceUrl.defaultZone. The +price for using this option is an extra network round trip on start up to +locate the service registration. The benefit is that the Config Server +can change its co-ordinates, as long as the Discovery Service is a fixed point. The +default service id is "configserver" but you can change that on the +client with spring.cloud.config.discovery.serviceId (and on the server +in the usual way for a service, e.g. by setting spring.application.name).

The discovery client implementations all support some kind of metadata +map (e.g. for Eureka we have eureka.instance.metadataMap). Some +additional properties of the Config Server may need to be configured +in its service registration metadata so that clients can connect +correctly. If the Config Server is secured with HTTP Basic you can +configure the credentials as "username" and "password". And if the +Config Server has a context path you can set "configPath". Example, +for a Config Server that is a Eureka client:

bootstrap.yml.  +

eureka:
+  instance:
+    ...
+    metadataMap:
+      user: osufhalskjrtl
+      password: lviuhlszvaorhvlo5847
+      configPath: /config

+

7.3 Config Client Fail Fast

In some cases, it may be desirable to fail startup of a service if +it cannot connect to the Config Server. If this is the desired +behavior, set the bootstrap configuration property +spring.cloud.config.failFast=true and the client will halt with +an Exception.

7.4 Config Client Retry

If you expect that the config server may occasionally be unavailable when +your app starts, you can ask it to keep trying after a failure. First you need +to set spring.cloud.config.failFast=true, and then 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.config.retry.* configuration properties.

[Tip]Tip

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

7.5 Locating Remote Configuration Resources

The Config Service serves property sources from /{name}/{profile}/{label}, where the default bindings in the client app are

  • "name" = ${spring.application.name}
  • "profile" = ${spring.profiles.active} (actually Environment.getActiveProfiles())
  • "label" = "master"

All of them can be overridden by setting spring.cloud.config.* +(where * is "name", "profile" or "label"). The "label" is useful for +rolling back to previous versions of configuration; with the default +Config Server implementation it can be a git label, branch name or +commit id. Label can also be provided as a comma-separated list, in +which case the items in the list are tried on-by-one until one succeeds. +This can be useful when working on a feature branch, for instance, +when you might want to align the config label with your branch, but +make it optional (e.g. spring.cloud.config.label=myfeature,develop).

7.6 Security

If you use HTTP Basic security on the server then clients just need to +know the password (and username if it isn’t the default). You can do +that via the config server URI, or via separate username and password +properties, e.g.

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+     uri: https://user:secret@myconfig.mycompany.com

+

or

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+     uri: https://myconfig.mycompany.com
+     username: user
+     password: secret

+

The spring.cloud.config.password and spring.cloud.config.username +values override anything that is provided in the URI.

If you deploy your apps on Cloud Foundry then the best way to provide +the password is through service credentials, e.g. in the URI, since +then it doesn’t even need to be in a config file. An example which +works locally and for a user-provided service on Cloud Foundry named +"configserver":

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+     uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}

+

If you use another form of security you might need to provide a +RestTemplate to the ConfigServicePropertySourceLocator (e.g. by +grabbing it in the bootstrap context and injecting one).

7.6.1 Health Indicator

The Config Client supplies a Spring Boot Health Indicator that attempts to load configuration from Config Server. The health indicator can be disabled by setting health.config.enabled=false. The response is also cached for performance reasons. The default cache time to live is 5 minutes. To change that value set the health.config.time-to-live property (in milliseconds).

7.6.2 Providing A Custom RestTemplate

In some cases you might need to customize the requests made to the config server from +the client. Typically this involves passing special Authorization headers to +authenticate requests to the server. To provide a custom RestTemplate follow the +steps below.

  1. Create a new configuration bean with an implementation of PropertySourceLocator.

CustomConfigServiceBootstrapConfiguration.java.  +

@Configuration
+public class CustomConfigServiceBootstrapConfiguration {
+    @Bean
+    public ConfigServicePropertySourceLocator configServicePropertySourceLocator() {
+        ConfigClientProperties clientProperties = configClientProperties();
+       ConfigServicePropertySourceLocator configServicePropertySourceLocator =  new ConfigServicePropertySourceLocator(clientProperties);
+        configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties));
+        return configServicePropertySourceLocator;
+    }
+}

+

  1. In resources/META-INF create a file called +spring.factories and specify your custom configuration.

spring.factories.  +

org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration

+

7.6.3 Vault

When using Vault as a backend to your config server the client will need to +supply a token for the server to retrieve values from Vault. This token +can be provided within the client by setting spring.cloud.config.token +in bootstrap.yml.

bootstrap.yml.  +

spring:
+  cloud:
+    config:
+      token: YourVaultToken

+

7.7 Vault

7.7.1 Nested Keys In Vault

Vault supports the ability to nest keys in a value stored in Vault. For example

echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp -

This command will write a JSON object to your Vault. To access these values in Spring +you would use the traditional dot(.) annotation. For example

@Value("${appA.secret}")
+String name = "World";

The above code would set the name variable to appAsecret.

\ No newline at end of file diff --git a/spring-cloud-config/1.4.4.RELEASE/spring-cloud-config.xml b/spring-cloud-config/1.4.4.RELEASE/spring-cloud-config.xml new file mode 100644 index 00000000..97ed7f1c --- /dev/null +++ b/spring-cloud-config/1.4.4.RELEASE/spring-cloud-config.xml @@ -0,0 +1,1528 @@ + + + + + +Spring Cloud Config +2018-06-28 + + + +1.4.4.RELEASE +Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications, but can be used with any application running in any language. As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate. The default implementation of the server storage backend uses git so it easily supports labelled versions of configuration environments, as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with Spring configuration. + + +Quick Start +Start the server: +$ cd spring-cloud-config-server +$ ../mvnw spring-boot:run +The server is a Spring Boot application so you can run it from your +IDE instead if you prefer (the main class is +ConfigServerApplication). Then try out a client: +$ curl localhost:8888/foo/development +{"name":"foo","label":"master","propertySources":[ + {"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}}, + {"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}} +]} +The default strategy for locating property sources is to clone a git +repository (at spring.cloud.config.server.git.uri) and use it to +initialize a mini SpringApplication. The mini-application’s +Environment is used to enumerate property sources and publish them +via a JSON endpoint. +The HTTP service has resources in the form: +/{application}/{profile}[/{label}] +/{application}-{profile}.yml +/{label}/{application}-{profile}.yml +/{application}-{profile}.properties +/{label}/{application}-{profile}.properties +where the "application" is injected as the spring.config.name in the +SpringApplication (i.e. what is normally "application" in a regular +Spring Boot app), "profile" is an active profile (or comma-separated +list of properties), and "label" is an optional git label (defaults to +"master".) +Spring Cloud Config Server pulls configuration for remote clients +from a git repository (which must be provided): +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo +
+Client Side Usage +To use these features in an application, just build it as a Spring +Boot application that depends on spring-cloud-config-client (e.g. see +the test cases for the config-client, or the sample app). The most +convenient way to add the dependency is via a Spring Boot starter +org.springframework.cloud:spring-cloud-starter-config. There is also a +parent pom and BOM (spring-cloud-starter-parent) for Maven users and a +Spring IO version management properties file for Gradle and Spring CLI +users. Example Maven configuration: + +pom.xml + + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>1.5.10.RELEASE</version> + <relativePath /> <!-- lookup parent from repository --> + </parent> + +<dependencyManagement> + <dependencies> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-dependencies</artifactId> + <version>Edgware.SR2</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> +</dependencyManagement> + +<dependencies> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-starter-config</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> +</dependencies> + +<build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + </plugins> +</build> + + <!-- repositories also needed for snapshots and milestones --> + + +Then you can create a standard Spring Boot application, like this simple HTTP server: +@SpringBootApplication +@RestController +public class Application { + + @RequestMapping("/") + public String home() { + return "Hello World!"; + } + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} +When it runs it will pick up the external configuration from the +default local config server on port 8888 if it is running. To modify +the startup behaviour you can change the location of the config server +using bootstrap.properties (like application.properties but for +the bootstrap phase of an application context), e.g. +spring.cloud.config.uri: http://myconfigserver.com +The bootstrap properties will show up in the /env endpoint as a +high-priority property source, e.g. +$ curl localhost:8080/env +{ + "profiles":[], + "configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"}, + "servletContextInitParams":{}, + "systemProperties":{...}, + ... +} +(a property source called "configService:<URL of remote +repository>/<file name>" contains the property "foo" with value +"bar" and is highest priority). + +the URL in the property source name is the git repository not +the config server URL. + +
+
+ +Spring Cloud Config Server +The Server provides an HTTP, resource-based API for external +configuration (name-value pairs, or equivalent YAML content). The +server is easily embeddable in a Spring Boot application using the +@EnableConfigServer annotation. So this app is a config server: + +ConfigServer.java + +@SpringBootApplication +@EnableConfigServer +public class ConfigServer { + public static void main(String[] args) { + SpringApplication.run(ConfigServer.class, args); + } +} + + +Like all Spring Boot apps it runs on port 8080 by default, but you +can switch it to the conventional port 8888 in various ways. The +easiest, which also sets a default configuration repository, +is by launching it with spring.config.name=configserver (there +is a configserver.yml in the Config Server jar). Another is +to use your own application.properties, e.g. + +application.properties + +server.port: 8888 +spring.cloud.config.server.git.uri: file://${user.home}/config-repo + + +where ${user.home}/config-repo is a git repository containing +YAML and properties files. + +in Windows you need an extra "/" in the file URL if it is +absolute with a drive prefix, e.g. file:///${user.home}/config-repo. + + +Here’s a recipe for creating the git repository in the example +above: +$ cd $HOME +$ mkdir config-repo +$ cd config-repo +$ git init . +$ echo info.foo: bar > application.properties +$ git add -A . +$ git commit -m "Add application.properties" + + +using the local filesystem for your git repository is +intended for testing only. Use a server to host your +configuration repositories in production. + + +the initial clone of your configuration repository will +be quick and efficient if you only keep text files in it. If you start +to store binary files, especially large ones, you may experience +delays on the first request for configuration and/or out of memory +errors in the server. + +
+Environment Repository +Where do you want to store the configuration data for the Config +Server? The strategy that governs this behaviour is the +EnvironmentRepository, serving Environment objects. This +Environment is a shallow copy of the domain from the Spring +Environment (including propertySources as the main feature). The +Environment resources are parametrized by three variables: + + +{application} maps to "spring.application.name" on the client side; + + +{profile} maps to "spring.profiles.active" on the client (comma separated list); and + + +{label} which is a server side feature labelling a "versioned" set of config files. + + +Repository implementations generally behave just like a Spring Boot +application loading configuration files from a "spring.config.name" +equal to the {application} parameter, and "spring.profiles.active" +equal to the {profiles} parameter. Precedence rules for profiles are +also the same as in a regular Boot application: active profiles take +precedence over defaults, and if there are multiple profiles the last +one wins (like adding entries to a Map). +Example: a client application has this bootstrap configuration: + +bootstrap.yml + +spring: + application: + name: foo + profiles: + active: dev,mysql + + +(as usual with a Spring Boot application, these properties could also +be set as environment variables or command line arguments). +If the repository is file-based, the server will create an +Environment from application.yml (shared between all clients), and +foo.yml (with foo.yml taking precedence). If the YAML files have +documents inside them that point to Spring profiles, those are applied +with higher precedence (in order of the profiles listed), and if +there are profile-specific YAML (or properties) files these are also +applied with higher precedence than the defaults. Higher precedence +translates to a PropertySource listed earlier in the +Environment. (These are the same rules as apply in a standalone +Spring Boot application.) +
+Git Backend +The default implementation of EnvironmentRepository uses a Git +backend, which is very convenient for managing upgrades and physical +environments, and also for auditing changes. To change the location of +the repository you can set the "spring.cloud.config.server.git.uri" +configuration property in the Config Server (e.g. in +application.yml). If you set it with a file: prefix it should work +from a local repository so you can get started quickly and easily +without a server, but in that case the server operates directly on the +local repository without cloning it (it doesn’t matter if it’s not +bare because the Config Server never makes changes to the "remote" +repository). To scale the Config Server up and make it highly +available, you would need to have all instances of the server pointing +to the same repository, so only a shared file system would work. Even +in that case it is better to use the ssh: protocol for a shared +filesystem repository, so that the server can clone it and use a local +working copy as a cache. +This repository implementation maps the {label} parameter of the +HTTP resource to a git label (commit id, branch name or tag). If the +git branch or tag name contains a slash ("/") then the label in the +HTTP URL should be specified with the special string "(_)" instead (to +avoid ambiguity with other URL paths). For example, if the label is +foo/bar, replacing the slash would result in a label that looks like +foo(_)bar. The inclusion of the special string "(_)" can also be +applied to the {application} parameter. Be careful with the brackets +in the URL if you are using a command line client like curl (e.g. +escape them from the shell with quotes ''). +
+Placeholders in Git URI +Spring Cloud Config Server supports a git repository URL with +placeholders for the {application} and {profile} (and {label} if +you need it, but remember that the label is applied as a git label +anyway). So you can easily support a "one repo per application" policy +using (for example): +spring: + cloud: + config: + server: + git: + uri: https://github.com/myorg/{application} +or a "one repo per profile" policy using a similar pattern but with +{profile}. +Additionally, using the special string "(_)" within your +{application} parameters can enable support for multiple +organizations (for example): +spring: + cloud: + config: + server: + git: + uri: https://github.com/{application} +where {application} is provided at request time in the format +"organization(_)application". +
+
+Pattern Matching and Multiple Repositories +There is also support for more complex requirements with pattern +matching on the application and profile name. The pattern format is a +comma-separated list of {application}/{profile} names with wildcards +(where a pattern beginning with a wildcard may need to be +quoted). Example: +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo + repos: + simple: https://github.com/simple/config-repo + special: + pattern: special*/dev*,*special*/dev* + uri: https://github.com/special/config-repo + local: + pattern: local* + uri: file:/home/configsvc/config-repo +If {application}/{profile} does not match any of the patterns, it +will use the default uri defined under +"spring.cloud.config.server.git.uri". In the above example, for the +"simple" repository, the pattern is simple/* (i.e. it only matches +one application named "simple" in all profiles). The "local" +repository matches all application names beginning with "local" in all +profiles (the /* suffix is added automatically to any pattern that +doesn’t have a profile matcher). + +the "one-liner" short cut used in the "simple" example above can +only be used if the only property to be set is the URI. If you need to +set anything else (credentials, pattern, etc.) you need to use the full +form. + +The pattern property in the repo is actually an array, so you can +use a YAML array (or [0], [1], etc. suffixes in properties files) +to bind to multiple patterns. You may need to do this if you are going +to run apps with multiple profiles. Example: +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo + repos: + development: + pattern: + - '*/development' + - '*/staging' + uri: https://github.com/development/config-repo + staging: + pattern: + - '*/qa' + - '*/production' + uri: https://github.com/staging/config-repo + +Spring Cloud will guess that a pattern containing a profile that +doesn’t end in * implies that you actually want to match a list of +profiles starting with this pattern (so */staging is a shortcut for +["*/staging", "*/staging,*"]). This is common where you need to run +apps in the "development" profile locally but also the "cloud" profile +remotely, for instance. + +Every repository can also optionally store config files in +sub-directories, and patterns to search for those directories can be +specified as searchPaths. For example at the top level: +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo + searchPaths: foo,bar* +In this example the server searches for config files in the top level +and in the "foo/" sub-directory and also any sub-directory whose name +begins with "bar". +By default the server clones remote repositories when configuration +is first requested. The server can be configured to clone the repositories +at startup. For example at the top level: +spring: + cloud: + config: + server: + git: + uri: https://git/common/config-repo.git + repos: + team-a: + pattern: team-a-* + cloneOnStart: true + uri: http://git/team-a/config-repo.git + team-b: + pattern: team-b-* + cloneOnStart: false + uri: http://git/team-b/config-repo.git + team-c: + pattern: team-c-* + uri: http://git/team-a/config-repo.git +In this example the server clones team-a’s config-repo on startup before it +accepts any requests. All other repositories will not be cloned until +configuration from the repository is requested. + +Setting a repository to be cloned when the Config Server starts up can +help to identify a misconfigured configuration source (e.g., an invalid +repository URI) quickly, while the Config Server is starting up. With +cloneOnStart not enabled for a configuration source, the Config Server may +start successfully with a misconfigured or invalid configuration source and +not detect an error until an application requests configuration from that +configuration source. + +
+
+Authentication +To use HTTP basic authentication on the remote repository add the +"username" and "password" properties separately (not in the URL), +e.g. +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo + username: trolley + password: strongpassword +If you don’t use HTTPS and user credentials, SSH should also work out +of the box when you store keys in the default directories (~/.ssh) +and the uri points to an SSH location, +e.g. "git@github.com:configuration/cloud-configuration". It is important that an entry for the Git server be present in the ~/.ssh/known_hosts file and that it is in ssh-rsa format. Other formats (like ecdsa-sha2-nistp256) are not supported. To avoid surprises, you should ensure that only one entry is present in the known_hosts file for the Git server and that it is matching with the URL you provided to the config server. If you used a hostname in the URL, you want to have exactly that in the known_hosts file, not the IP. +The repository is accessed using JGit, so any documentation you find on +that should be applicable. HTTPS proxy settings can be set in +~/.git/config or in the same way as for any other JVM process via +system properties (-Dhttps.proxyHost and -Dhttps.proxyPort). + +If you don’t know where your ~/.git directory is use git config +--global to manipulate the settings (e.g. git config --global +http.sslVerify false). + +
+
+Authentication with AWS CodeCommit +AWS CodeCommit authentication can also be +done. AWS CodeCommit uses an authentication helper when using Git from the command line. This helper is not +used with the JGit library, so a JGit CredentialProvider for AWS CodeCommit will be created if the Git +URI matches the AWS CodeCommit pattern. AWS CodeCommit URIs always look like +https://git-codecommit.${AWS_REGION}.amazonaws.com/${repopath}. +If you provide a username and password with an AWS CodeCommit URI, then these must be +the AWS accessKeyId and secretAccessKey +to be used to access the repository. If you do not specify a username and password, +then the accessKeyId and secretAccessKey will be retrieved using the +AWS Default Credential Provider Chain. +If your Git URI matches the CodeCommit URI pattern (above) then you must provide +valid AWS credentials in the username and password, or in one of the locations supported +by the default credential provider chain. AWS EC2 instances may use +IAM Roles for EC2 Instances. +Note: The aws-java-sdk-core jar is an optional dependency. If the aws-java-sdk-core jar is not on your +classpath, then the AWS Code Commit credential provider will not be created regardless of the git server URI. +
+
+Git SSH configuration using properties +By default, the JGit library used by Spring Cloud Config Server uses SSH configuration files such as ~/.ssh/known_hosts and /etc/ssh/ssh_config when connecting to Git repositories using an SSH URI. +In cloud environments such as Cloud Foundry, the local filesystem may be ephemeral or not easily accessible. For cases such as these, SSH configuration can be set using +Java properties. In order to activate property based SSH configuration, the property spring.cloud.config.server.git.ignoreLocalSshSettings must be set to true. +Example: + spring: + cloud: + config: + server: + git: + uri: git@gitserver.com:team/repo1.git + ignoreLocalSshSettings: true + hostKey: someHostKey + hostKeyAlgorithm: ssh-rsa + privateKey: | + -----BEGIN RSA PRIVATE KEY----- + MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX + IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF + ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud + 1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i + oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W + DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd + fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b + BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG + EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj + 5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8 + +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe + pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG + ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ + xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW + dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi + PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX + VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z + FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R + gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4 + VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV + cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee + KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N + CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs + q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J + 69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT + -----END RSA PRIVATE KEY----- + +SSH Configuration properties + + + + + +Property Name +Remarks + + + + +ignoreLocalSshSettings +If true, use property based SSH config instead of file based. Must be set at as spring.cloud.config.server.git.ignoreLocalSshSettings, not inside a repository definition. + + +privateKey +Valid SSH private key. Must be set if ignoreLocalSshSettings is true and Git URI is SSH format + + +hostKey +Valid SSH host key. Must be set if hostKeyAlgorithm is also set + + +hostKeyAlgorithm +One of ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 ,ecdsa-sha2-nistp521. Must be set if hostKey is also set + + +proxyHost +Hostname for the ssh proxy connection. Is optional and used only when ignoreLocalSshSettings is true + + +proxyPort +Port for the ssh proxy connection. Must be set if proxyHost is also set + + +strictHostKeyChecking +true or false. If false, ignore errors with host key + + +knownHostsFile +Location of custom .known_hosts file + + +preferredAuthentications +Override server authentication method order. This should allow evade login prompts if server has keyboard-interactive authentication before publickey method. + + + +
+
+
+Placeholders in Git Search Paths +Spring Cloud Config Server also supports a search path with +placeholders for the {application} and {profile} (and {label} if +you need it). Example: +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo + searchPaths: '{application}' +searches the repository for files in the same name as the directory +(as well as the top level). Wildcards are also valid in a search +path with placeholders (any matching directory is included in the +search). +
+
+Force pull in Git Repositories +As mentioned before Spring Cloud Config Server makes a clone of the +remote git repository and if somehow the local copy gets dirty (e.g. +folder content changes by OS process) so Spring Cloud Config Server +cannot update the local copy from remote repository. +To solve this there is a force-pull property that will make Spring Cloud +Config Server force pull from remote repository if the local copy is dirty. +Example: +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo + force-pull: true +If you have a multiple repositories configuration you can configure the +force-pull property per repository. Example: +spring: + cloud: + config: + server: + git: + uri: https://git/common/config-repo.git + force-pull: true + repos: + team-a: + pattern: team-a-* + uri: http://git/team-a/config-repo.git + force-pull: true + team-b: + pattern: team-b-* + uri: http://git/team-b/config-repo.git + force-pull: true + team-c: + pattern: team-c-* + uri: http://git/team-a/config-repo.git + +The default value for force-pull property is false. + +
+
+Deleting untracked branches in Git Repositories +As Spring Cloud Config Server has a clone of the remote git repository +after check-outing branch to local repo (e.g fetching properties by label) it will keep this branch +forever or till the next server restart (which creates new local repo). +So there could be a case when remote branch is deleted but local copy of it is still available for fetching. +And if Spring Cloud Config Server client service starts with --spring.cloud.config.label=deletedRemoteBranch,master +it will fetch properties from deletedRemoteBranch local branch, but not from master. +In order to keep local repository branches clean and up to remote - deleteUntrackedBranches property could be set. +It will make Spring Cloud Config Server force delete untracked branches from local repository. +Example: +spring: + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud-samples/config-repo + deleteUntrackedBranches: true + +The default value for deleteUntrackedBranches property is false. + +
+
+
+Version Control Backend Filesystem Use + +With VCS based backends (git, svn) files are checked out or cloned to the local filesystem. By default they are put in the system temporary directory with a prefix of config-repo-. On linux, for example it could be /tmp/config-repo-<randomid>. Some operating systems routinely clean out temporary directories. This can lead to unexpected behaviour such as missing properties. To avoid this problem, change the directory Config Server uses, by setting spring.cloud.config.server.git.basedir or spring.cloud.config.server.svn.basedir to a directory that does not reside in the system temp structure. + +
+
+File System Backend +There is also a "native" profile in the Config Server that doesn’t use +Git, but just loads the config files from the local classpath or file +system (any static URL you want to point to with +"spring.cloud.config.server.native.searchLocations"). To use the +native profile just launch the Config Server with +"spring.profiles.active=native". + +Remember to use the file: prefix for file resources (the +default without a prefix is usually the classpath). Just as with any +Spring Boot configuration you can embed ${}-style environment +placeholders, but remember that absolute paths in Windows require an +extra "/", e.g. file:///${user.home}/config-repo + + +The default value of the searchLocations is identical to a +local Spring Boot application (so [classpath:/, classpath:/config, +file:./, file:./config]). This does not expose the +application.properties from the server to all clients because any +property sources present in the server are removed before being sent +to the client. + + +A filesystem backend is great for getting started quickly and +for testing. To use it in production you need to be sure that the +file system is reliable, and shared across all instances of the +Config Server. + +The search locations can contain placeholders for {application}, +{profile} and {label}. In this way you can segregate the +directories in the path, and choose a strategy that makes sense for +you (e.g. sub-directory per application, or sub-directory per +profile). +If you don’t use placeholders in the search locations, this repository +also appends the {label} parameter of the HTTP resource to a suffix +on the search path, so properties files are loaded from each search +location and a subdirectory with the same name as the label (the +labelled properties take precedence in the Spring Environment). Thus +the default behaviour with no placeholders is the same as adding a +search location ending with /{label}/. For example file:/tmp/config +is the same as file:/tmp/config,file:/tmp/config/{label}. This behavior can be +disabled by setting spring.cloud.config.server.native.addLabelLocations=false. +
+
+Vault Backend +Spring Cloud Config Server also supports Vault as a backend. + +Vault is a tool for securely accessing secrets. A secret is anything +that you want to tightly control access to, such as API keys, passwords, +certificates, and more. Vault provides a unified interface to any secret, +while providing tight access control and recording a detailed audit log. + +For more information on Vault see the Vault quickstart guide. +To enable the config server to use a Vault backend you can run your config server +with the vault profile. For example in your config server’s application.properties +you can add spring.profiles.active=vault. +By default the config server will assume your Vault server is running at +http://127.0.0.1:8200. It also will assume that the name of backend +is secret and the key is application. All of these defaults can be +configured in your config server’s application.properties. Below is a +table of configurable Vault properties. All properties are prefixed with +spring.cloud.config.server.vault. + + + + + + +Name +Default Value + + + + +host +127.0.0.1 + + +port +8200 + + +scheme +http + + +backend +secret + + +defaultKey +application + + +profileSeparator +, + + + + +All configurable properties can be found in +org.springframework.cloud.config.server.environment.VaultEnvironmentRepository. +With your config server running you can make HTTP requests to the server to retrieve +values from the Vault backend. To do this you will need a token for your Vault server. +First place some data in you Vault. For example +$ vault write secret/application foo=bar baz=bam +$ vault write secret/myapp foo=myappsbar +Now make the HTTP request to your config server to retrieve the values. +$ curl -X "GET" "http://localhost:8888/myapp/default" -H "X-Config-Token: yourtoken" +You should see a response similar to this after making the above request. +{ + "name":"myapp", + "profiles":[ + "default" + ], + "label":null, + "version":null, + "state":null, + "propertySources":[ + { + "name":"vault:myapp", + "source":{ + "foo":"myappsbar" + } + }, + { + "name":"vault:application", + "source":{ + "baz":"bam", + "foo":"bar" + } + } + ] +} +
+Multiple Properties Sources +When using Vault you can provide your applications with multiple properties sources. +For example, assume you have written data to the following paths in Vault. +secret/myApp,dev +secret/myApp +secret/application,dev +secret/application +Properties written to secret/application are available to +all applications using the Config Server. An +application with the name myApp would have any properties +written to secret/myApp and secret/application available to it. +When myApp has the dev profile enabled then properties written to +all of the above paths would be available to it, with properties in +the first path in the list taking priority over the others. +
+
+
+Sharing Configuration With All Applications +
+File Based Repositories +With file-based (i.e. git, svn and native) repositories, resources +with file names in application* are shared between all client +applications (so application.properties, application.yml, +application-*.properties etc.). You can use resources with these +file names to configure global defaults and have them overridden by +application-specific files as necessary. +The #_property_overrides[property overrides] feature can also be used +for setting global defaults, and with placeholders applications are +allowed to override them locally. + +With the "native" profile (local file system backend) it is +recommended that you use an explicit search location that isn’t part +of the server’s own configuration. Otherwise the application* +resources in the default search locations are removed because they are +part of the server. + +
+
+Vault Server +When using Vault as a backend you can share configuration with +all applications by placing configuration in +secret/application. For example, if you run this Vault command +$ vault write secret/application foo=bar baz=bam +All applications using the config server will have the properties +foo and baz available to them. +
+
+
+JDBC Backend +Spring Cloud Config Server supports JDBC (relation database) as a +backend for configuration properties. You can enable this feature by +adding spring-jdbc to the classpath, and using the "jdbc" profile, +or by adding a bean of type JdbcEnvironmentRepository. Spring Boot +will configure a data source if you include the right dependencies on +the classpath (see the user guide for more details on that). +The database needs to have a table called "PROPERTIES" with columns +"APPLICATION", "PROFILE", "LABEL" (with the usual Environment +meaning), plus "KEY" and "VALUE" for the key and value pairs in +Properties style. All fields are of type String in Java, so you can +make them VARCHAR of whatever length you need. Property values +behave in the same way as they would if they came from Spring Boot +properties files named {application}-{profile}.properties, including +all the encryption and decryption, which will be applied as +post-processing steps (i.e. not in the repository implementation +directly). +
+
+Composite Environment Repositories +In some scenarios you may wish to pull configuration data from multiple +environment repositories. To do this you can just enable +multiple profiles in your config server’s application properties or YAML file. +If, for example, you want to pull configuration data from a Git repository +as well as a SVN repository you would set the following properties for your +configuration server. +spring: + profiles: + active: git, svn + cloud: + config: + server: + svn: + uri: file:///path/to/svn/repo + order: 2 + git: + uri: file:///path/to/git/repo + order: 1 +In addition to each repo specifying a URI, you can also specify an order property. +The order property allows you to specify the priority order for all your repositories. +The lower the numerical value of the order property the higher priority it will have. +The priority order of a repository will help resolve any potential conflicts between +repositories that contain values for the same properties. + +Any type of failure when retrieving values from an environment repositoy +will result in a failure for the entire composite environment. + + +When using a composite environment it is important that all repos contain +the same label(s). If you have an environment similar to the one above and you request +configuration data with the label master but the SVN +repo does not contain a branch called master the entire request will fail. + +
+Custom Composite Environment Repositories +It is also possible to provide your own EnvironmentRepository bean +to be included as part of a composite environment in addition to +using one of the environment repositories from Spring Cloud. To do this your bean +must implement the EnvironmentRepository interface. If you would like to control +the priority of you custom EnvironmentRepository within the composite +environment you should also implement the Ordered interface and override the +getOrdered method. If you do not implement the Ordered interface then your +EnvironmentRepository will be given the lowest priority. +
+
+
+Property Overrides +The Config Server has an "overrides" feature that allows the operator +to provide configuration properties to all applications that cannot be +accidentally changed by the application using the normal Spring Boot +hooks. To declare overrides just add a map of name-value pairs to +spring.cloud.config.server.overrides. For example +spring: + cloud: + config: + server: + overrides: + foo: bar +will cause all applications that are config clients to read foo=bar +independent of their own configuration. (Of course an application can +use the data in the Config Server in any way it likes, so overrides +are not enforceable, but they do provide useful default behaviour if +they are Spring Cloud Config clients.) + +Normal, Spring environment placeholders with "${}" can be escaped +(and resolved on the client) by using backslash ("\") to escape the +"$" or the "{", e.g. \${app.foo:bar} resolves to "bar" unless the +app provides its own "app.foo". Note that in YAML you don’t need to +escape the backslash itself, but in properties files you do, when you +configure the overrides on the server. + +You can change the priority of all overrides in the client to be more +like default values, allowing applications to supply their own values +in environment variables or System properties, by setting the flag +spring.cloud.config.overrideNone=true (default is false) in the +remote repository. +
+
+
+Health Indicator +Config Server comes with a Health Indicator that checks if the configured +EnvironmentRepository is working. By default it asks the EnvironmentRepository +for an application named app, the default profile and the default +label provided by the EnvironmentRepository implementation. +You can configure the Health Indicator to check more applications +along with custom profiles and custom labels, e.g. +spring: + cloud: + config: + server: + health: + repositories: + myservice: + label: mylabel + myservice-dev: + name: myservice + profiles: development +You can disable the Health Indicator by setting spring.cloud.config.server.health.enabled=false. +
+
+Security +You are free to secure your Config Server in any way that makes sense +to you (from physical network security to OAuth2 bearer +tokens), and Spring Security and Spring Boot make it easy to do pretty +much anything. +To use the default Spring Boot configured HTTP Basic security, just +include Spring Security on the classpath (e.g. through +spring-boot-starter-security). The default is a username of "user" +and a randomly generated password, which isn’t going to be very useful +in practice, so we recommend you configure the password (via +security.user.password) and encrypt it (see below for instructions +on how to do that). +
+
+Encryption and Decryption + +Prerequisites: to use the encryption and decryption features +you need the full-strength JCE installed in your JVM (it’s not there by default). +You can download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" +from Oracle, and follow instructions for installation (essentially replace the 2 policy files +in the JRE lib/security directory with the ones that you downloaded). + +If the remote property sources contain encrypted content (values +starting with {cipher}) they will be decrypted before sending to +clients over HTTP. The main advantage of this set up is that the +property values don’t have to be in plain text when they are "at rest" +(e.g. in a git repository). If a value cannot be decrypted it is +removed from the property source and an additional property is added +with the same key, but prefixed with "invalid." and a value that means +"not applicable" (usually "<n/a>"). This is largely to prevent cipher +text being used as a password and accidentally leaking. +If you are setting up a remote config repository for config client +applications it might contain an application.yml like this, for +instance: + +application.yml + +spring: + datasource: + username: dbuser + password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ' + + +Encrypted values in a .properties file must not be wrapped in quotes, otherwise the value will not be decrypted: + +application.properties + +spring.datasource.username: dbuser +spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ + + +You can safely push this plain text to a shared git repository and the +secret password is protected. +The server also exposes /encrypt and /decrypt endpoints (on the +assumption that these will be secured and only accessed by authorized +agents). If you are editing a remote config file you can use the Config Server +to encrypt values by POSTing to the /encrypt endpoint, e.g. +$ curl localhost:8888/encrypt -d mysecret +682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda + +If the value you are encrypting has characters in it that need to be URL encoded you should use +the --data-urlencode option to curl to make sure they are encoded properly. + + +Be sure not to include any of the curl command statistics in the encrypted value. +Outputting the value to a file can help avoid this problem. + +The inverse operation is also available via /decrypt (provided the server is +configured with a symmetric key or a full key pair): +$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda +mysecret + +If you are testing like this with curl, then use +--data-urlencode (instead of -d) or set an explicit Content-Type: +text/plain to make sure curl encodes the data correctly when there +are special characters ('+' is particularly tricky). + +Take the encrypted value and add the {cipher} prefix before you put +it in the YAML or properties file, and before you commit and push it +to a remote, potentially insecure store. +The /encrypt and /decrypt endpoints also both accept paths of the +form /*/{name}/{profiles} which can be used to control cryptography +per application (name) and profile when clients call into the main +Environment resource. + +to control the cryptography in this granular way you must also +provide a @Bean of type TextEncryptorLocator that creates a +different encryptor per name and profiles. The one that is provided +by default does not do this (so all encryptions use the same key). + +The spring command line client (with Spring Cloud CLI extensions +installed) can also be used to encrypt and decrypt, e.g. +$ spring encrypt mysecret --key foo +682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda +$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda +mysecret +To use a key in a file (e.g. an RSA public key for encryption) prepend +the key value with "@" and provide the file path, e.g. +$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub +AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+... +The key argument is mandatory (despite having a -- prefix). +
+
+Key Management +The Config Server can use a symmetric (shared) key or an asymmetric +one (RSA key pair). The asymmetric choice is superior in terms of +security, but it is often more convenient to use a symmetric key since +it is just a single property value to configure in the bootstrap.properties. +To configure a symmetric key you just need to set encrypt.key to a +secret String (or use an enviroment variable ENCRYPT_KEY to keep it +out of plain text configuration files). +To configure an asymmetric key you can either set the key as a +PEM-encoded text value (in encrypt.key), or via a keystore (e.g. as +created by the keytool utility that comes with the JDK). The +keystore properties are encrypt.keyStore.* with * equal to + + +location (a Resource location), + + +password (to unlock the keystore) and + + +alias (to identify which key in the store is to be +used). + + +The encryption is done with the public key, and a private key is +needed for decryption. Thus in principle you can configure only the +public key in the server if you only want to do encryption (and are +prepared to decrypt the values yourself locally with the private +key). In practice you might not want to do that because it spreads the +key management process around all the clients, instead of +concentrating it in the server. On the other hand it’s a useful option +if your config server really is relatively insecure and only a +handful of clients need the encrypted properties. +
+
+Creating a Key Store for Testing +To create a keystore for testing you can do something like this: +$ keytool -genkeypair -alias mytestkey -keyalg RSA \ + -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \ + -keypass changeme -keystore server.jks -storepass letmein +Put the server.jks file in the classpath (for instance) and then in +your bootstrap.yml for the Config Server: +encrypt: + keyStore: + location: classpath:/server.jks + password: letmein + alias: mytestkey + secret: changeme +
+
+Using Multiple Keys and Key Rotation +In addition to the {cipher} prefix in encrypted property values, the +Config Server looks for {name:value} prefixes (zero or many) before +the start of the (Base64 encoded) cipher text. The keys are passed to +a TextEncryptorLocator which can do whatever logic it needs to +locate a TextEncryptor for the cipher. If you have configured a +keystore (encrypt.keystore.location) the default locator will look +for keys in the store with aliases as supplied by the "key" prefix, +i.e. with a cipher text like this: +foo: + bar: `{cipher}{key:testkey}...` +the locator will look for a key named "testkey". A secret can also be +supplied via a {secret:…​} value in the prefix, but if it is not +the default is to use the keystore password (which is what you get +when you build a keytore and don’t specify a secret). If you do +supply a secret it is recommended that you also encrypt the secrets +using a custom SecretLocator. +Key rotation is hardly ever necessary on cryptographic grounds if the +keys are only being used to encrypt a few bytes of configuration data +(i.e. they are not being used elsewhere), but occasionally you might +need to change the keys if there is a security breach for instance. In +that case all the clients would need to change their source config +files (e.g. in git) and use a new {key:…​} prefix in all the +ciphers, checking beforehand of course that the key alias is available +in the Config Server keystore. + +the {name:value} prefixes can also be added to plaintext posted +to the /encrypt endpoint, if you want to let the Config Server +handle all encryption as well as decryption. + +
+
+Serving Encrypted Properties +Sometimes you want the clients to decrypt the configuration locally, +instead of doing it in the server. In that case you can still have +/encrypt and /decrypt endpoints (if you provide the encrypt.* +configuration to locate a key), but you need to explicitly switch off +the decryption of outgoing properties by placing +spring.cloud.config.server.encrypt.enabled=false in bootstrap.[yml|properties]. +If you don’t care about the endpoints, then it should work if you configure neither the +key nor the enabled flag. +
+
+ +Serving Alternative Formats +The default JSON format from the environment endpoints is perfect for +consumption by Spring applications because it maps directly onto the +Environment abstraction. If you prefer you can consume the same data +as YAML or Java properties by adding a suffix to the resource path +(".yml", ".yaml" or ".properties"). This can be useful for consumption +by applications that do not care about the structure of the JSON +endpoints, or the extra metadata they provide, for example an +application that is not using Spring might benefit from the simplicity +of this approach. +The YAML and properties representations have an additional flag +(provided as a boolean query parameter resolvePlaceholders) to +signal that placeholders in the source documents, in the standard +Spring ${…​} form, should be resolved in the output where possible +before rendering. This is a useful feature for consumers that don’t +know about the Spring placeholder conventions. + +there are limitations in using the YAML or properties formats, +mainly in relation to the loss of metadata. The JSON is structured as +an ordered list of property sources, for example, with names that +correlate with the source. The YAML and properties forms are coalesced +into a single map, even if the origin of the values has multiple +sources, and the names of the original source files are lost. The YAML +representation is not necessarily a faithful representation of the +YAML source in a backing repository either: it is constructed from a +list of flat property sources, and assumptions have to be made about +the form of the keys. + + + +Serving Plain Text +Instead of using the Environment abstraction (or one of the +alternative representations of it in YAML or properties format) your +applications might need generic plain text configuration files, +tailored to their environment. The Config Server provides these +through an additional endpoint at /{name}/{profile}/{label}/{path} +where "name", "profile" and "label" have the same meaning as the +regular environment endpoint, but "path" is a file name +(e.g. log.xml). The source files for this endpoint are located in +the same way as for the environment endpoints: the same search path is +used as for properties or YAML files, but instead of aggregating all +matching resources, only the first one to match is returned. +After a resource is located, placeholders in the normal format +(${…​}) are resolved using the effective Environment for the +application name, profile and label supplied. In this way the resource +endpoint is tightly integrated with the environment +endpoints. Example, if you have this layout for a GIT (or SVN) +repository: +application.yml +nginx.conf +where nginx.conf looks like this: +server { + listen 80; + server_name ${nginx.server.name}; +} +and application.yml like this: +nginx: + server: + name: example.com +--- +spring: + profiles: development +nginx: + server: + name: develop.com +then the /foo/default/master/nginx.conf resource looks like this: +server { + listen 80; + server_name example.com; +} +and /foo/development/master/nginx.conf like this: +server { + listen 80; + server_name develop.com; +} + +Just like the source files for environment configuration, the +"profile" is used to resolve the file name, so if you want a +profile-specific file then /*/development/*/logback.xml will be +resolved by a file called logback-development.xml (in preference +to logback.xml). + + +If you do not want to supply the label and let the server use the default label, you can supply a useDefaultLabel request parameter. So, the above example for the default profile could look like /foo/default/nginx.conf?useDefaultLabel. + + + +Embedding the Config Server +The Config Server runs best as a standalone application, but if you +need to you can embed it in another application. Just use the +@EnableConfigServer annotation. An optional property that can be +useful in this case is spring.cloud.config.server.bootstrap which is +a flag to indicate that the server should configure itself from its +own remote repository. The flag is off by default because it can delay +startup, but when embedded in another application it makes sense to +initialize the same way as any other application. + +It should be obvious, but remember that if you use the bootstrap +flag the config server will need to have its name and repository URI +configured in bootstrap.yml. + +To change the location of the server endpoints you can (optionally) +set spring.cloud.config.server.prefix, e.g. "/config", to serve the +resources under a prefix. The prefix should start but not end with a +"/". It is applied to the @RequestMappings in the Config Server +(i.e. underneath the Spring Boot prefixes server.servletPath and +server.contextPath). +If you want to read the configuration for an application directly from +the backend repository (instead of from the config server) that’s +basically an embedded config server with no endpoints. You can switch +off the endpoints entirely if you don’t use the @EnableConfigServer +annotation (just set spring.cloud.config.server.bootstrap=true). + + +Push Notifications and Spring Cloud Bus +Many source code repository providers (like Github, Gitlab or Bitbucket +for instance) will notify you of changes in a repository through a +webhook. You can configure the webhook via the provider’s user +interface as a URL and a set of events in which you are +interested. For instance +Github +will POST to the webhook with a JSON body containing a list of +commits, and a header "X-Github-Event" equal to "push". If you add a +dependency on the spring-cloud-config-monitor library and activate +the Spring Cloud Bus in your Config Server, then a "/monitor" endpoint +is enabled. +When the webhook is activated the Config Server will send a +RefreshRemoteApplicationEvent targeted at the applications it thinks +might have changed. The change detection can be strategized, but by +default it just looks for changes in files that match the application +name (e.g. "foo.properties" is targeted at the "foo" application, and +"application.properties" is targeted at all applications). The strategy +if you want to override the behaviour is PropertyPathNotificationExtractor +which accepts the request headers and body as parameters and returns a list +of file paths that changed. +The default configuration works out of the box with Github, Gitlab or +Bitbucket. In addition to the JSON notifications from Github, Gitlab +or Bitbucket you can trigger a change notification by POSTing to +"/monitor" with a form-encoded body parameters path={name}. This will +broadcast to applications matching the "{name}" pattern (can contain +wildcards). + +the RefreshRemoteApplicationEvent will only be transmitted if +the spring-cloud-bus is activated in the Config Server and in the +client application. + + +the default configuration also detects filesystem changes in +local git repositories (the webhook is not used in that case but as +soon as you edit a config file a refresh will be broadcast). + + + +Spring Cloud Config Client +A Spring Boot application can take immediate advantage of the Spring +Config Server (or other external property sources provided by the +application developer), and it will also pick up some additional +useful features related to Environment change events. +
+Config First Bootstrap +This is the default behaviour for any application which has the Spring +Cloud Config Client on the classpath. When a config client starts up +it binds to the Config Server (via the bootstrap configuration +property spring.cloud.config.uri) and initializes Spring +Environment with remote property sources. +The net result of this is that all client apps that want to consume +the Config Server need a bootstrap.yml (or an environment variable) +with the server address in spring.cloud.config.uri (defaults to +"http://localhost:8888"). +
+
+Discovery First Bootstrap +If you are using a `DiscoveryClient implementation, such as Spring Cloud Netflix +and Eureka Service Discovery or Spring Cloud Consul (Spring Cloud Zookeeper does +not support this yet), then you can have the Config Server register with the +Discovery Service if you want to, but in the default "Config First" mode, +clients won’t be able to take advantage of the registration. +If you prefer to use DiscoveryClient to locate the Config Server, you can do +that by setting spring.cloud.config.discovery.enabled=true (default +"false"). The net result of that is that client apps all need a +bootstrap.yml (or an environment variable) with the appropriate discovery +configuration. For example, with Spring Cloud Netflix, you need to define the +Eureka server address, e.g. in eureka.client.serviceUrl.defaultZone. The +price for using this option is an extra network round trip on start up to +locate the service registration. The benefit is that the Config Server +can change its co-ordinates, as long as the Discovery Service is a fixed point. The +default service id is "configserver" but you can change that on the +client with spring.cloud.config.discovery.serviceId (and on the server +in the usual way for a service, e.g. by setting spring.application.name). +The discovery client implementations all support some kind of metadata +map (e.g. for Eureka we have eureka.instance.metadataMap). Some +additional properties of the Config Server may need to be configured +in its service registration metadata so that clients can connect +correctly. If the Config Server is secured with HTTP Basic you can +configure the credentials as "username" and "password". And if the +Config Server has a context path you can set "configPath". Example, +for a Config Server that is a Eureka client: + +bootstrap.yml + +eureka: + instance: + ... + metadataMap: + user: osufhalskjrtl + password: lviuhlszvaorhvlo5847 + configPath: /config + + +
+
+Config Client Fail Fast +In some cases, it may be desirable to fail startup of a service if +it cannot connect to the Config Server. If this is the desired +behavior, set the bootstrap configuration property +spring.cloud.config.failFast=true and the client will halt with +an Exception. +
+
+Config Client Retry +If you expect that the config server may occasionally be unavailable when +your app starts, you can ask it to keep trying after a failure. First you need +to set spring.cloud.config.failFast=true, and then 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.config.retry.* configuration properties. + +To take full control of the retry add a @Bean of type +RetryOperationsInterceptor with id "configServerRetryInterceptor". Spring +Retry has a RetryInterceptorBuilder that makes it easy to create one. + +
+
+Locating Remote Configuration Resources +The Config Service serves property sources from /{name}/{profile}/{label}, where the default bindings in the client app are + + +"name" = ${spring.application.name} + + +"profile" = ${spring.profiles.active} (actually Environment.getActiveProfiles()) + + +"label" = "master" + + +All of them can be overridden by setting spring.cloud.config.* +(where * is "name", "profile" or "label"). The "label" is useful for +rolling back to previous versions of configuration; with the default +Config Server implementation it can be a git label, branch name or +commit id. Label can also be provided as a comma-separated list, in +which case the items in the list are tried on-by-one until one succeeds. +This can be useful when working on a feature branch, for instance, +when you might want to align the config label with your branch, but +make it optional (e.g. spring.cloud.config.label=myfeature,develop). +
+
+Security +If you use HTTP Basic security on the server then clients just need to +know the password (and username if it isn’t the default). You can do +that via the config server URI, or via separate username and password +properties, e.g. + +bootstrap.yml + +spring: + cloud: + config: + uri: https://user:secret@myconfig.mycompany.com + + +or + +bootstrap.yml + +spring: + cloud: + config: + uri: https://myconfig.mycompany.com + username: user + password: secret + + +The spring.cloud.config.password and spring.cloud.config.username +values override anything that is provided in the URI. +If you deploy your apps on Cloud Foundry then the best way to provide +the password is through service credentials, e.g. in the URI, since +then it doesn’t even need to be in a config file. An example which +works locally and for a user-provided service on Cloud Foundry named +"configserver": + +bootstrap.yml + +spring: + cloud: + config: + uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888} + + +If you use another form of security you might need to provide a +RestTemplate to the ConfigServicePropertySourceLocator (e.g. by +grabbing it in the bootstrap context and injecting one). +
+Health Indicator +The Config Client supplies a Spring Boot Health Indicator that attempts to load configuration from Config Server. The health indicator can be disabled by setting health.config.enabled=false. The response is also cached for performance reasons. The default cache time to live is 5 minutes. To change that value set the health.config.time-to-live property (in milliseconds). +
+
+Providing A Custom RestTemplate +In some cases you might need to customize the requests made to the config server from +the client. Typically this involves passing special Authorization headers to +authenticate requests to the server. To provide a custom RestTemplate follow the +steps below. + + +Create a new configuration bean with an implementation of PropertySourceLocator. + + + +CustomConfigServiceBootstrapConfiguration.java + +@Configuration +public class CustomConfigServiceBootstrapConfiguration { + @Bean + public ConfigServicePropertySourceLocator configServicePropertySourceLocator() { + ConfigClientProperties clientProperties = configClientProperties(); + ConfigServicePropertySourceLocator configServicePropertySourceLocator = new ConfigServicePropertySourceLocator(clientProperties); + configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties)); + return configServicePropertySourceLocator; + } +} + + + + +In resources/META-INF create a file called +spring.factories and specify your custom configuration. + + + +spring.factories + +org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration + + +
+
+Vault +When using Vault as a backend to your config server the client will need to +supply a token for the server to retrieve values from Vault. This token +can be provided within the client by setting spring.cloud.config.token +in bootstrap.yml. + +bootstrap.yml + +spring: + cloud: + config: + token: YourVaultToken + + +
+
+
+Vault +
+Nested Keys In Vault +Vault supports the ability to nest keys in a value stored in Vault. For example +echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp - +This command will write a JSON object to your Vault. To access these values in Spring +you would use the traditional dot(.) annotation. For example +@Value("${appA.secret}") +String name = "World"; +The above code would set the name variable to appAsecret. +
+
+
+
\ No newline at end of file