Added bats and tests for gh-pages

This commit is contained in:
Marcin Grzejszczak
2019-03-28 18:58:57 +01:00
parent f8427d402b
commit 6cf9ed86ea
1184 changed files with 49494 additions and 316 deletions

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "docs/src/test/bats/test_helper/bats-assert"]
path = docs/src/test/bats/test_helper/bats-assert
url = https://github.com/ztombol/bats-assert
[submodule "docs/src/test/bats/test_helper/bats-support"]
path = docs/src/test/bats/test_helper/bats-support
url = https://github.com/ztombol/bats-support

View File

@@ -29,6 +29,22 @@
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<executions>
<execution><!-- Run our version calculation script -->
<id>Run tests</id>
<phase>test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${basedir}/src/test/bash/run-bats.sh</executable>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>

View File

@@ -1,15 +1,20 @@
#!/bin/bash -x
#!/bin/bash
# Usage: (cd <project root>; ghpages.sh -v <version> -b -c)
set -e
export GIT_BIN ROOT_FOLDER COMMIT_CHANGES MAVEN_PATH MAVEN_EXEC REPO_NAME SPRING_CLOUD_STATIC_REPO
export CURRENT_BRANCH PREVIOUS_BRANCH
GIT_BIN="${GIT_BIN:-git}"
# The script should be executed from the root folder
ROOT_FOLDER="$( pwd )"
echo "Current folder is ${ROOT_FOLDER}"
# 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
@@ -24,8 +29,8 @@ function set_default_props() {
MAVEN_EXEC="${MAVEN_PATH}mvn"
fi
echo "Path to Maven is [${MAVEN_EXEC}]"
if [ -z $REPO_NAME ]; then
REPO_NAME=$(git remote -v | grep origin | head -1 | sed -e 's!.*/!!' -e 's/ .*//' -e 's/\.git.*//')
if [ -z "${REPO_NAME}" ]; then
REPO_NAME="$("${GIT_BIN}" remote -v | grep origin | head -1 | sed -e 's!.*/!!' -e 's/ .*//' -e 's/\.git.*//')"
fi
echo "Repo name is [${REPO_NAME}]"
SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git}
@@ -34,22 +39,23 @@ function set_default_props() {
# Adds the oauth token if present to the remote url
function add_oauth_token_to_remote_url() {
remote=`git config remote.origin.url | sed -e 's/^git:/https:/'`
local remote
remote="$( "${GIT_BIN}" config remote.origin.url | sed -e 's/^git:/https:/' )"
echo "Current remote [${remote}]"
if [[ "${RELEASER_GIT_OAUTH_TOKEN}" != "" && ${remote} != *"@"* ]]; then
echo "OAuth token found. Will reuse it to push the code"
withToken=${remote/https:\/\//https://${RELEASER_GIT_OAUTH_TOKEN}@}
git remote set-url --push origin "${withToken}"
"${GIT_BIN}" remote set-url --push origin "${withToken}"
else
echo "No OAuth token found"
git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
"${GIT_BIN}" remote set-url --push origin "$( "${GIT_BIN}" config remote.origin.url | sed -e 's/^git:/https:/' )"
fi
}
# Check if gh-pages exists and docs have been built
function check_if_anything_to_sync() {
add_oauth_token_to_remote_url
if ! (git remote set-branches --add origin gh-pages && git fetch -q) && [[ "${RELEASE_TRAIN}" != "yes" ]] ; then
if ! ("${GIT_BIN}" remote set-branches --add origin gh-pages && "${GIT_BIN}" fetch -q) && [[ "${RELEASE_TRAIN}" != "yes" ]] ; then
echo "No gh-pages, so not syncing"
exit 0
fi
@@ -66,19 +72,20 @@ function retrieve_current_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=$("${GIT_BIN}" 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"
PREVIOUS_BRANCH=${CURRENT_BRANCH}
"${GIT_BIN}" checkout "${CURRENT_BRANCH}" || echo "Failed to check the branch... continuing with the script"
PREVIOUS_BRANCH="${CURRENT_BRANCH}"
echo "Previous branch was [${PREVIOUS_BRANCH}]"
}
# Switches to the provided value of the release version. We always prefix it with `v`
function switch_to_tag() {
if [[ "${RELEASE_TRAIN}" != "yes" ]] ; then
git checkout v${VERSION}
"${GIT_BIN}" checkout v"${VERSION}"
fi
}
@@ -91,6 +98,7 @@ function build_docs_if_applicable() {
# Get the name of the `docs.main` property
# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile
# shellcheck disable=SC2016
function retrieve_doc_properties() {
MAIN_ADOC_VALUE=$("${MAVEN_EXEC}" -q \
-Dexec.executable="echo" \
@@ -113,47 +121,52 @@ function retrieve_doc_properties() {
# 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
local success="false"
"${GIT_BIN}" diff-index --quiet HEAD && dirty=$? && success="true"
if [[ "${success}" == "false" ]]; then
echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1"
fi
echo "The repo is dirty [${dirty}]"
if [ "$dirty" != "0" ]; then "${GIT_BIN}" 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}
DESTINATION_REPO_FOLDER="${ROOT_FOLDER}"
elif [[ "${CLONE}" == "yes" ]]; then
mkdir -p ${ROOT_FOLDER}/target
local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static
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} && cd ${clonedStatic} && git checkout gh-pages
"${GIT_BIN}" clone "${SPRING_CLOUD_STATIC_REPO}" "${clonedStatic}" && cd "${clonedStatic}" && "${GIT_BIN}" checkout gh-pages
else
echo "Spring Cloud Static already cloned - will pull changes"
cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages
cd "${clonedStatic}" && "${GIT_BIN}" checkout gh-pages && "${GIT_BIN}" pull origin gh-pages
fi
if [[ -z "${RELEASE_TRAIN}" ]] ; then
DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME}
DESTINATION_REPO_FOLDER="${clonedStatic}/${REPO_NAME}"
else
DESTINATION_REPO_FOLDER=${clonedStatic}
DESTINATION_REPO_FOLDER="${clonedStatic}"
fi
mkdir -p ${DESTINATION_REPO_FOLDER}
mkdir -p "${DESTINATION_REPO_FOLDER}"
else
if [[ ! -e "${DESTINATION}/.git" ]]; then
echo "[${DESTINATION}] is not a git repository"
exit 1
fi
if [[ -z "${RELEASE_TRAIN}" ]] ; then
DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME}
DESTINATION_REPO_FOLDER="${DESTINATION}/${REPO_NAME}"
else
DESTINATION_REPO_FOLDER=${DESTINATION}
DESTINATION_REPO_FOLDER="${DESTINATION}"
fi
mkdir -p ${DESTINATION_REPO_FOLDER}
mkdir -p "${DESTINATION_REPO_FOLDER}"
echo "Destination was provided [${DESTINATION}]"
fi
cd ${DESTINATION_REPO_FOLDER}
git checkout gh-pages
git pull origin gh-pages
cd "${DESTINATION_REPO_FOLDER}"
"${GIT_BIN}" checkout gh-pages
"${GIT_BIN}" pull origin gh-pages
# Add git branches
###################################################################
@@ -172,32 +185,33 @@ function copy_docs_for_current_version() {
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
if ! "${GIT_BIN}" ls-files -i -o --exclude-standard --directory | grep -q ^"${file}"$; then
# Not ignored...
cp -rf $f ${ROOT_FOLDER}/
cp -rf "${f}" "${ROOT_FOLDER}"/
fi
done
git add -A ${ROOT_FOLDER}
"${GIT_BIN}" add -A "${ROOT_FOLDER}"
COMMIT_CHANGES="yes"
else
echo -e "Current branch is [${CURRENT_BRANCH}]"
# https://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}
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
file="${f#docs/target/generated-docs/*}"
if ! "${GIT_BIN}" ls-files -i -o --exclude-standard --directory | grep -q ^"${file}"$; then
echo "The file [${file}] shouldn't be ignored"
# 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
cp -rf "${f}" "${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html"
"${GIT_BIN}" add -A "${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html"
else
cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}
git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file || echo "Failed to add the file [$file]"
cp -rf "${f}" "${ROOT_FOLDER}/${CURRENT_BRANCH}"
"${GIT_BIN}" add -A "${ROOT_FOLDER}/${CURRENT_BRANCH}/${file}" || echo "Failed to add the file [${file}]"
fi
fi
done
@@ -211,12 +225,12 @@ function copy_docs_for_current_version() {
# Copies the docs by using the explicitly provided version
function copy_docs_for_provided_version() {
local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION}
mkdir -p ${FOLDER}
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}
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}"
@@ -227,26 +241,27 @@ function copy_docs_for_provided_version() {
# $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
local file="$1"
local destination="$2"
echo "Copying file [${file}] to destination [${destination}]"
if ! "${GIT_BIN}" 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
cp -rf "${f}" "${destination}"/index.html
else
cp -rf $f ${destination}
cp -rf "${f}" "${destination}"
fi
git add -A ${destination}
"${GIT_BIN}" add -A "${destination}"
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"
"${GIT_BIN}" 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.
@@ -254,7 +269,7 @@ function commit_changes_if_applicable() {
###################################################################
if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then
add_oauth_token_to_remote_url
git push origin gh-pages
"${GIT_BIN}" push origin gh-pages
fi
fi
}
@@ -262,10 +277,10 @@ function commit_changes_if_applicable() {
# 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 ${PREVIOUS_BRANCH} || echo "Failed to check the branch... continuing with the script"
if [ "$dirty" != "0" ]; then git stash pop; fi
exit 0
cd "${ROOT_FOLDER}"
"${GIT_BIN}" checkout "${PREVIOUS_BRANCH}" || echo "Failed to check the branch... continuing with the script"
if [ "$dirty" != "0" ]; then "${GIT_BIN}" stash pop; fi
return 0
}
# Assert if properties have been properly passed
@@ -322,53 +337,58 @@ EOF
#
# ==========================================
while [[ $# > 0 ]]
do
key="$1"
case ${key} in
-v|--version)
VERSION="$2"
shift # past argument
;;
-r|--releasetrain)
RELEASE_TRAIN="yes"
;;
-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
retrieve_current_branch
if echo $VERSION | egrep -q 'SNAPSHOT' || [[ -z "${VERSION}" ]]; then
CLONE=""
VERSION=""
echo "You've provided a version variable but it's a snapshot one. Due to this will not clone spring-cloud-static and publish docs over there"
if [[ "${SOURCE_FUNCTIONS}" == "true" ]]; then
echo "Will just source functions. Will not run any commands"
else
switch_to_tag
while [[ $# -gt 0 ]]
do
key="$1"
case "${key}" in
-v|--version)
VERSION="$2"
shift # past argument
;;
-r|--releasetrain)
RELEASE_TRAIN="yes"
;;
-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
retrieve_current_branch
if echo "${VERSION}" | grep -q -E 'SNAPSHOT' || [[ -z "${VERSION}" ]]; then
CLONE=""
VERSION=""
echo "You've provided a version variable but it's a snapshot one. Due to this will not clone spring-cloud-static and publish docs over there"
else
switch_to_tag
fi
build_docs_if_applicable
retrieve_doc_properties
stash_changes
add_docs_from_target
checkout_previous_branch
fi
build_docs_if_applicable
retrieve_doc_properties
stash_changes
add_docs_from_target
checkout_previous_branch

View File

@@ -1,211 +0,0 @@
#!/bin/bash
set -e
# Either clones or pulls the repo for given project
# Params:
# $1 organization e.g. spring-cloud
# $2 repo name e.g. spring-cloud-sleuth
function clone_or_pull() {
if [ "$#" -ne 2 ]
then
echo "You haven't provided 2 args... \$1 organization e.g. spring-cloud; \$2 repo name e.g. spring-cloud-sleuth"
exit 1
fi
if [[ "${JUST_PUSH}" == "yes" ]] ; then
echo "Skipping cloning since the option to just push was provided"
exit 0
fi
local ORGANIZATION=$1
local REPO_NAME=$2
local LOCALREPO_VC_DIR=${REPO_NAME}/.git
if [ ! -d ${LOCALREPO_VC_DIR} ]
then
echo "Repo [${REPO_NAME}] doesn't exist - will clone it!"
git clone git@github.com:${ORGANIZATION}/${REPO_NAME}.git
else
echo "Repo [${REPO_NAME}] exists - will pull the changes"
cd ${REPO_NAME} && git pull || echo "Not pulling since repo is up to date"
cd ${ROOT_FOLDER}
fi
}
# For the given branch updates the docs/src/main/asciidoc/ghpages.sh
# with the one from spring-cloud-build. Then commits and pushes the change
# Params:
# $1 repo name e.g. spring-cloud-sleuth
# $2 branch name
function update_ghpages_script() {
if [ "$#" -ne 2 ]
then
echo "You haven't provided 2 args... \$1 repo name e.g. spring-cloud-sleuth; \$2 branch name e.g. master"
exit 1
fi
local REPO_NAME=$1
local BRANCH_NAME=$2
echo "Updating ghpages script for [${REPO_NAME}] and branch [${BRANCH_NAME}]"
cd ${REPO_NAME}
echo "Checking out [${BRANCH_NAME}]"
git checkout ${BRANCH_NAME}
echo "Resetting the repo and pulling before commiting"
git reset --hard origin/${BRANCH_NAME} && git pull origin ${BRANCH_NAME}
# If the user wants to just push we will not copy / add / commit files
if [[ "${JUST_PUSH}" != "yes" ]] ; then
echo "Copying [${GHPAGES_DOWNLOAD_PATH}] to [${GHPAGES_IN_REPO_PATH}]"
cp -rf ${GHPAGES_DOWNLOAD_PATH} ${GHPAGES_IN_REPO_PATH}
echo "Adding and committing [${GHPAGES_IN_REPO_PATH}] with message [${COMMIT_MESSAGE}]"
git add ${GHPAGES_IN_REPO_PATH}
git commit -m "${COMMIT_MESSAGE}" || echo "Proceeding to the next repo"
fi
if [[ "${AUTO_PUSH}" == "yes" ]] ; then
echo "Pushing the branch [${BRANCH_NAME}]"
wait_if_manual_proceed
git push origin ${BRANCH_NAME}
fi
cd ${ROOT_FOLDER}
}
# Downloads ghpages.sh
function download_ghpages() {
rm -rf ${GHPAGES_DOWNLOAD_PATH}
echo "Downloading ghpages.sh from [${GHPAGES_URL}] to [${GHPAGES_DOWNLOAD_PATH}]"
curl ${GHPAGES_URL} -o ${GHPAGES_DOWNLOAD_PATH}
chmod +x ${GHPAGES_DOWNLOAD_PATH}
}
# Either clones or pulls the repo for given project and then updates gh-pages for the given project
# Params:
# $1 organization e.g. spring-cloud
# $2 repo name e.g. spring-cloud-sleuth
# $3 branch name e.g. master
function clone_and_update_ghpages() {
if [ "$#" -ne 3 ]
then
echo "You haven't provided 3 args... \$1 organization e.g. spring-cloud; \$2 repo name e.g. spring-cloud-sleuth; \$3 branch name e.g. master"
exit 1
fi
local ORGANIZATION=$1
local REPO_NAME=$2
local BRANCH_NAME=$3
local VAR
echo -e "\n\nWill clone the repo and update scripts for org [${ORGANIZATION}], repo [${REPO_NAME}] and branch [${BRANCH_NAME}]\n\n"
clone_or_pull ${ORGANIZATION} ${REPO_NAME}
update_ghpages_script ${REPO_NAME} ${BRANCH_NAME}
echo "Proceeding to next project"
wait_if_manual_proceed
}
function wait_if_manual_proceed() {
if [[ "${AUTO_PROCEED}" != "yes" ]] ; then
echo -n "Press [ENTER] to continue..."
read VAR
fi
}
# Prints the provided parameters
function print_parameters() {
cat <<EOF
Running the script with the following parameters
GHPAGES_URL=${GHPAGES_URL}
GHPAGES_DOWNLOAD_PATH=${GHPAGES_DOWNLOAD_PATH}
COMMIT_MESSAGE=${COMMIT_MESSAGE}
GHPAGES_IN_REPO_PATH=${GHPAGES_IN_REPO_PATH}
AUTO_PROCEED=${AUTO_PROCEED}
AUTO_PUSH=${AUTO_PUSH}
JUST_PUSH=${JUST_PUSH}
ROOT_FOLDER=${ROOT_FOLDER}
EOF
}
# Prints the usage
function print_usage() {
cat <<EOF
The idea of this script is to batch update all ghpages scripts for all projects that we have in Spring Cloud.
If you don't provide any options by default the script will copy the latest ghpages.sh, commit it for each repo
and then push it to the appropriate branch.
USAGE:
You can use the following options:
-p|--nopush - the script will not push the changes
-m|--manualproceed - if you want to do a manual proceed after every step
-x|--justpush - if you want to go to every single repo and just push the changes
-h|--help - present this help message
EOF
}
# ==========================================
# ____ ____ _____ _____ _____ _______
# / ____|/ ____| __ \|_ _| __ \__ __|
# | (___ | | | |__) | | | | |__) | | |
# \___ \| | | _ / | | | ___/ | |
# ____) | |____| | \ \ _| |_| | | |
# |_____/ \_____|_| \_\_____|_| |_|
#
# ==========================================
while [[ $# > 0 ]]
do
key="$1"
case ${key} in
-p|--nopush)
AUTO_PUSH="no"
;;
-m|--manualproceed)
AUTO_PROCEED="no"
;;
-x|--justpush)
JUST_PUSH="yes"
;;
-h|--help)
print_usage
exit 0
;;
*)
echo "Invalid option: [$1]"
print_usage
exit 1
;;
esac
shift # past argument or value
done
export GHPAGES_URL=${GHPAGES_URL:-https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/ghpages.sh}
export GHPAGES_DOWNLOAD_PATH=${GHPAGES_DOWNLOAD_PATH:-/tmp/ghpages.sh}
export COMMIT_MESSAGE=${COMMIT_MESSAGE:-Updating ghpages for all projects}
export GHPAGES_IN_REPO_PATH=${GHPAGES_IN_REPO_PATH:-docs/src/main/asciidoc/ghpages.sh}
export AUTO_PROCEED=${AUTO_PROCEED:-yes}
export AUTO_PUSH=${AUTO_PUSH:-yes}
export JUST_PUSH=${JUST_PUSH:-no}
export ROOT_FOLDER=`pwd`
print_parameters
download_ghpages
clone_and_update_ghpages spring-cloud spring-cloud-aws master
clone_and_update_ghpages spring-cloud spring-cloud-aws 1.0.x
clone_and_update_ghpages spring-cloud spring-cloud-aws 1.2.x
clone_and_update_ghpages spring-cloud spring-cloud-bus master
clone_and_update_ghpages spring-cloud spring-cloud-cli 1.0.x
clone_and_update_ghpages spring-cloud spring-cloud-cli 1.1.x
clone_and_update_ghpages spring-cloud spring-cloud-cli master
clone_and_update_ghpages spring-cloud spring-cloud-cloudfoundry master
clone_and_update_ghpages spring-cloud spring-cloud-cluster master
clone_and_update_ghpages spring-cloud spring-cloud-commons master
clone_and_update_ghpages spring-cloud spring-cloud-config master
clone_and_update_ghpages spring-cloud spring-cloud-config 1.1.x
clone_and_update_ghpages spring-cloud spring-cloud-consul 1.0.x
clone_and_update_ghpages spring-cloud spring-cloud-consul master
clone_and_update_ghpages spring-cloud spring-cloud-contract master
clone_and_update_ghpages spring-cloud spring-cloud-netflix 1.0.x
clone_and_update_ghpages spring-cloud spring-cloud-netflix 1.1.x
clone_and_update_ghpages spring-cloud spring-cloud-netflix master
clone_and_update_ghpages spring-cloud spring-cloud-security master
clone_and_update_ghpages spring-cloud spring-cloud-sleuth 1.0.x
clone_and_update_ghpages spring-cloud spring-cloud-sleuth master
clone_and_update_ghpages spring-cloud spring-cloud-starters Brixton
clone_and_update_ghpages spring-cloud spring-cloud-starters master
clone_and_update_ghpages spring-cloud-incubator spring-cloud-vault-config master
clone_and_update_ghpages spring-cloud spring-cloud-zookeeper master

View File

@@ -0,0 +1,81 @@
#!/bin/bash
[[ -z $DEBUG ]] || set -o xtrace
set -o errexit
set -o errtrace
set -o nounset
set -o pipefail
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ROOT_DIR="${ROOT_DIR}/../../.."
function usage {
echo "usage: $0: <download-shellcheck|run-shellcheck|download-bats|run-bats|initialize-submodules>"
exit 1
}
if [[ $# -ne 1 ]]; then
usage
fi
SHELLCHECK_VERSION="v0.4.6"
SHELLCHECK_BIN="${ROOT_DIR}/../target/shellcheck-${SHELLCHECK_VERSION}/shellcheck"
case $1 in
download-shellcheck)
if [[ "${OSTYPE}" == linux* && ! -z "${SHELLCHECK_BIN}" ]]; then
SHELLCHECK_ARCHIVE="shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz"
SHELLCHECK_ARCHIVE_SHA512SUM="d9ac3e4fb2383b2d6862415e8052459ce24fd5402806b9ce739990d5c1cccebe4121288df29de32dcef5daa115874ddf7f9730de256bf134ee11cd9704aaa64c"
if [[ -x "${ROOT_DIR}/../target/shellcheck-${SHELLCHECK_VERSION}/shellcheck" ]]; then
echo "shellcheck already downloaded - skipping..."
exit 0
fi
wget -P "${ROOT_DIR}/../target/" \
"https://storage.googleapis.com/shellcheck/${SHELLCHECK_ARCHIVE}"
pushd "${ROOT_DIR}/../target/"
echo "${SHELLCHECK_ARCHIVE_SHA512SUM} ${SHELLCHECK_ARCHIVE}" | sha512sum -c -
tar xvf "${SHELLCHECK_ARCHIVE}"
rm -vf -- "${SHELLCHECK_ARCHIVE}"
popd
else
echo "It seems that automatic installation is not supported on your platform."
echo "Please install shellcheck manually:"
echo " https://github.com/koalaman/shellcheck#installing"
exit 1
fi
;;
run-shellcheck)
echo "Running shellcheck"
"${SHELLCHECK_BIN}" "${ROOT_DIR}"/src/main/asciidoc/*.sh
echo "Shellcheck passed sucesfully!"
;;
download-bats)
if [[ -x "${ROOT_DIR}/../target/bats/bin/bats" ]]; then
echo "bats already downloaded - skipping..."
exit 0
fi
git clone https://github.com/bats-core/bats-core.git "${ROOT_DIR}/../target/bats"
;;
run-bats)
echo "Running bats"
SHELLCHECK_BIN="${ROOT_DIR}/../target/bats/bin/bats"
"${SHELLCHECK_BIN}" "${ROOT_DIR}"/src/test/bats
echo "Bats passed sucesfully!"
;;
initialize-submodules)
files="$( ls "${ROOT_DIR}/src/test/bats/test_helper/bats-assert/" || echo "" )"
if [ ! -z "${files}" ]; then
echo "Submodules already initialized";
git submodule foreach git pull origin master || echo "Failed to pull - continuing the script"
else
echo "Initilizing submodules"
git submodule init
git submodule update
git submodule foreach git pull origin master || echo "Failed to pull - continuing the script"
fi
;;
*)
usage
;;
esac

16
docs/src/test/bash/run-bats.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
[[ -z $DEBUG ]] || set -o xtrace
set -o errexit
set -o errtrace
set -o nounset
set -o pipefail
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
"${ROOT_DIR}"/build-helper.sh "initialize-submodules"
"${ROOT_DIR}"/build-helper.sh "download-shellcheck"
"${ROOT_DIR}"/build-helper.sh "run-shellcheck"
"${ROOT_DIR}"/build-helper.sh "download-bats"
"${ROOT_DIR}"/build-helper.sh "run-bats"

View File

@@ -0,0 +1 @@
Foo

View File

@@ -0,0 +1 @@
ref: refs/heads/master

View File

@@ -0,0 +1,11 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = file://.
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master

View File

@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@@ -0,0 +1,15 @@
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit. The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".
. git-sh-setup
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
:

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".
# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
# This example catches duplicate Signed-off-by lines.
test "" = "$(grep '^Signed-off-by: ' "$1" |
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
echo >&2 Duplicate Signed-off-by lines.
exit 1
}

View File

@@ -0,0 +1,114 @@
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open2;
# An example hook script to integrate Watchman
# (https://facebook.github.io/watchman/) with git to speed up detecting
# new and modified files.
#
# The hook is passed a version (currently 1) and a time in nanoseconds
# formatted as a string and outputs to stdout all files that have been
# modified since the given time. Paths must be relative to the root of
# the working tree and separated by a single NUL.
#
# To enable this hook, rename this file to "query-watchman" and set
# 'git config core.fsmonitor .git/hooks/query-watchman'
#
my ($version, $time) = @ARGV;
# Check the hook interface version
if ($version == 1) {
# convert nanoseconds to seconds
$time = int $time / 1000000000;
} else {
die "Unsupported query-fsmonitor hook version '$version'.\n" .
"Falling back to scanning...\n";
}
my $git_work_tree;
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
$git_work_tree = Win32::GetCwd();
$git_work_tree =~ tr/\\/\//;
} else {
require Cwd;
$git_work_tree = Cwd::cwd();
}
my $retry = 1;
launch_watchman();
sub launch_watchman {
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
or die "open2() failed: $!\n" .
"Falling back to scanning...\n";
# In the query expression below we're asking for names of files that
# changed since $time but were not transient (ie created after
# $time but no longer exist).
#
# To accomplish this, we're using the "since" generator to use the
# recency index to select candidate nodes and "fields" to limit the
# output to file names only. Then we're using the "expression" term to
# further constrain the results.
#
# The category of transient files that we want to ignore will have a
# creation clock (cclock) newer than $time_t value and will also not
# currently exist.
my $query = <<" END";
["query", "$git_work_tree", {
"since": $time,
"fields": ["name"],
"expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]]
}]
END
print CHLD_IN $query;
close CHLD_IN;
my $response = do {local $/; <CHLD_OUT>};
die "Watchman: command returned no output.\n" .
"Falling back to scanning...\n" if $response eq "";
die "Watchman: command returned invalid output: $response\n" .
"Falling back to scanning...\n" unless $response =~ /^\{/;
my $json_pkg;
eval {
require JSON::XS;
$json_pkg = "JSON::XS";
1;
} or do {
require JSON::PP;
$json_pkg = "JSON::PP";
};
my $o = $json_pkg->new->utf8->decode($response);
if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {
print STDERR "Adding '$git_work_tree' to watchman's watch list.\n";
$retry--;
qx/watchman watch "$git_work_tree"/;
die "Failed to make watchman watch '$git_work_tree'.\n" .
"Falling back to scanning...\n" if $? != 0;
# Watchman will always return all files on the first query so
# return the fast "everything is dirty" flag to git and do the
# Watchman query just to get it over with now so we won't pay
# the cost in git to look up each individual file.
print "/\0";
eval { launch_watchman() };
exit 0;
}
die "Watchman: $o->{error}.\n" .
"Falling back to scanning...\n" if $o->{error};
binmode STDOUT, ":utf8";
local $, = "\0";
print @{$o->{files}};
}

View File

@@ -0,0 +1,8 @@
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".
exec git update-server-info

View File

@@ -0,0 +1,14 @@
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".
. git-sh-setup
precommit="$(git rev-parse --git-path hooks/pre-commit)"
test -x "$precommit" && exec "$precommit" ${1+"$@"}
:

View File

@@ -0,0 +1,49 @@
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=$(git hash-object -t tree /dev/null)
fi
# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)
# Redirect output to stderr.
exec 1>&2
# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
# Note that the use of brackets around a tr range is ok here, (it's
# even required, for portability to Solaris 10's /usr/bin/tr), since
# the square bracket bytes happen to fall in the designated range.
test $(git diff --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
cat <<\EOF
Error: Attempt to add a non-ASCII file name.
This can cause problems if you want to work with people on other platforms.
To be portable it is advisable to rename the file.
If you know what you are doing you can disable this check using:
git config hooks.allownonascii true
EOF
exit 1
fi
# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

View File

@@ -0,0 +1,53 @@
#!/bin/sh
# An example hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).
remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_sha" = $z40 ]
then
# Handle delete
:
else
if [ "$remote_sha" = $z40 ]
then
# New branch, examine all commits
range="$local_sha"
else
# Update to existing branch, examine new commits
range="$remote_sha..$local_sha"
fi
# Check for WIP commit
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
if [ -n "$commit" ]
then
echo >&2 "Found WIP commit in $local_ref, not pushing"
exit 1
fi
fi
done
exit 0

View File

@@ -0,0 +1,169 @@
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.
publish=next
basebranch="$1"
if test "$#" = 2
then
topic="refs/heads/$2"
else
topic=`git symbolic-ref HEAD` ||
exit 0 ;# we do not interrupt rebasing detached HEAD
fi
case "$topic" in
refs/heads/??/*)
;;
*)
exit 0 ;# we do not interrupt others.
;;
esac
# Now we are dealing with a topic branch being rebased
# on top of master. Is it OK to rebase it?
# Does the topic really exist?
git show-ref -q "$topic" || {
echo >&2 "No such branch $topic"
exit 1
}
# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
echo >&2 "$topic is fully merged to master; better remove it."
exit 1 ;# we could allow it, but there is no point.
fi
# Is topic ever merged to next? If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
not_in_topic=`git rev-list "^$topic" master`
if test -z "$not_in_topic"
then
echo >&2 "$topic is already up to date with master"
exit 1 ;# we could allow it, but there is no point.
else
exit 0
fi
else
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
/usr/bin/perl -e '
my $topic = $ARGV[0];
my $msg = "* $topic has commits already merged to public branch:\n";
my (%not_in_next) = map {
/^([0-9a-f]+) /;
($1 => 1);
} split(/\n/, $ARGV[1]);
for my $elem (map {
/^([0-9a-f]+) (.*)$/;
[$1 => $2];
} split(/\n/, $ARGV[2])) {
if (!exists $not_in_next{$elem->[0]}) {
if ($msg) {
print STDERR $msg;
undef $msg;
}
print STDERR " $elem->[1]\n";
}
}
' "$topic" "$not_in_next" "$not_in_master"
exit 1
fi
<<\DOC_END
This sample hook safeguards topic branches that have been
published from being rewound.
The workflow assumed here is:
* Once a topic branch forks from "master", "master" is never
merged into it again (either directly or indirectly).
* Once a topic branch is fully cooked and merged into "master",
it is deleted. If you need to build on top of it to correct
earlier mistakes, a new topic branch is created by forking at
the tip of the "master". This is not strictly necessary, but
it makes it easier to keep your history simple.
* Whenever you need to test or publish your changes to topic
branches, merge them into "next" branch.
The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.
With this workflow, you would want to know:
(1) ... if a topic branch has ever been merged to "next". Young
topic branches can have stupid mistakes you would rather
clean up before publishing, and things that have not been
merged into other branches can be easily rebased without
affecting other people. But once it is published, you would
not want to rewind it.
(2) ... if a topic branch has been fully merged to "master".
Then you can delete it. More importantly, you should not
build on top of it -- other people may already want to
change things related to the topic as patches against your
"master", so if you need further changes, it is better to
fork the topic (perhaps with the same name) afresh from the
tip of "master".
Let's look at this example:
o---o---o---o---o---o---o---o---o---o "next"
/ / / /
/ a---a---b A / /
/ / / /
/ / c---c---c---c B /
/ / / \ /
/ / / b---b C \ /
/ / / / \ /
---o---o---o---o---o---o---o---o---o---o---o "master"
A, B and C are topic branches.
* A has one fix since it was merged up to "next".
* B has finished. It has been fully merged up to "master" and "next",
and is ready to be deleted.
* C has not merged to "next" at all.
We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.
To compute (1):
git rev-list ^master ^topic next
git rev-list ^master next
if these match, topic has not merged in next at all.
To compute (2):
git rev-list master..topic
if this is empty, it is fully merged to "master".
DOC_END

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#
# An example hook script to make use of push options.
# The example simply echoes all push options that start with 'echoback='
# and rejects all pushes when the "reject" push option is used.
#
# To enable this hook, rename this file to "pre-receive".
if test -n "$GIT_PUSH_OPTION_COUNT"
then
i=0
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
do
eval "value=\$GIT_PUSH_OPTION_$i"
case "$value" in
echoback=*)
echo "echo from the pre-receive-hook: ${value#*=}" >&2
;;
reject)
exit 1
esac
i=$((i + 1))
done
fi

View File

@@ -0,0 +1,42 @@
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source. The hook's purpose is to edit the commit
# message file. If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".
# This hook includes three examples. The first one removes the
# "# Please enter the commit message..." help message.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output. It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited. This is rarely a good idea.
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
# case "$COMMIT_SOURCE,$SHA1" in
# ,|template,)
# /usr/bin/perl -i.bak -pe '
# print "\n" . `git diff --cached --name-status -r`
# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
# *) ;;
# esac
# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
# if test -z "$COMMIT_SOURCE"
# then
# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
# fi

View File

@@ -0,0 +1,128 @@
#!/bin/sh
#
# An example hook script to block unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
# This boolean sets whether unannotated tags will be allowed into the
# repository. By default they won't be.
# hooks.allowdeletetag
# This boolean sets whether deleting tags will be allowed in the
# repository. By default they won't be.
# hooks.allowmodifytag
# This boolean sets whether a tag may be modified after creation. By default
# it won't be.
# hooks.allowdeletebranch
# This boolean sets whether deleting branches will be allowed in the
# repository. By default they won't be.
# hooks.denycreatebranch
# This boolean sets whether remotely creating branches will be denied
# in the repository. By default this is allowed.
#
# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"
# --- Safety check
if [ -z "$GIT_DIR" ]; then
echo "Don't run this script from the command line." >&2
echo " (if you want, you could supply GIT_DIR then run" >&2
echo " $0 <ref> <oldrev> <newrev>)" >&2
exit 1
fi
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
exit 1
fi
# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)
# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
echo "*** Project description file hasn't been set" >&2
exit 1
;;
esac
# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
newrev_type=delete
else
newrev_type=$(git cat-file -t $newrev)
fi
case "$refname","$newrev_type" in
refs/tags/*,commit)
# un-annotated tag
short_refname=${refname##refs/tags/}
if [ "$allowunannotated" != "true" ]; then
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
exit 1
fi
;;
refs/tags/*,delete)
# delete tag
if [ "$allowdeletetag" != "true" ]; then
echo "*** Deleting a tag is not allowed in this repository" >&2
exit 1
fi
;;
refs/tags/*,tag)
# annotated tag
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
then
echo "*** Tag '$refname' already exists." >&2
echo "*** Modifying a tag is not allowed in this repository." >&2
exit 1
fi
;;
refs/heads/*,commit)
# branch
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
echo "*** Creating a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/heads/*,delete)
# delete branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/remotes/*,commit)
# tracking branch
;;
refs/remotes/*,delete)
# delete tracking branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
exit 1
fi
;;
*)
# Anything else (is there anything else?)
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
exit 1
;;
esac
# --- Finished
exit 0

View File

@@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

View File

@@ -0,0 +1,4 @@
0000000000000000000000000000000000000000 d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619277 +0100 commit (initial): Initial commit
d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619297 +0100 checkout: moving from master to gh-pages
d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 722a79af4a158c0076b4aaab7273750a35034738 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619310 +0100 commit: Foo
722a79af4a158c0076b4aaab7273750a35034738 d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619315 +0100 checkout: moving from gh-pages to master

View File

@@ -0,0 +1,2 @@
0000000000000000000000000000000000000000 d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619297 +0100 branch: Created from HEAD
d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 722a79af4a158c0076b4aaab7273750a35034738 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619310 +0100 commit: Foo

View File

@@ -0,0 +1 @@
0000000000000000000000000000000000000000 d999af9d9ffde37f31f69dc42e9c9c1be55c0b72 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619277 +0100 commit (initial): Initial commit

View File

@@ -0,0 +1 @@
722a79af4a158c0076b4aaab7273750a35034738

View File

@@ -0,0 +1 @@
d999af9d9ffde37f31f69dc42e9c9c1be55c0b72

View File

@@ -0,0 +1,14 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
insert_final_newline = true
[*.yml]
indent_style = space
indent_size = 2

View File

@@ -0,0 +1,27 @@
/application.yml
/application.properties
asciidoctor.css
*~
.#*
*#
target/
build/
bin/
_site/
.classpath
.project
.settings
.springBeans
.sts4-cache/
.attach_pid*
.DS_Store
*.sw*
*.iml
*.ipr
*.iws
.idea/*
.factorypath
dump.rdb
.apt_generated
artifacts
**/dependency-reduced-pom.xml

View File

@@ -0,0 +1 @@
-Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom

View File

@@ -0,0 +1 @@
-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring

View File

@@ -0,0 +1,110 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL =
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: : " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

View File

@@ -0,0 +1 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<servers>
<server>
<id>repo.spring.io</id>
<username>${env.CI_DEPLOY_USERNAME}</username>
<password>${env.CI_DEPLOY_PASSWORD}</password>
</server>
</servers>
<profiles>
<profile>
<!--
N.B. this profile is only here to support users and IDEs that do not use Maven 3.3.
It isn't needed on the command line if you use the wrapper script (mvnw) or if you use
a native Maven with the right version. Eclipse users should points their Maven tooling to
this settings file, or copy the profile into their ~/.m2/settings.xml.
-->
<id>spring</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
</settings>

View File

@@ -0,0 +1,16 @@
sudo: required
cache:
directories:
- $HOME/.m2
language: java
jdk:
- oraclejdk8
install: true
# The environment variable ${TRAVIS_PULL_REQUEST} is set to "false" when the build
# is for a normal branch commit. When the build is for a pull request, it will
# contain the pull requests number.
script:
- '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || ./mvnw package -Pspring,full -U -Dmaven.test.redirectTestOutputToFile=false'
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] || ./mvnw package -Pspring -U -Dmaven.test.redirectTestOutputToFile=false'
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@@ -0,0 +1,44 @@
= Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open
and welcoming community, we pledge to respect all people who contribute through reporting
issues, posting feature requests, updating documentation, submitting pull requests or
patches, and other activities.
We are committed to making participation in this project a harassment-free experience for
everyone, regardless of level of experience, gender, gender identity and expression,
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses,
without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments,
commits, code, wiki edits, issues, and other contributions that are not aligned to this
Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
that they deem inappropriate, threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to fairly and
consistently applying these principles to every aspect of managing this project. Project
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an
individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will
be reviewed and investigated and will result in a response that is deemed necessary and
appropriate to the circumstances. Maintainers are obligated to maintain confidentiality
with regard to the reporter of an incident.
This Code of Conduct is adapted from the
http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,334 @@
////
DO NOT EDIT THIS FILE. IT WAS GENERATED.
Manual changes to this file will be lost when it is generated again.
Edit the files in the src/main/asciidoc/ directory instead.
////
:jdkversion: 1.8
:github-tag: master
:github-repo: spring-cloud/spring-cloud-stream
:github-raw: https://raw.githubusercontent.com/{github-repo}/{github-tag}
:github-code: https://github.com/{github-repo}/tree/{github-tag}
image::https://circleci.com/gh/spring-cloud/spring-cloud-stream.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-stream"]
image::https://codecov.io/gh/spring-cloud/spring-cloud-stream/branch/{github-tag}/graph/badge.svg["codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-stream"]
image::https://badges.gitter.im/spring-cloud/spring-cloud-stream.svg[Gitter, link="https://gitter.im/spring-cloud/spring-cloud-stream?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
// ======================================================================================
= Preface
=== A Brief History of Spring's Data Integration Journey
Spring's journey on Data Integration started with https://projects.spring.io/spring-integration/[Spring Integration]. With its programming model, it provided a consistent developer experience to build applications that can embrace http://www.enterpriseintegrationpatterns.com/[Enterprise Integration Patterns] to connect with external systems such as, databases, message brokers, and among others.
Fast forward to the cloud-era, where microservices have become prominent in the enterprise setting. https://projects.spring.io/spring-boot/[Spring Boot] transformed the way how developers built Applications. With Spring's programming model and the runtime responsibilities handled by Spring Boot, it became seamless to develop stand-alone, production-grade Spring-based microservices.
To extend this to Data Integration workloads, Spring Integration and Spring Boot were put together into a new project. Spring Cloud Stream was born.
[%hardbreaks]
With Spring Cloud Stream, developers can:
* Build, test, iterate, and deploy data-centric applications in isolation.
* Apply modern microservices architecture patterns, including composition through messaging.
* Decouple application responsibilities with event-centric thinking. An event can represent something that has happened in time, to which the downstream consumer applications can react without knowing where it originated or the producer's identity.
* Port the business logic onto message brokers (such as RabbitMQ, Apache Kafka, Amazon Kinesis).
* Interoperate between channel-based and non-channel-based application binding scenarios to support stateless and stateful computations by using Project Reactor's Flux and Kafka Streams APIs.
* Rely on the framework's automatic content-type support for common use-cases. Extending to different data conversion types is possible.
=== Quick Start
You can try Spring Cloud Stream in less then 5 min even before you jump into any details by following this three-step guide.
We show you how to create a Spring Cloud Stream application that receives messages coming from the messaging middleware of your choice (more on this later) and logs received messages to the console.
We call it `LoggingConsumer`.
While not very practical, it provides a good introduction to some of the main concepts
and abstractions, making it easier to digest the rest of this user guide.
The three steps are as follows:
. <<spring-cloud-stream-preface-creating-sample-application>>
. <<spring-cloud-stream-preface-importing-project>>
. <<spring-cloud-stream-preface-adding-message-handler>>
[[spring-cloud-stream-preface-creating-sample-application]]
==== Creating a Sample Application by Using Spring Initializr
To get started, visit the https://start.spring.io[Spring Initializr]. From there, you can generate our `LoggingConsumer` application. To do so:
. In the *Dependencies* section, start typing `stream`.
When the "`Cloud Stream`" option should appears, select it.
. Start typing either 'kafka' or 'rabbit'.
. Select "`Kafka`" or "`RabbitMQ`".
+
Basically, you choose the messaging middleware to which your application binds.
We recommend using the one you have already installed or feel more comfortable with installing and running.
Also, as you can see from the Initilaizer screen, there are a few other options you can choose.
For example, you can choose Gradle as your build tool instead of Maven (the default).
. In the *Artifact* field, type 'logging-consumer'.
+
The value of the *Artifact* field becomes the application name.
If you chose RabbitMQ for the middleware, your Spring Initializr should now be as follows:
[%hardbreaks]
[%hardbreaks]
[%hardbreaks]
image::{github-raw}/docs/src/main/asciidoc/images/spring-initializr.png[align="center"]
[%hardbreaks]
[%hardbreaks]
. Click the *Generate Project* button.
+
Doing so downloads the zipped version of the generated project to your hard drive.
. Unzip the file into the folder you want to use as your project directory.
TIP: We encourage you to explore the many possibilities available in the Spring Initializr.
It lets you create many different kinds of Spring applications.
[[spring-cloud-stream-preface-importing-project]]
==== Importing the Project into Your IDE
Now you can import the project into your IDE.
Keep in mind that, depending on the IDE, you may need to follow a specific import procedure.
For example, depending on how the project was generated (Maven or Gradle), you may need to follow specific import procedure (for example, in Eclipse or STS, you need to use File -> Import -> Maven -> Existing Maven Project).
Once imported, the project must have no errors of any kind. Also, `src/main/java` should contain `com.example.loggingconsumer.LoggingConsumerApplication`.
Technically, at this point, you can run the application's main class.
It is already a valid Spring Boot application.
However, it does not do anything, so we want to add some code.
[[spring-cloud-stream-preface-adding-message-handler]]
==== Adding a Message Handler, Building, and Running
Modify the `com.example.loggingconsumer.LoggingConsumerApplication` class to look as follows:
[source, java]
----
@SpringBootApplication
@EnableBinding(Sink.class)
public class LoggingConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(LoggingConsumerApplication.class, args);
}
@StreamListener(Sink.INPUT)
public void handle(Person person) {
System.out.println("Received: " + person);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
}
}
----
As you can see from the preceding listing:
* We have enabled `Sink` binding (input-no-output) by using `@EnableBinding(Sink.class)`.
Doing so signals to the framework to initiate binding to the messaging middleware, where it automatically creates the destination (that is, queue, topic, and others) that are bound to the `Sink.INPUT` channel.
* We have added a `handler` method to receive incoming messages of type `Person`.
Doing so lets you see one of the core features of the framework: It tries to automatically convert incoming message payloads to type `Person`.
You now have a fully functional Spring Cloud Stream application that does listens for messages.
From here, for simplicity, we assume you selected RabbitMQ in <<spring-cloud-stream-preface-creating-sample-application,step one>>.
Assuming you have RabbitMQ installed and running, you can start the application by running its `main` method in your IDE.
You should see following output:
[source]
----
--- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg, bound to: input
--- [ main] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672]
--- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#2a3a299:0/SimpleConnection@66c83fc8. . .
. . .
--- [ main] o.s.i.a.i.AmqpInboundChannelAdapter : started inbound.input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg
. . .
--- [ main] c.e.l.LoggingConsumerApplication : Started LoggingConsumerApplication in 2.531 seconds (JVM running for 2.897)
----
Go to the RabbitMQ management console or any other RabbitMQ client and send a message to `input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg`.
The `anonymous.CbMIwdkJSBO1ZoPDOtHtCg` part represents the group name and is generated, so it is bound to be different in your environment.
For something more predictable, you can use an explicit group name by setting `spring.cloud.stream.bindings.input.group=hello` (or whatever name you like).
The contents of the message should be a JSON representation of the `Person` class, as follows:
{"name":"Sam Spade"}
Then, in your console, you should see:
`Received: Sam Spade`
You can also build and package your application into a boot jar (by using `./mvnw clean install`) and run the built JAR by using the `java -jar` command.
Now you have a working (albeit very basic) Spring Cloud Stream application.
== What's New in 2.2?
Spring Cloud Stream introduces a number of new features, enhancements, and changes in addition to the once already introduced in
https://docs.spring.io/spring-cloud-stream/docs/Elmhurst.SR2/reference/htmlsingle/#_what_s_new_in_2_0[version 2.0]
The following sections outline the most notable ones:
* <<spring-cloud-stream-preface-new-features>>
* <<spring-cloud-stream-preface-notable-enhancements>>
[[spring-cloud-stream-preface-new-features]]
=== New Features and Components
[[spring-cloud-stream-preface-notable-enhancements]]
=== Notable Enhancements
[[spring-cloud-stream-preface-notable-deprecations]]
=== Notable Deprecations
As of version 2.2, the following items have been deprecated:
- The spring-cloud-stream-reactive module is deprecated in favor of native support
via <<spring_cloud_function, Spring Cloud Function>> programming model.
=== Notes on migrating from 1.x to 2.x?
- Due to the improvements in content-type negotiation, the `originalContentType` header is not used (ignored) since 2.x and only exists for maintaining compatibility with 1.x versions
- Introduction of `@StreamRetryTemplate` qualifier. While configuring custom instance of the `RetryTemplate` and to avoid conflicts you must qualify the instance of such `RetryTemplate` with this qualifier. See <<Retry Template, Retry Template>> for more details.
= Appendices
[appendix]
[[building]]
== Building
:jdkversion: 1.8
=== Basic Compile and Test
To build the source you will need to install JDK {jdkversion}.
The build uses the Maven wrapper so you don't have to install a specific
version of Maven. To enable the tests for Redis, Rabbit, and Kafka bindings you
should have those servers running before building. See below for more
information on running the servers.
The main build command is
----
$ ./mvnw clean install
----
You can also add '-DskipTests' if you like, to avoid running the tests.
NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command
in place of `./mvnw` in the examples below. If you do that you also
might need to add `-P spring` if your local Maven settings do not
contain repository declarations for spring pre-release artifacts.
NOTE: Be aware that you might need to increase the amount of memory
available to Maven by setting a `MAVEN_OPTS` environment variable with
a value like `-Xmx512m -XX:MaxPermSize=128m`. We try to cover this in
the `.mvn` configuration, so if you find you have to do it to make a
build succeed, please raise a ticket to get the settings added to
source control.
The projects that require middleware generally include a
`docker-compose.yml`, so consider using
http://compose.docker.io/[Docker Compose] to run the middeware servers
in Docker containers. See the README in the
https://github.com/spring-cloud-samples/scripts[scripts demo
repository] for specific instructions about the common cases of mongo,
rabbit and redis.
=== Documentation
There is a "full" profile that will generate documentation.
=== Working with the code
If you don't have an IDE preference we would recommend that you use
http://www.springsource.com/developer/sts[Spring Tools Suite] or
http://eclipse.org[Eclipse] when working with the code. We use the
http://eclipse.org/m2e/[m2eclipe] eclipse plugin for maven support. Other IDEs and tools
should also work without issue.
==== Importing into eclipse with m2eclipse
We recommend the http://eclipse.org/m2e/[m2eclipe] eclipse plugin when working with
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
marketplace".
Unfortunately m2e does not yet support Maven 3.3, so once the projects
are imported into Eclipse you will also need to tell m2eclipse to use
the `.settings.xml` file for the projects. If you do not do this you
may see many different errors related to the POMs in the
projects. Open your Eclipse preferences, expand the Maven
preferences, and select User Settings. In the User Settings field
click Browse and navigate to the Spring Cloud project you imported
selecting the `.settings.xml` file in that project. Click Apply and
then OK to save the preference changes.
NOTE: Alternatively you can copy the repository settings from https://github.com/spring-cloud/spring-cloud-build/blob/master/.settings.xml[`.settings.xml`] into your own `~/.m2/settings.xml`.
==== Importing into eclipse without m2eclipse
If you prefer not to use m2eclipse you can generate eclipse project metadata using the
following command:
[indent=0]
----
$ ./mvnw eclipse:eclipse
----
The generated eclipse projects can be imported by selecting `import existing projects`
from the `file` menu.
[[contributing]]
== Contributing
Spring Cloud is released under the non-restrictive Apache 2.0 license,
and follows a very standard Github development process, using Github
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
=== Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you to sign the
https://support.springsource.com/spring_committer_signup[contributor's agreement].
Signing the contributor's agreement does not grant anyone commit rights to the main
repository, but it does mean that we can accept your contributions, and you will get an
author credit if we do. Active contributors might be asked to join the core team, and
given the ability to merge pull requests.
=== Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
* Use the Spring Framework code format conventions. If you use Eclipse
you can import formatter settings using the
`eclipse-code-formatter.xml` file from the
https://github.com/spring-cloud/build/tree/master/eclipse-coding-conventions.xml[Spring
Cloud Build] project. If using IntelliJ, you can use the
http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
Plugin] to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
`@author` tag identifying you, and preferably at least a paragraph on what the class is
for.
* Add the ASF license header comment to all new `.java` files (copy from existing files
in the project)
* Add yourself as an `@author` to the .java files that you modify substantially (more
than cosmetic changes).
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
* A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or
other target branch in the main project).
* When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
message (where XXXX is the issue number).
// ======================================================================================

View File

@@ -0,0 +1,326 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-core-docs</artifactId>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-parent</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version>
</parent>
<packaging>pom</packaging>
<name>spring-cloud-stream-core-docs</name>
<description>Spring Cloud Stream Core Documentation</description>
<properties>
<docs.main>home</docs.main>
<main.basedir>${basedir}/..</main.basedir>
<spring-doc-resources.version>0.1.1.RELEASE</spring-doc-resources.version>
<spring-asciidoctor-extensions.version>0.1.0.RELEASE
</spring-asciidoctor-extensions.version>
<asciidoctorj-pdf.version>1.5.0-alpha.16</asciidoctorj-pdf.version>
</properties>
<profiles>
<profile>
<id>docs</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<inherited>false</inherited>
<executions>
<execution>
<id>unpack-docs</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework.cloud
</groupId>
<artifactId>spring-cloud-build-docs
</artifactId>
<version>${spring-cloud-build.version}
</version>
<classifier>sources</classifier>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${docs.resources.dir}
</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<id>unpack-docs-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>io.spring.docresources</groupId>
<artifactId>spring-doc-resources</artifactId>
<version>${spring-doc-resources.version}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/refdocs/</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-asciidoc-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/refdocs/</outputDirectory>
<resources>
<resource>
<directory>src/main/asciidoc</directory>
<filtering>false</filtering>
<excludes>
<exclude>ghpages.sh</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>${asciidoctor-maven-plugin.version}</version>
<inherited>false</inherited>
<dependencies>
<dependency>
<groupId>io.spring.asciidoctor</groupId>
<artifactId>spring-asciidoctor-extensions</artifactId>
<version>${spring-asciidoctor-extensions.version}</version>
</dependency>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj-pdf</artifactId>
<version>${asciidoctorj-pdf.version}</version>
</dependency>
</dependencies>
<configuration>
<sourceDirectory>${project.build.directory}/refdocs/</sourceDirectory>
<attributes>
<spring-cloud-stream-version>${project.version}</spring-cloud-stream-version>
<docs-url>http://cloud.spring.io/</docs-url>
<docs-version></docs-version>
<!-- <docs-version>${project.version}/</docs-version> -->
<!-- <docs-url>http://cloud.spring.io/spring-cloud-static/</docs-url> -->
</attributes>
</configuration>
<executions>
<execution>
<id>generate-html-documentation</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html5</backend>
<sourceHighlighter>highlight.js</sourceHighlighter>
<doctype>book</doctype>
<attributes>
// these attributes are required to use the doc resources
<docinfo>shared</docinfo>
<stylesdir>css/</stylesdir>
<stylesheet>spring.css</stylesheet>
<linkcss>true</linkcss>
<icons>font</icons>
<highlightjsdir>js/highlight</highlightjsdir>
<highlightjs-theme>atom-one-dark-reasonable</highlightjs-theme>
<allow-uri-read>true</allow-uri-read>
<nofooter />
<toc>left</toc>
<toc-levels>4</toc-levels>
<spring-cloud-version>${project.version}</spring-cloud-version>
<sectlinks>true</sectlinks>
</attributes>
</configuration>
</execution>
<execution>
<id>generate-docbook</id>
<phase>none</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
</execution>
<execution>
<id>generate-index</id>
<phase>none</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>${maven-antrun-plugin.version}</version>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.tigris.antelope</groupId>
<artifactId>antelopetasks</artifactId>
<version>3.2.10</version>
</dependency>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>1.7.17</version>
</dependency>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj</artifactId>
<version>1.5.8</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>readme</id>
<phase>process-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<java classname="org.jruby.Main" failonerror="yes">
<arg
value="${docs.resources.dir}/ruby/generate_readme.sh" />
<arg value="-o" />
<arg value="${main.basedir}/README.adoc" />
</java>
</target>
</configuration>
</execution>
<execution>
<id>assert-no-unresolved-links</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<fileset id="unresolved.file"
dir="${basedir}/target/generated-docs/" includes="**/*.html">
<contains text="Unresolved" />
</fileset>
<fail message="[Unresolved] Found...failing">
<condition>
<resourcecount when="greater" count="0"
refid="unresolved.file" />
</condition>
</fail>
</target>
</configuration>
</execution>
<execution>
<id>setup-maven-properties</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<taskdef
resource="net/sf/antcontrib/antcontrib.properties" />
<taskdef name="stringutil"
classname="ise.antelope.tasks.StringUtilTask" />
<var name="version-type" value="${project.version}" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp=".*\.(.*)"
replace="\1" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(M)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(RC)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="BUILD-(.*)"
replace="SNAPSHOT" />
<stringutil string="${version-type}"
property="spring-cloud-repo">
<lowercase />
</stringutil>
<var name="github-tag" value="v${project.version}" />
<propertyregex property="github-tag"
override="true" input="${github-tag}" regexp=".*SNAPSHOT"
replace="master" />
</target>
</configuration>
</execution>
<execution>
<id>copy-css</id>
<phase>none</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>generate-documentation-index</id>
<phase>none</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>copy-generated-html</id>
<phase>none</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,146 @@
:jdkversion: 1.8
:github-tag: master
:github-repo: spring-cloud/spring-cloud-stream
:github-raw: https://raw.githubusercontent.com/{github-repo}/{github-tag}
:github-code: https://github.com/{github-repo}/tree/{github-tag}
image::https://circleci.com/gh/spring-cloud/spring-cloud-stream.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-stream"]
image::https://codecov.io/gh/spring-cloud/spring-cloud-stream/branch/{github-tag}/graph/badge.svg["codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-stream"]
image::https://badges.gitter.im/spring-cloud/spring-cloud-stream.svg[Gitter, link="https://gitter.im/spring-cloud/spring-cloud-stream?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]
// ======================================================================================
= Preface
include::preface.adoc[]
= Appendices
[appendix]
[[building]]
== Building
:jdkversion: 1.8
=== Basic Compile and Test
To build the source you will need to install JDK {jdkversion}.
The build uses the Maven wrapper so you don't have to install a specific
version of Maven. To enable the tests for Redis, Rabbit, and Kafka bindings you
should have those servers running before building. See below for more
information on running the servers.
The main build command is
----
$ ./mvnw clean install
----
You can also add '-DskipTests' if you like, to avoid running the tests.
NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command
in place of `./mvnw` in the examples below. If you do that you also
might need to add `-P spring` if your local Maven settings do not
contain repository declarations for spring pre-release artifacts.
NOTE: Be aware that you might need to increase the amount of memory
available to Maven by setting a `MAVEN_OPTS` environment variable with
a value like `-Xmx512m -XX:MaxPermSize=128m`. We try to cover this in
the `.mvn` configuration, so if you find you have to do it to make a
build succeed, please raise a ticket to get the settings added to
source control.
The projects that require middleware generally include a
`docker-compose.yml`, so consider using
http://compose.docker.io/[Docker Compose] to run the middeware servers
in Docker containers. See the README in the
https://github.com/spring-cloud-samples/scripts[scripts demo
repository] for specific instructions about the common cases of mongo,
rabbit and redis.
=== Documentation
There is a "full" profile that will generate documentation.
=== Working with the code
If you don't have an IDE preference we would recommend that you use
http://www.springsource.com/developer/sts[Spring Tools Suite] or
http://eclipse.org[Eclipse] when working with the code. We use the
http://eclipse.org/m2e/[m2eclipe] eclipse plugin for maven support. Other IDEs and tools
should also work without issue.
==== Importing into eclipse with m2eclipse
We recommend the http://eclipse.org/m2e/[m2eclipe] eclipse plugin when working with
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
marketplace".
Unfortunately m2e does not yet support Maven 3.3, so once the projects
are imported into Eclipse you will also need to tell m2eclipse to use
the `.settings.xml` file for the projects. If you do not do this you
may see many different errors related to the POMs in the
projects. Open your Eclipse preferences, expand the Maven
preferences, and select User Settings. In the User Settings field
click Browse and navigate to the Spring Cloud project you imported
selecting the `.settings.xml` file in that project. Click Apply and
then OK to save the preference changes.
NOTE: Alternatively you can copy the repository settings from https://github.com/spring-cloud/spring-cloud-build/blob/master/.settings.xml[`.settings.xml`] into your own `~/.m2/settings.xml`.
==== Importing into eclipse without m2eclipse
If you prefer not to use m2eclipse you can generate eclipse project metadata using the
following command:
[indent=0]
----
$ ./mvnw eclipse:eclipse
----
The generated eclipse projects can be imported by selecting `import existing projects`
from the `file` menu.
[[contributing]]
== Contributing
Spring Cloud is released under the non-restrictive Apache 2.0 license,
and follows a very standard Github development process, using Github
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
=== Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you to sign the
https://support.springsource.com/spring_committer_signup[contributor's agreement].
Signing the contributor's agreement does not grant anyone commit rights to the main
repository, but it does mean that we can accept your contributions, and you will get an
author credit if we do. Active contributors might be asked to join the core team, and
given the ability to merge pull requests.
=== Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
* Use the Spring Framework code format conventions. If you use Eclipse
you can import formatter settings using the
`eclipse-code-formatter.xml` file from the
https://github.com/spring-cloud/build/tree/master/eclipse-coding-conventions.xml[Spring
Cloud Build] project. If using IntelliJ, you can use the
http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
Plugin] to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
`@author` tag identifying you, and preferably at least a paragraph on what the class is
for.
* Add the ASF license header comment to all new `.java` files (copy from existing files
in the project)
* Add yourself as an `@author` to the .java files that you modify substantially (more
than cosmetic changes).
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
* A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or
other target branch in the main project).
* When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
message (where XXXX is the issue number).
// ======================================================================================

View File

@@ -0,0 +1,13 @@
*{spring-cloud-stream-version}*
[[binders]]
== Binder Implementations
The following is the list of available binder implementations
* https://cloud.spring.io/spring-cloud-stream-binder-rabbit/[RabbitMQ]
* https://cloud.spring.io/spring-cloud-stream-binder-kafka/[Apache Kafka]
* https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis[Amazon Kinesis]
* https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder[Google PubSub _(partner maintained)_]
* https://github.com/SolaceProducts/spring-cloud-stream-binder-solace[Solace PubSub+ _(partner maintained)_]
* https://github.com/Microsoft/spring-cloud-azure/tree/master/spring-cloud-azure-eventhub-stream-binder[Azure Event Hubs _(partner maintained)_]

View File

@@ -0,0 +1,330 @@
#!/bin/bash -x
set -e
# Set default props like MAVEN_PATH, ROOT_FOLDER etc.
function set_default_props() {
# The script should be executed from the root folder
ROOT_FOLDER=`pwd`
echo "Current folder is ${ROOT_FOLDER}"
if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then
echo "You're not in the root folder of the project!"
exit 1
fi
# Prop that will let commit the changes
COMMIT_CHANGES="no"
MAVEN_PATH=${MAVEN_PATH:-}
echo "Path to Maven is [${MAVEN_PATH}]"
REPO_NAME=${PWD##*/}
echo "Repo name is [${REPO_NAME}]"
SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git}
echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}"
}
# Check if gh-pages exists and docs have been built
function check_if_anything_to_sync() {
git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
if ! (git remote set-branches --add origin gh-pages && git fetch -q); then
echo "No gh-pages, so not syncing"
exit 0
fi
if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then
echo "No gh-pages sources in docs/target/generated-docs, so not syncing"
exit 0
fi
}
function retrieve_current_branch() {
# Code getting the name of the current branch. For master we want to publish as we did until now
# https://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}]"
# https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then
mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH}
echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder"
for f in docs/target/generated-docs/*; do
file=${f#docs/target/generated-docs/*}
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
# Not ignored...
# We want users to access 2.0.0.BUILD-SNAPSHOT/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then
# We don't want to copy the spring-cloud-sleuth.html
# we want it to be converted to index.html
cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
else
cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}
git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file
fi
fi
done
COMMIT_CHANGES="yes"
else
echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in
[docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch."
fi
fi
}
# Copies the docs by using the explicitly provided version
function copy_docs_for_provided_version() {
local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION}
mkdir -p ${FOLDER}
echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder"
for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do
file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*}
copy_docs_for_branch ${file} ${FOLDER}
done
COMMIT_CHANGES="yes"
CURRENT_BRANCH="v${VERSION}"
}
# Copies the docs from target to the provided destination
# Params:
# $1 - file from target
# $2 - destination to which copy the files
function copy_docs_for_branch() {
local file=$1
local destination=$2
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then
# Not ignored...
# We want users to access 2.0.0.BUILD-SNAPSHOT/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then
# We don't want to copy the spring-cloud-sleuth.html
# we want it to be converted to index.html
cp -rf $f ${destination}/index.html
git add -A ${destination}/index.html
else
cp -rf $f ${destination}
git add -A ${destination}/$file
fi
fi
}
function commit_changes_if_applicable() {
if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then
COMMIT_SUCCESSFUL="no"
git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes"
# Uncomment the following push if you want to auto push to
# the gh-pages branch whenever you commit to master locally.
# This is a little extreme. Use with care!
###################################################################
if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then
git push origin gh-pages
fi
fi
}
# Switch back to the previous branch and exit block
function checkout_previous_branch() {
# If -version was provided we need to come back to root project
cd ${ROOT_FOLDER}
git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script"
if [ "$dirty" != "0" ]; then git stash pop; fi
exit 0
}
# Assert if properties have been properly passed
function assert_properties() {
echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]"
if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi
if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi
if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi
}
# Prints the usage
function print_usage() {
cat <<EOF
The idea of this script is to update gh-pages branch with the generated docs. Without any options
the script will work in the following manner:
- if there's no gh-pages / target for docs module then the script ends
- for master branch the generated docs are copied to the root of gh-pages branch
- for any other branch (if that branch is whitelisted) a subfolder with branch name is created
and docs are copied there
- if the version switch is passed (-v) then a tag with (v) prefix will be retrieved and a folder
with that version number will be created in the gh-pages branch. WARNING! No whitelist verification will take place
- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will
switch to gh-pages of that repo and copy the generated docs to `docs/<project-name>/<version>`
- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will
switch to gh-pages of that repo and copy the generated docs to `docs/<project-name>/<version>`
USAGE:
You can use the following options:
-v|--version - the script will apply the whole procedure for a particular library version
-d|--destination - the root of destination folder where the docs should be copied. You have to use the full path.
E.g. point to spring-cloud-static folder. Can't be used with (-c)
-b|--build - will run the standard build process after checking out the branch
-c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination.
Obviously can't be used with (-d)
EOF
}
# ==========================================
# ____ ____ _____ _____ _____ _______
# / ____|/ ____| __ \|_ _| __ \__ __|
# | (___ | | | |__) | | | | |__) | | |
# \___ \| | | _ / | | | ___/ | |
# ____) | |____| | \ \ _| |_| | | |
# |_____/ \_____|_| \_\_____|_| |_|
#
# ==========================================
while [[ $# > 0 ]]
do
key="$1"
case ${key} in
-v|--version)
VERSION="$2"
shift # past argument
;;
-d|--destination)
DESTINATION="$2"
shift # past argument
;;
-b|--build)
BUILD="yes"
;;
-c|--clone)
CLONE="yes"
;;
-h|--help)
print_usage
exit 0
;;
*)
echo "Invalid option: [$1]"
print_usage
exit 1
;;
esac
shift # past argument or value
done
assert_properties
set_default_props
check_if_anything_to_sync
if [[ -z "${VERSION}" ]] ; then
retrieve_current_branch
else
switch_to_tag
fi
build_docs_if_applicable
retrieve_doc_properties
stash_changes
add_docs_from_target
checkout_previous_branch

View File

@@ -0,0 +1,24 @@
= Spring Cloud Stream Reference Documentation
Sabby Anandan; Marius Bogoevici; Eric Bottard; Mark Fisher; Ilayaperumal Gopinathan; Gunnar Hillert; Mark Pollack; Patrick Peralta; Glenn Renfro; Thomas Risberg; Dave Syer; David Turanski; Janne Valkealahti; Benjamin Klein; Vinicius Carvalho; Gary Russell; Oleg Zhurakousky; Jay Bryant; Soby Chacko
*{spring-cloud-stream-version}*
:docinfo: shared
The reference documentation consists of the following sections:
[horizontal]
<<spring-cloud-stream.adoc#spring-cloud-stream-reference,Overview>> :: History, Quick Start, Concepts, Architecture Overview, Binder Abstraction, and Core Features
{docs-url}spring-cloud-stream-binder-rabbit/{docs-version}spring-cloud-stream-binder-rabbit.html[Rabbit MQ Binder] :: Spring Cloud Stream binder reference for Rabbit MQ
{docs-url}spring-cloud-stream-binder-kafka/{docs-version}spring-cloud-stream-binder-kafka.html#_apache_kafka_binder[Apache Kafka Binder] :: Spring Cloud Stream binder reference for Apache Kafka
{docs-url}spring-cloud-stream-binder-kafka/{docs-version}spring-cloud-stream-binder-kafka.html#_kafka_streams_binder[Apache Kafka Streams Binder] :: Spring Cloud Stream binder reference for Apache Kafka Streams
<<binders.adoc#binders,Additional Binders>> :: A collection of Partner maintained binder implementations for Spring Cloud Stream (e.g., Azure Event Hubs, Google PubSub, Solace PubSub+)
https://github.com/spring-cloud/spring-cloud-stream-samples/[Spring Cloud Stream Samples] :: A curated collection of repeatable Spring Cloud Stream samples to walk through the features
Relevant Links:
[horizontal]
https://cloud.spring.io/spring-cloud-dataflow/[Spring Cloud Data Flow] :: Spring Cloud Data Flow
http://www.enterpriseintegrationpatterns.com/[Enterprise Integration Patterns] :: Patterns and Best Practices for Enterprise Integration
https://spring.io/projects/spring-integration[Spring Integration] :: Spring Integration framework

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,183 @@
=== A Brief History of Spring's Data Integration Journey
Spring's journey on Data Integration started with https://projects.spring.io/spring-integration/[Spring Integration]. With its programming model, it provided a consistent developer experience to build applications that can embrace http://www.enterpriseintegrationpatterns.com/[Enterprise Integration Patterns] to connect with external systems such as, databases, message brokers, and among others.
Fast forward to the cloud-era, where microservices have become prominent in the enterprise setting. https://projects.spring.io/spring-boot/[Spring Boot] transformed the way how developers built Applications. With Spring's programming model and the runtime responsibilities handled by Spring Boot, it became seamless to develop stand-alone, production-grade Spring-based microservices.
To extend this to Data Integration workloads, Spring Integration and Spring Boot were put together into a new project. Spring Cloud Stream was born.
[%hardbreaks]
With Spring Cloud Stream, developers can:
* Build, test, iterate, and deploy data-centric applications in isolation.
* Apply modern microservices architecture patterns, including composition through messaging.
* Decouple application responsibilities with event-centric thinking. An event can represent something that has happened in time, to which the downstream consumer applications can react without knowing where it originated or the producer's identity.
* Port the business logic onto message brokers (such as RabbitMQ, Apache Kafka, Amazon Kinesis).
* Interoperate between channel-based and non-channel-based application binding scenarios to support stateless and stateful computations by using Project Reactor's Flux and Kafka Streams APIs.
* Rely on the framework's automatic content-type support for common use-cases. Extending to different data conversion types is possible.
=== Quick Start
You can try Spring Cloud Stream in less then 5 min even before you jump into any details by following this three-step guide.
We show you how to create a Spring Cloud Stream application that receives messages coming from the messaging middleware of your choice (more on this later) and logs received messages to the console.
We call it `LoggingConsumer`.
While not very practical, it provides a good introduction to some of the main concepts
and abstractions, making it easier to digest the rest of this user guide.
The three steps are as follows:
. <<spring-cloud-stream-preface-creating-sample-application>>
. <<spring-cloud-stream-preface-importing-project>>
. <<spring-cloud-stream-preface-adding-message-handler>>
[[spring-cloud-stream-preface-creating-sample-application]]
==== Creating a Sample Application by Using Spring Initializr
To get started, visit the https://start.spring.io[Spring Initializr]. From there, you can generate our `LoggingConsumer` application. To do so:
. In the *Dependencies* section, start typing `stream`.
When the "`Cloud Stream`" option should appears, select it.
. Start typing either 'kafka' or 'rabbit'.
. Select "`Kafka`" or "`RabbitMQ`".
+
Basically, you choose the messaging middleware to which your application binds.
We recommend using the one you have already installed or feel more comfortable with installing and running.
Also, as you can see from the Initilaizer screen, there are a few other options you can choose.
For example, you can choose Gradle as your build tool instead of Maven (the default).
. In the *Artifact* field, type 'logging-consumer'.
+
The value of the *Artifact* field becomes the application name.
If you chose RabbitMQ for the middleware, your Spring Initializr should now be as follows:
[%hardbreaks]
[%hardbreaks]
[%hardbreaks]
image::{github-raw}/docs/src/main/asciidoc/images/spring-initializr.png[align="center"]
[%hardbreaks]
[%hardbreaks]
. Click the *Generate Project* button.
+
Doing so downloads the zipped version of the generated project to your hard drive.
. Unzip the file into the folder you want to use as your project directory.
TIP: We encourage you to explore the many possibilities available in the Spring Initializr.
It lets you create many different kinds of Spring applications.
[[spring-cloud-stream-preface-importing-project]]
==== Importing the Project into Your IDE
Now you can import the project into your IDE.
Keep in mind that, depending on the IDE, you may need to follow a specific import procedure.
For example, depending on how the project was generated (Maven or Gradle), you may need to follow specific import procedure (for example, in Eclipse or STS, you need to use File -> Import -> Maven -> Existing Maven Project).
Once imported, the project must have no errors of any kind. Also, `src/main/java` should contain `com.example.loggingconsumer.LoggingConsumerApplication`.
Technically, at this point, you can run the application's main class.
It is already a valid Spring Boot application.
However, it does not do anything, so we want to add some code.
[[spring-cloud-stream-preface-adding-message-handler]]
==== Adding a Message Handler, Building, and Running
Modify the `com.example.loggingconsumer.LoggingConsumerApplication` class to look as follows:
[source, java]
----
@SpringBootApplication
@EnableBinding(Sink.class)
public class LoggingConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(LoggingConsumerApplication.class, args);
}
@StreamListener(Sink.INPUT)
public void handle(Person person) {
System.out.println("Received: " + person);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
}
}
----
As you can see from the preceding listing:
* We have enabled `Sink` binding (input-no-output) by using `@EnableBinding(Sink.class)`.
Doing so signals to the framework to initiate binding to the messaging middleware, where it automatically creates the destination (that is, queue, topic, and others) that are bound to the `Sink.INPUT` channel.
* We have added a `handler` method to receive incoming messages of type `Person`.
Doing so lets you see one of the core features of the framework: It tries to automatically convert incoming message payloads to type `Person`.
You now have a fully functional Spring Cloud Stream application that does listens for messages.
From here, for simplicity, we assume you selected RabbitMQ in <<spring-cloud-stream-preface-creating-sample-application,step one>>.
Assuming you have RabbitMQ installed and running, you can start the application by running its `main` method in your IDE.
You should see following output:
[source]
----
--- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg, bound to: input
--- [ main] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672]
--- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#2a3a299:0/SimpleConnection@66c83fc8. . .
. . .
--- [ main] o.s.i.a.i.AmqpInboundChannelAdapter : started inbound.input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg
. . .
--- [ main] c.e.l.LoggingConsumerApplication : Started LoggingConsumerApplication in 2.531 seconds (JVM running for 2.897)
----
Go to the RabbitMQ management console or any other RabbitMQ client and send a message to `input.anonymous.CbMIwdkJSBO1ZoPDOtHtCg`.
The `anonymous.CbMIwdkJSBO1ZoPDOtHtCg` part represents the group name and is generated, so it is bound to be different in your environment.
For something more predictable, you can use an explicit group name by setting `spring.cloud.stream.bindings.input.group=hello` (or whatever name you like).
The contents of the message should be a JSON representation of the `Person` class, as follows:
{"name":"Sam Spade"}
Then, in your console, you should see:
`Received: Sam Spade`
You can also build and package your application into a boot jar (by using `./mvnw clean install`) and run the built JAR by using the `java -jar` command.
Now you have a working (albeit very basic) Spring Cloud Stream application.
== What's New in 2.2?
Spring Cloud Stream introduces a number of new features, enhancements, and changes in addition to the once already introduced in
https://docs.spring.io/spring-cloud-stream/docs/Elmhurst.SR2/reference/htmlsingle/#_what_s_new_in_2_0[version 2.0]
The following sections outline the most notable ones:
* <<spring-cloud-stream-preface-new-features>>
* <<spring-cloud-stream-preface-notable-enhancements>>
[[spring-cloud-stream-preface-new-features]]
=== New Features and Components
[[spring-cloud-stream-preface-notable-enhancements]]
=== Notable Enhancements
[[spring-cloud-stream-preface-notable-deprecations]]
=== Notable Deprecations
As of version 2.2, the following items have been deprecated:
- The spring-cloud-stream-reactive module is deprecated in favor of native support
via <<spring_cloud_function, Spring Cloud Function>> programming model.
=== Notes on migrating from 1.x to 2.x?
- Due to the improvements in content-type negotiation, the `originalContentType` header is not used (ignored) since 2.x and only exists for maintaining compatibility with 1.x versions
- Introduction of `@StreamRetryTemplate` qualifier. While configuring custom instance of the `RetryTemplate` and to avoid conflicts you must qualify the instance of such `RetryTemplate` with this qualifier. See <<Retry Template, Retry Template>> for more details.

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env ruby
base_dir = File.join(File.dirname(__FILE__),'../../..')
src_dir = File.join(base_dir, "/src/main/asciidoc")
require 'asciidoctor'
require 'optparse'
options = {}
file = "#{src_dir}/README.adoc"
OptionParser.new do |o|
o.on('-o OUTPUT_FILE', 'Output file (default is stdout)') { |file| options[:to_file] = file unless file=='-' }
o.on('-h', '--help') { puts o; exit }
o.parse!
end
file = ARGV[0] if ARGV.length>0
# Copied from https://github.com/asciidoctor/asciidoctor-extensions-lab/blob/master/scripts/asciidoc-coalescer.rb
doc = Asciidoctor.load_file file, safe: :unsafe, header_only: true, attributes: options[:attributes]
header_attr_names = (doc.instance_variable_get :@attributes_modified).to_a
header_attr_names.each {|k| doc.attributes[%(#{k}!)] = '' unless doc.attr? k }
attrs = doc.attributes
attrs['allow-uri-read'] = true
puts attrs
out = "// Do not edit this file (e.g. go instead to src/main/asciidoc)\n\n"
doc = Asciidoctor.load_file file, safe: :unsafe, parse: false, attributes: attrs
out << doc.reader.read
unless options[:to_file]
puts out
else
File.open(options[:to_file],'w+') do |file|
file.write(out)
end
end

View File

@@ -0,0 +1 @@
Added checkstyle

View File

@@ -0,0 +1 @@
3e7f960197e196ec9a2f536711a97cc7cfc7e45d branch 'gh-pages' of github.com:spring-cloud/spring-cloud-stream

View File

@@ -0,0 +1 @@
ref: refs/heads/master

View File

@@ -0,0 +1 @@
6b970b1d0ed73ee4da171c19ee2d004c629570df

View File

@@ -0,0 +1,14 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@github.com:spring-cloud/spring-cloud-stream
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "gh-pages"]
remote = origin
merge = refs/heads/gh-pages

View File

@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@@ -0,0 +1,15 @@
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit. The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".
. git-sh-setup
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
:

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".
# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
# This example catches duplicate Signed-off-by lines.
test "" = "$(grep '^Signed-off-by: ' "$1" |
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
echo >&2 Duplicate Signed-off-by lines.
exit 1
}

View File

@@ -0,0 +1,114 @@
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open2;
# An example hook script to integrate Watchman
# (https://facebook.github.io/watchman/) with git to speed up detecting
# new and modified files.
#
# The hook is passed a version (currently 1) and a time in nanoseconds
# formatted as a string and outputs to stdout all files that have been
# modified since the given time. Paths must be relative to the root of
# the working tree and separated by a single NUL.
#
# To enable this hook, rename this file to "query-watchman" and set
# 'git config core.fsmonitor .git/hooks/query-watchman'
#
my ($version, $time) = @ARGV;
# Check the hook interface version
if ($version == 1) {
# convert nanoseconds to seconds
$time = int $time / 1000000000;
} else {
die "Unsupported query-fsmonitor hook version '$version'.\n" .
"Falling back to scanning...\n";
}
my $git_work_tree;
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
$git_work_tree = Win32::GetCwd();
$git_work_tree =~ tr/\\/\//;
} else {
require Cwd;
$git_work_tree = Cwd::cwd();
}
my $retry = 1;
launch_watchman();
sub launch_watchman {
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
or die "open2() failed: $!\n" .
"Falling back to scanning...\n";
# In the query expression below we're asking for names of files that
# changed since $time but were not transient (ie created after
# $time but no longer exist).
#
# To accomplish this, we're using the "since" generator to use the
# recency index to select candidate nodes and "fields" to limit the
# output to file names only. Then we're using the "expression" term to
# further constrain the results.
#
# The category of transient files that we want to ignore will have a
# creation clock (cclock) newer than $time_t value and will also not
# currently exist.
my $query = <<" END";
["query", "$git_work_tree", {
"since": $time,
"fields": ["name"],
"expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]]
}]
END
print CHLD_IN $query;
close CHLD_IN;
my $response = do {local $/; <CHLD_OUT>};
die "Watchman: command returned no output.\n" .
"Falling back to scanning...\n" if $response eq "";
die "Watchman: command returned invalid output: $response\n" .
"Falling back to scanning...\n" unless $response =~ /^\{/;
my $json_pkg;
eval {
require JSON::XS;
$json_pkg = "JSON::XS";
1;
} or do {
require JSON::PP;
$json_pkg = "JSON::PP";
};
my $o = $json_pkg->new->utf8->decode($response);
if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {
print STDERR "Adding '$git_work_tree' to watchman's watch list.\n";
$retry--;
qx/watchman watch "$git_work_tree"/;
die "Failed to make watchman watch '$git_work_tree'.\n" .
"Falling back to scanning...\n" if $? != 0;
# Watchman will always return all files on the first query so
# return the fast "everything is dirty" flag to git and do the
# Watchman query just to get it over with now so we won't pay
# the cost in git to look up each individual file.
print "/\0";
eval { launch_watchman() };
exit 0;
}
die "Watchman: $o->{error}.\n" .
"Falling back to scanning...\n" if $o->{error};
binmode STDOUT, ":utf8";
local $, = "\0";
print @{$o->{files}};
}

View File

@@ -0,0 +1,8 @@
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".
exec git update-server-info

View File

@@ -0,0 +1,14 @@
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".
. git-sh-setup
precommit="$(git rev-parse --git-path hooks/pre-commit)"
test -x "$precommit" && exec "$precommit" ${1+"$@"}
:

View File

@@ -0,0 +1,49 @@
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=$(git hash-object -t tree /dev/null)
fi
# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)
# Redirect output to stderr.
exec 1>&2
# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
# Note that the use of brackets around a tr range is ok here, (it's
# even required, for portability to Solaris 10's /usr/bin/tr), since
# the square bracket bytes happen to fall in the designated range.
test $(git diff --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
cat <<\EOF
Error: Attempt to add a non-ASCII file name.
This can cause problems if you want to work with people on other platforms.
To be portable it is advisable to rename the file.
If you know what you are doing you can disable this check using:
git config hooks.allownonascii true
EOF
exit 1
fi
# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

View File

@@ -0,0 +1,53 @@
#!/bin/sh
# An example hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).
remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_sha" = $z40 ]
then
# Handle delete
:
else
if [ "$remote_sha" = $z40 ]
then
# New branch, examine all commits
range="$local_sha"
else
# Update to existing branch, examine new commits
range="$remote_sha..$local_sha"
fi
# Check for WIP commit
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
if [ -n "$commit" ]
then
echo >&2 "Found WIP commit in $local_ref, not pushing"
exit 1
fi
fi
done
exit 0

View File

@@ -0,0 +1,169 @@
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.
publish=next
basebranch="$1"
if test "$#" = 2
then
topic="refs/heads/$2"
else
topic=`git symbolic-ref HEAD` ||
exit 0 ;# we do not interrupt rebasing detached HEAD
fi
case "$topic" in
refs/heads/??/*)
;;
*)
exit 0 ;# we do not interrupt others.
;;
esac
# Now we are dealing with a topic branch being rebased
# on top of master. Is it OK to rebase it?
# Does the topic really exist?
git show-ref -q "$topic" || {
echo >&2 "No such branch $topic"
exit 1
}
# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
echo >&2 "$topic is fully merged to master; better remove it."
exit 1 ;# we could allow it, but there is no point.
fi
# Is topic ever merged to next? If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
not_in_topic=`git rev-list "^$topic" master`
if test -z "$not_in_topic"
then
echo >&2 "$topic is already up to date with master"
exit 1 ;# we could allow it, but there is no point.
else
exit 0
fi
else
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
/usr/bin/perl -e '
my $topic = $ARGV[0];
my $msg = "* $topic has commits already merged to public branch:\n";
my (%not_in_next) = map {
/^([0-9a-f]+) /;
($1 => 1);
} split(/\n/, $ARGV[1]);
for my $elem (map {
/^([0-9a-f]+) (.*)$/;
[$1 => $2];
} split(/\n/, $ARGV[2])) {
if (!exists $not_in_next{$elem->[0]}) {
if ($msg) {
print STDERR $msg;
undef $msg;
}
print STDERR " $elem->[1]\n";
}
}
' "$topic" "$not_in_next" "$not_in_master"
exit 1
fi
<<\DOC_END
This sample hook safeguards topic branches that have been
published from being rewound.
The workflow assumed here is:
* Once a topic branch forks from "master", "master" is never
merged into it again (either directly or indirectly).
* Once a topic branch is fully cooked and merged into "master",
it is deleted. If you need to build on top of it to correct
earlier mistakes, a new topic branch is created by forking at
the tip of the "master". This is not strictly necessary, but
it makes it easier to keep your history simple.
* Whenever you need to test or publish your changes to topic
branches, merge them into "next" branch.
The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.
With this workflow, you would want to know:
(1) ... if a topic branch has ever been merged to "next". Young
topic branches can have stupid mistakes you would rather
clean up before publishing, and things that have not been
merged into other branches can be easily rebased without
affecting other people. But once it is published, you would
not want to rewind it.
(2) ... if a topic branch has been fully merged to "master".
Then you can delete it. More importantly, you should not
build on top of it -- other people may already want to
change things related to the topic as patches against your
"master", so if you need further changes, it is better to
fork the topic (perhaps with the same name) afresh from the
tip of "master".
Let's look at this example:
o---o---o---o---o---o---o---o---o---o "next"
/ / / /
/ a---a---b A / /
/ / / /
/ / c---c---c---c B /
/ / / \ /
/ / / b---b C \ /
/ / / / \ /
---o---o---o---o---o---o---o---o---o---o---o "master"
A, B and C are topic branches.
* A has one fix since it was merged up to "next".
* B has finished. It has been fully merged up to "master" and "next",
and is ready to be deleted.
* C has not merged to "next" at all.
We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.
To compute (1):
git rev-list ^master ^topic next
git rev-list ^master next
if these match, topic has not merged in next at all.
To compute (2):
git rev-list master..topic
if this is empty, it is fully merged to "master".
DOC_END

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#
# An example hook script to make use of push options.
# The example simply echoes all push options that start with 'echoback='
# and rejects all pushes when the "reject" push option is used.
#
# To enable this hook, rename this file to "pre-receive".
if test -n "$GIT_PUSH_OPTION_COUNT"
then
i=0
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
do
eval "value=\$GIT_PUSH_OPTION_$i"
case "$value" in
echoback=*)
echo "echo from the pre-receive-hook: ${value#*=}" >&2
;;
reject)
exit 1
esac
i=$((i + 1))
done
fi

View File

@@ -0,0 +1,42 @@
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source. The hook's purpose is to edit the commit
# message file. If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".
# This hook includes three examples. The first one removes the
# "# Please enter the commit message..." help message.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output. It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited. This is rarely a good idea.
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
# case "$COMMIT_SOURCE,$SHA1" in
# ,|template,)
# /usr/bin/perl -i.bak -pe '
# print "\n" . `git diff --cached --name-status -r`
# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
# *) ;;
# esac
# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
# if test -z "$COMMIT_SOURCE"
# then
# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
# fi

View File

@@ -0,0 +1,128 @@
#!/bin/sh
#
# An example hook script to block unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
# This boolean sets whether unannotated tags will be allowed into the
# repository. By default they won't be.
# hooks.allowdeletetag
# This boolean sets whether deleting tags will be allowed in the
# repository. By default they won't be.
# hooks.allowmodifytag
# This boolean sets whether a tag may be modified after creation. By default
# it won't be.
# hooks.allowdeletebranch
# This boolean sets whether deleting branches will be allowed in the
# repository. By default they won't be.
# hooks.denycreatebranch
# This boolean sets whether remotely creating branches will be denied
# in the repository. By default this is allowed.
#
# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"
# --- Safety check
if [ -z "$GIT_DIR" ]; then
echo "Don't run this script from the command line." >&2
echo " (if you want, you could supply GIT_DIR then run" >&2
echo " $0 <ref> <oldrev> <newrev>)" >&2
exit 1
fi
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
exit 1
fi
# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)
# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
echo "*** Project description file hasn't been set" >&2
exit 1
;;
esac
# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
newrev_type=delete
else
newrev_type=$(git cat-file -t $newrev)
fi
case "$refname","$newrev_type" in
refs/tags/*,commit)
# un-annotated tag
short_refname=${refname##refs/tags/}
if [ "$allowunannotated" != "true" ]; then
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
exit 1
fi
;;
refs/tags/*,delete)
# delete tag
if [ "$allowdeletetag" != "true" ]; then
echo "*** Deleting a tag is not allowed in this repository" >&2
exit 1
fi
;;
refs/tags/*,tag)
# annotated tag
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
then
echo "*** Tag '$refname' already exists." >&2
echo "*** Modifying a tag is not allowed in this repository." >&2
exit 1
fi
;;
refs/heads/*,commit)
# branch
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
echo "*** Creating a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/heads/*,delete)
# delete branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/remotes/*,commit)
# tracking branch
;;
refs/remotes/*,delete)
# delete tracking branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
exit 1
fi
;;
*)
# Anything else (is there anything else?)
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
exit 1
;;
esac
# --- Finished
exit 0

View File

@@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

View File

@@ -0,0 +1,9 @@
0000000000000000000000000000000000000000 c6d238085f11a086b62813da5d08cd90310da5ea Marcin Grzejszczak <marcin@grzejszczak.pl> 1549274693 +0100 clone: from git@github.com:spring-cloud/spring-cloud-stream
c6d238085f11a086b62813da5d08cd90310da5ea a8cbf7779458bf72b4e2439136299c33eb797697 Marcin Grzejszczak <marcin@grzejszczak.pl> 1549292135 +0100 commit: Added checkstyle
a8cbf7779458bf72b4e2439136299c33eb797697 070ab0adfa59e54951f6b759d930f5da1e9f218b Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590477 +0100 pull --rebase origin master: Fast-forward
070ab0adfa59e54951f6b759d930f5da1e9f218b 7b980d7644c03e913963daf46d74476ee881eea6 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590489 +0100 checkout: moving from master to gh-pages
7b980d7644c03e913963daf46d74476ee881eea6 6b970b1d0ed73ee4da171c19ee2d004c629570df Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590494 +0100 pull --rebase origin gh-pages: Fast-forward
6b970b1d0ed73ee4da171c19ee2d004c629570df 070ab0adfa59e54951f6b759d930f5da1e9f218b Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619375 +0100 checkout: moving from gh-pages to master
070ab0adfa59e54951f6b759d930f5da1e9f218b 6b970b1d0ed73ee4da171c19ee2d004c629570df Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619382 +0100 checkout: moving from master to gh-pages
6b970b1d0ed73ee4da171c19ee2d004c629570df 3e7f960197e196ec9a2f536711a97cc7cfc7e45d Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619390 +0100 pull --rebase origin gh-pages: Fast-forward
3e7f960197e196ec9a2f536711a97cc7cfc7e45d 070ab0adfa59e54951f6b759d930f5da1e9f218b Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619397 +0100 checkout: moving from gh-pages to master

View File

@@ -0,0 +1,3 @@
0000000000000000000000000000000000000000 7b980d7644c03e913963daf46d74476ee881eea6 Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590489 +0100 branch: Created from refs/remotes/origin/gh-pages
7b980d7644c03e913963daf46d74476ee881eea6 6b970b1d0ed73ee4da171c19ee2d004c629570df Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590494 +0100 pull --rebase origin gh-pages: Fast-forward
6b970b1d0ed73ee4da171c19ee2d004c629570df 3e7f960197e196ec9a2f536711a97cc7cfc7e45d Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619390 +0100 pull --rebase origin gh-pages: Fast-forward

View File

@@ -0,0 +1,3 @@
0000000000000000000000000000000000000000 c6d238085f11a086b62813da5d08cd90310da5ea Marcin Grzejszczak <marcin@grzejszczak.pl> 1549274693 +0100 clone: from git@github.com:spring-cloud/spring-cloud-stream
c6d238085f11a086b62813da5d08cd90310da5ea a8cbf7779458bf72b4e2439136299c33eb797697 Marcin Grzejszczak <marcin@grzejszczak.pl> 1549292135 +0100 commit: Added checkstyle
a8cbf7779458bf72b4e2439136299c33eb797697 070ab0adfa59e54951f6b759d930f5da1e9f218b Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590477 +0100 pull --rebase origin master: Fast-forward

View File

@@ -0,0 +1 @@
0000000000000000000000000000000000000000 c6d238085f11a086b62813da5d08cd90310da5ea Marcin Grzejszczak <marcin@grzejszczak.pl> 1549274693 +0100 clone: from git@github.com:spring-cloud/spring-cloud-stream

View File

@@ -0,0 +1,2 @@
7b980d7644c03e913963daf46d74476ee881eea6 6b970b1d0ed73ee4da171c19ee2d004c629570df Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590494 +0100 pull --rebase origin gh-pages: fast-forward
6b970b1d0ed73ee4da171c19ee2d004c629570df 3e7f960197e196ec9a2f536711a97cc7cfc7e45d Marcin Grzejszczak <marcin@grzejszczak.pl> 1553619390 +0100 pull --rebase origin gh-pages: fast-forward

View File

@@ -0,0 +1,2 @@
c6d238085f11a086b62813da5d08cd90310da5ea a8cbf7779458bf72b4e2439136299c33eb797697 Marcin Grzejszczak <marcin@grzejszczak.pl> 1549292142 +0100 update by push
a8cbf7779458bf72b4e2439136299c33eb797697 070ab0adfa59e54951f6b759d930f5da1e9f218b Marcin Grzejszczak <marcin@grzejszczak.pl> 1553590477 +0100 pull --rebase origin master: fast-forward

View File

@@ -0,0 +1,2 @@
x+)JMU052a040031QpL*.)JL.q<><71>KI-
I-.)<29><>J,Kd(K8a<1D><><61><D6AA>/<2F>L<EFBFBD>[<5B><><>' ?''1)'<27>9?<3F><>4<17>bĈ$<24><>MM'<27><><EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD><76>G<EFBFBD>r4#@"kY<6B>Tv<54> <09>?<3F>?<3F><><hf׷<66>[s<>:T …<>ye<79>E<EFBFBD>y<EFBFBD><79>y%<01><>%E<>ɩ<EFBFBD><C9A9><EFBFBD>E[N<16>Q<EFBFBD>)<29><><EFBFBD>tk<74>r<EFBFBD><72>g<EFBFBD>%cZ<><5A><03>(<28><>f<EFBFBD>s<EFBFBD>ߞ<EFBFBD><DF9E>77n'o(<28><>ȭӡ<C8AD><12>J2K2<4B><32><EFBFBD> @E8<01><><EFBFBD><01>K<15>f/J,}*r<><72><EFBFBD>ʻ<EFBFBD>A<EFBFBD><41>zA^ .-(<28>/*<2A>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%<25>57[<5B>r=<3D>'[m<><6D>TSpjQfbNf<15>2<EFBFBD><32>|<7C><><EFBFBD><EFBFBD>'<27>'<27><>s~><3E>><3E>mwԅk<1F><>TB<54>L<EFBFBD>p7ښ3<DA9A><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IbjO<6A>w?υ<>ُ<><D98F>7<EFBFBD>w<EFBFBD><77><EFBFBD>\<5C>#<23>\{<7B><>?<3F><>Y<05><01><>i

Some files were not shown because too many files have changed in this diff Show More