Added checkstyle rules

This commit is contained in:
Marcin Grzejszczak
2019-02-07 15:03:44 +01:00
parent ddd9961120
commit 999fb6c9e8
157 changed files with 6633 additions and 3477 deletions

View File

@@ -3,7 +3,7 @@ jobs:
build:
docker:
- image: springcloud/pipeline-base
# user: appuser
# user: appuser
environment:
_JAVA_OPTIONS: "-Xms1024m -Xmx2048m"
TERM: dumb
@@ -43,4 +43,4 @@ jobs:
destination: artifacts
- store_test_results:
path: ~/junit/
destination: testartifacts
destination: testartifacts

18
.editorconfig Normal file
View File

@@ -0,0 +1,18 @@
# 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
[*.yaml]
indent_style = space
indent_size = 2

3
.gitignore vendored
View File

@@ -14,4 +14,5 @@ _site/
.factorypath
*.swp
/consul
consul_*.zip
consul_*.zip
consul_*.zip.*

117
.mvn/wrapper/MavenWrapperDownloader.java vendored Executable file
View File

@@ -0,0 +1,117 @@
/*
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
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.
*/
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();
}
}

BIN
.mvn/wrapper/maven-wrapper.jar vendored Normal file → Executable file

Binary file not shown.

2
.mvn/wrapper/maven-wrapper.properties vendored Normal file → Executable file
View File

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

View File

@@ -10,7 +10,9 @@
<profiles>
<profile>
<id>spring</id>
<activation><activeByDefault>true</activeByDefault></activation>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>spring-snapshots</id>

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>
<parent>

177
mvnw vendored
View File

@@ -54,38 +54,16 @@ case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
#
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
# for the new JDKs provided by Oracle.
#
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
#
# Oracle JDKs
#
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
#
# Apple JDKs
#
export JAVA_HOME=`/usr/libexec/java_home`
fi
;;
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
@@ -130,7 +108,7 @@ if $cygwin ; then
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Migwn, ensure paths are in UNIX format before anything is touched
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
@@ -184,27 +162,28 @@ fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
local basedir=$(pwd)
local wdir=$(pwd)
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
wdir=$(cd "$wdir/.."; pwd)
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
@@ -216,38 +195,92 @@ concat_lines() {
fi
}
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
wget "$jarUrl" -O "$wrapperJarPath"
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
curl -o "$wrapperJarPath" "$jarUrl"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
echo "Running version check"
VERSION=$( sed '\!<parent!,\!</parent!d' `dirname $0`/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!' )
echo "The found version is [${VERSION}]"
if echo $VERSION | egrep -q 'M|RC'; then
echo Activating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
else
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
fi
if echo $VERSION | egrep -q 'RELEASE'; then
echo Activating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
else
echo Deactivating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
fi
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

161
mvnw.cmd vendored Executable file
View File

@@ -0,0 +1,161 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
echo Found %WRAPPER_JAR%
) else (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

37
pom.xml
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>
@@ -25,14 +25,24 @@
<spring-cloud-config.version>2.1.1.BUILD-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-netflix.version>2.1.1.BUILD-SNAPSHOT</spring-cloud-netflix.version>
<spring-cloud-deployer.version>1.0.3.RELEASE</spring-cloud-deployer.version>
<spring-cloud-openfeign.version>2.1.1.BUILD-SNAPSHOT</spring-cloud-openfeign.version>
<spring-cloud-openfeign.version>2.1.1.BUILD-SNAPSHOT
</spring-cloud-openfeign.version>
<spring-cloud-stream.version>Fishtown.BUILD-SNAPSHOT</spring-cloud-stream.version>
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError>
<maven-checkstyle-plugin.failsOnViolation>true
</maven-checkstyle-plugin.failsOnViolation>
<maven-checkstyle-plugin.includeTestSourceDirectory>true
</maven-checkstyle-plugin.includeTestSourceDirectory>
</properties>
<scm>
<url>https://github.com/spring-cloud/spring-cloud-consul</url>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-consul.git</connection>
<developerConnection>scm:git:ssh://git@github.com/spring-cloud/spring-cloud-consul.git</developerConnection>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-consul.git
</connection>
<developerConnection>
scm:git:ssh://git@github.com/spring-cloud/spring-cloud-consul.git
</developerConnection>
<tag>HEAD</tag>
</scm>
@@ -62,9 +72,26 @@
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</reporting>
<dependencyManagement>
<dependencies>
<dependency>

View File

@@ -1,5 +1,6 @@
#!/bin/bash
trap 'pkill -9 consul; EXIT' 0
./src/main/bash/travis_install_consul.sh
./src/test/bash/travis_run_consul.sh
./mvnw clean install -B -Pdocs ${@}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,8 @@ import org.springframework.util.Assert;
/**
* @author Spencer Gibb
*/
public class ConsulBinder extends AbstractBinder<MessageChannel, ConsumerProperties, ProducerProperties> {
public class ConsulBinder
extends AbstractBinder<MessageChannel, ConsumerProperties, ProducerProperties> {
private static final String BEAN_NAME_TEMPLATE = "outbound.%s";
@@ -40,8 +41,10 @@ public class ConsulBinder extends AbstractBinder<MessageChannel, ConsumerPropert
}
@Override
protected Binding<MessageChannel> doBindConsumer(String name, String group, MessageChannel inputChannel, ConsumerProperties properties) {
ConsulInboundMessageProducer messageProducer = new ConsulInboundMessageProducer(this.eventService);
protected Binding<MessageChannel> doBindConsumer(String name, String group,
MessageChannel inputChannel, ConsumerProperties properties) {
ConsulInboundMessageProducer messageProducer = new ConsulInboundMessageProducer(
this.eventService);
messageProducer.setOutputChannel(inputChannel);
messageProducer.setBeanFactory(this.getBeanFactory());
messageProducer.afterPropertiesSet();
@@ -51,13 +54,16 @@ public class ConsulBinder extends AbstractBinder<MessageChannel, ConsumerPropert
}
@Override
protected Binding<MessageChannel> doBindProducer(String name, MessageChannel channel, ProducerProperties properties) {
protected Binding<MessageChannel> doBindProducer(String name, MessageChannel channel,
ProducerProperties properties) {
Assert.isInstanceOf(SubscribableChannel.class, channel);
logger.debug("Binding Consul client to eventName " + name);
ConsulSendingHandler sendingHandler = new ConsulSendingHandler(this.eventService.getConsulClient(), name);
this.logger.debug("Binding Consul client to eventName " + name);
ConsulSendingHandler sendingHandler = new ConsulSendingHandler(
this.eventService.getConsulClient(), name);
EventDrivenConsumer consumer = new EventDrivenConsumer((SubscribableChannel) channel, sendingHandler);
EventDrivenConsumer consumer = new EventDrivenConsumer(
(SubscribableChannel) channel, sendingHandler);
consumer.setBeanFactory(getBeanFactory());
consumer.setBeanName(String.format(BEAN_NAME_TEMPLATE, name));
consumer.afterPropertiesSet();
@@ -65,4 +71,5 @@ public class ConsulBinder extends AbstractBinder<MessageChannel, ConsumerPropert
return new DefaultBinding<>(name, null, channel, consumer);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
package org.springframework.cloud.consul.binder;
import static org.springframework.util.Base64Utils.decodeFromString;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -25,24 +23,31 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import com.ecwid.consul.v1.OperationException;
import com.ecwid.consul.v1.event.model.Event;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.endpoint.MessageProducerSupport;
import com.ecwid.consul.v1.event.model.Event;
import static org.springframework.util.Base64Utils.decodeFromString;
/**
* Adapter that receives Messages from Consul Events, converts them into Spring
* Integration Messages, and sends the results to a Message Channel.
*
* @author Spencer Gibb
*/
public class ConsulInboundMessageProducer extends MessageProducerSupport {
protected static final Log logger = LogFactory.getLog(ConsulInboundMessageProducer.class);
protected static final Log logger = LogFactory
.getLog(ConsulInboundMessageProducer.class);
private final ScheduledExecutorService scheduler;
private final Runnable eventsRunnable;
private EventService eventService;
private final ScheduledExecutorService scheduler;
private final Runnable eventsRunnable;
private ScheduledFuture<?> eventsHandle;
public ConsulInboundMessageProducer(EventService eventService) {
@@ -75,8 +80,9 @@ public class ConsulInboundMessageProducer extends MessageProducerSupport {
@Override
protected void doStart() {
//TODO: make configurable
eventsHandle = this.scheduler.scheduleWithFixedDelay(eventsRunnable, 500, 500, TimeUnit.MILLISECONDS);
// TODO: make configurable
this.eventsHandle = this.scheduler.scheduleWithFixedDelay(this.eventsRunnable,
500, 500, TimeUnit.MILLISECONDS);
}
@Override
@@ -90,20 +96,22 @@ public class ConsulInboundMessageProducer extends MessageProducerSupport {
// @Scheduled(fixedDelayString = "${spring.cloud.consul.binder.eventDelay:30000}")
public void getEvents() {
try {
List<Event> events = eventService.watch();
List<Event> events = this.eventService.watch();
for (Event event : events) {
// Map<String, Object> headers = new HashMap<>();
// headers.put(MessageHeaders.REPLY_CHANNEL, outputChannel.)
String decoded = new String(decodeFromString(event.getPayload()));
sendMessage(getMessageBuilderFactory().withPayload(decoded)
// TODO: support headers
// TODO: support headers
.build());
}
} catch (OperationException e) {
}
catch (OperationException e) {
if (logger.isErrorEnabled()) {
logger.error("Error getting consul events: " + e);
}
} catch (Exception e) {
}
catch (Exception e) {
if (logger.isErrorEnabled()) {
logger.error("Error getting consul events: " + e.getMessage());
}
@@ -112,4 +120,5 @@ public class ConsulInboundMessageProducer extends MessageProducerSupport {
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,23 +16,24 @@
package org.springframework.cloud.consul.binder;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.messaging.Message;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.event.model.Event;
import com.ecwid.consul.v1.event.model.EventParams;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.messaging.Message;
/**
* Adapter that converts and sends Messages as Consul events
* Adapter that converts and sends Messages as Consul events.
*
* @author Spencer Gibb
*/
public class ConsulSendingHandler extends AbstractMessageHandler {
private final ConsulClient consul;
private final String eventName;
public ConsulSendingHandler(ConsulClient consul, String eventName) {
@@ -42,16 +43,17 @@ public class ConsulSendingHandler extends AbstractMessageHandler {
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("Publishing message" + message);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Publishing message" + message);
}
Object payload = message.getPayload();
// TODO: support headers
// TODO: support consul event filters: NodeFilter, ServiceFilter, TagFilter
Response<Event> event = consul.eventFire(this.eventName, (String) payload,
Response<Event> event = this.consul.eventFire(this.eventName, (String) payload,
new EventParams(), QueryParams.DEFAULT);
// TODO: return event?
// return null;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,6 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.PostConstruct;
import org.springframework.cloud.consul.binder.config.ConsulBinderProperties;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
@@ -30,6 +28,8 @@ import com.ecwid.consul.v1.event.model.Event;
import com.ecwid.consul.v1.event.model.EventParams;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cloud.consul.binder.config.ConsulBinderProperties;
/**
* @author Spencer Gibb
*/
@@ -43,14 +43,15 @@ public class EventService {
private AtomicReference<Long> lastIndex = new AtomicReference<>();
public EventService(ConsulBinderProperties properties, ConsulClient consul, ObjectMapper objectMapper) {
public EventService(ConsulBinderProperties properties, ConsulClient consul,
ObjectMapper objectMapper) {
this.properties = properties;
this.consul = consul;
this.objectMapper = objectMapper;
}
public ConsulClient getConsulClient() {
return consul;
return this.consul;
}
@PostConstruct
@@ -58,25 +59,25 @@ public class EventService {
setLastIndex(getEventsResponse());
}
public Long getLastIndex() {
return this.lastIndex.get();
}
private void setLastIndex(Response<?> response) {
Long consulIndex = response.getConsulIndex();
if (consulIndex != null) {
lastIndex.set(response.getConsulIndex());
this.lastIndex.set(response.getConsulIndex());
}
}
public Long getLastIndex() {
return lastIndex.get();
}
public Event fire(String name, String payload) {
Response<Event> response = consul.eventFire(name, payload, new EventParams(),
Response<Event> response = this.consul.eventFire(name, payload, new EventParams(),
QueryParams.DEFAULT);
return response.getValue();
}
public Response<List<Event>> getEventsResponse() {
return consul.eventList(QueryParams.DEFAULT);
return this.consul.eventList(QueryParams.DEFAULT);
}
public List<Event> getEvents() {
@@ -88,7 +89,7 @@ public class EventService {
}
public List<Event> watch() {
return watch(lastIndex.get());
return watch(this.lastIndex.get());
}
public List<Event> watch(Long lastIndex) {
@@ -98,10 +99,11 @@ public class EventService {
index = lastIndex;
}
int eventTimeout = 5;
if (properties != null) {
eventTimeout = properties.getEventTimeout();
if (this.properties != null) {
eventTimeout = this.properties.getEventTimeout();
}
Response<List<Event>> watch = consul.eventList(new QueryParams(eventTimeout, index));
Response<List<Event>> watch = this.consul
.eventList(new QueryParams(eventTimeout, index));
return filterEvents(readEvents(watch), lastIndex);
}
@@ -111,7 +113,10 @@ public class EventService {
}
/**
* from https://github.com/hashicorp/consul/blob/master/watch/funcs.go#L169-L194
* from https://github.com/hashicorp/consul/blob/master/watch/funcs.go#L169-L194 .
* @param toFilter events to filter
* @param lastIndex last index to pick from the list of events
* @return filtered list of events
*/
protected List<Event> filterEvents(List<Event> toFilter, Long lastIndex) {
List<Event> events = toFilter;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,13 @@
package org.springframework.cloud.consul.binder.config;
import com.ecwid.consul.v1.ConsulClient;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.consul.ConditionalOnConsulEnabled;
import org.springframework.cloud.consul.binder.ConsulBinder;
import org.springframework.cloud.consul.binder.EventService;
@@ -29,9 +31,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import com.ecwid.consul.v1.ConsulClient;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Configures the Consul binder.
*
@@ -42,7 +41,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
@Import({ PropertyPlaceholderAutoConfiguration.class })
@ConditionalOnConsulEnabled
@ConditionalOnProperty(name = "spring.cloud.consul.binder.enabled", matchIfMissing = true)
//FIXME: boot 2.0.0 @EnableConfigurationProperties({ConsulBinderProperties.class})
// FIXME: boot 2.0.0 @EnableConfigurationProperties({ConsulBinderProperties.class})
public class ConsulBinderConfiguration {
// @Autowired
@@ -54,7 +53,8 @@ public class ConsulBinderConfiguration {
@Bean
@ConditionalOnMissingBean
public EventService eventService(ConsulClient consulClient) {
return new EventService(null/*consulBinderProperties*/, consulClient, objectMapper);
return new EventService(null/* consulBinderProperties */, consulClient,
this.objectMapper);
}
@Bean
@@ -63,5 +63,6 @@ public class ConsulBinderConfiguration {
return new ConsulBinder(eventService);
}
//TODO: create consul client if needed
// TODO: create consul client if needed
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import org.springframework.core.style.ToStringCreator;
*/
@ConfigurationProperties("spring.cloud.stream.consul.binder")
public class ConsulBinderProperties {
private int eventTimeout = 5;
public ConsulBinderProperties() {
@@ -39,8 +40,8 @@ public class ConsulBinderProperties {
@Override
public String toString() {
return new ToStringCreator(this)
.append("eventTimeout", eventTimeout)
return new ToStringCreator(this).append("eventTimeout", this.eventTimeout)
.toString();
}
}

View File

@@ -13,6 +13,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
spring.cloud.stream.binder.consul.default.host=localhost
spring.cloud.stream.binder.consul.default.port=8500

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,11 +18,14 @@ package org.springframework.cloud.consul.binder;
import java.util.concurrent.TimeUnit;
import com.ecwid.consul.v1.ConsulClient;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -36,19 +39,17 @@ import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.ecwid.consul.v1.ConsulClient;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.put;
import static com.github.tomakehurst.wiremock.client.WireMock.putRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD;
/**
* @author Spencer Gibb
*/
@@ -56,33 +57,35 @@ import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER
@SpringBootTest(classes = ConsulBinderApplicationTests.Application.class)
@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
public class ConsulBinderApplicationTests {
@Autowired
private Events events;
@Rule
public final WireMockRule wireMock = new WireMockRule(18500);
@Autowired
private Events events;
@Before
public void setUp() throws Exception {
wireMock.stubFor(put(urlPathMatching("/v1/event/fire/purchases"))
this.wireMock.stubFor(put(urlPathMatching("/v1/event/fire/purchases"))
.willReturn(aResponse().withStatus(200)));
/*wireMock.stubFor(get(urlPathMatching("/v1/event/list"))
.willReturn(aResponse().withBody("[]")
.withStatus(200)
.withHeader("X-Consul-Index", "1")));*/
/*
* wireMock.stubFor(get(urlPathMatching("/v1/event/list"))
* .willReturn(aResponse().withBody("[]") .withStatus(200)
* .withHeader("X-Consul-Index", "1")));
*/
}
@Test
@Ignore //FIXME: 2.0.0 need stream fix
@Ignore // FIXME: 2.0.0 need stream fix
public void shouldInitializeConsulSource() {
assertNotNull(events);
assertThat(this.events).isNotNull();
}
@Test
@Ignore //FIXME: 2.0.0 need stream fix
@Ignore // FIXME: 2.0.0 need stream fix
public void shouldPublishTextConsulMessage() {
// given
@@ -90,7 +93,7 @@ public class ConsulBinderApplicationTests {
.build();
// when
events.purchases().send(message);
this.events.purchases().send(message);
// then
await().atMost(1, TimeUnit.SECONDS);
@@ -101,12 +104,14 @@ public class ConsulBinderApplicationTests {
@Output
MessageChannel purchases();
}
@Configuration
@EnableAutoConfiguration
@EnableBinding(Events.class)
public static class Application {
@Bean
public ConsulClient consulClient() {
return new ConsulClient("localhost", 18500);
@@ -118,5 +123,7 @@ public class ConsulBinderApplicationTests {
when(eventService.getConsulClient()).thenReturn(consulClient);
return eventService;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.consul.binder.test.consumer.TestConsumer;
import org.springframework.cloud.consul.binder.test.producer.TestProducer;
import org.springframework.cloud.deployer.spi.app.AppDeployer;
@@ -40,8 +41,7 @@ import org.springframework.util.SocketUtils;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link org.springframework.cloud.consul.binder.ConsulBinder}.
@@ -49,12 +49,6 @@ import static org.junit.Assert.assertTrue;
* @author Spencer Gibb
*/
public class ConsulBinderTests {
private static final Logger logger = LoggerFactory.getLogger(ConsulBinderTests.class);
/**
* Timeout value in milliseconds for operations to complete.
*/
private static final long TIMEOUT = 30000;
/**
* Payload of test message.
@@ -66,6 +60,13 @@ public class ConsulBinderTests {
*/
public static final String BINDING_NAME = "test";
private static final Logger logger = LoggerFactory.getLogger(ConsulBinderTests.class);
/**
* Timeout value in milliseconds for operations to complete.
*/
private static final long TIMEOUT = 30000;
/**
* Deployer to launch producer and consumer test applications.
*/
@@ -76,7 +77,6 @@ public class ConsulBinderTests {
*/
private final RestTemplate restTemplate = new RestTemplate();
public ConsulBinderTests() {
LocalDeployerProperties properties = new LocalDeployerProperties();
properties.setDeleteFilesOnExit(false);
@@ -85,43 +85,38 @@ public class ConsulBinderTests {
/**
* Test basic message sending functionality.
*
* @throws Exception
* @throws InterruptedException when waiting for message was interrupted
*/
@Test
@Ignore //FIXME: 2.0.0 need stream fix
public void testMessageSendReceive() throws Exception {
@Ignore // FIXME: 2.0.0 need stream fix
public void testMessageSendReceive() throws InterruptedException {
testMessageSendReceive(null);
}
/**
* Test usage of partition selector.
*
* @throws Exception
*/
/*@Test
public void testPartitionedMessageSendReceive() throws Exception {
testMessageSendReceive(null, true);
}*/
/*
* @Test public void testPartitionedMessageSendReceive() throws Exception {
* testMessageSendReceive(null, true); }
*/
/**
* Test consumer group functionality.
*
* @throws Exception
*/
/*@Test
public void testMessageSendReceiveConsumerGroups() throws Exception {
testMessageSendReceive(new String[]{"a", "b"}, false);
}*/
/*
* @Test public void testMessageSendReceiveConsumerGroups() throws Exception {
* testMessageSendReceive(new String[]{"a", "b"}, false); }
*/
/**
* Test message sending functionality.
*
* @param groups consumer groups; may be {@code null}
* @param partitioned if true, execute test with a partition selector
* @throws Exception
* @throws InterruptedException when waiting for message was interrupted
*/
private void testMessageSendReceive(String[] groups) throws Exception {
private void testMessageSendReceive(String[] groups) throws InterruptedException {
Set<AppId> consumers = null;
AppId producer = null;
@@ -130,7 +125,7 @@ public class ConsulBinderTests {
producer = launchProducer();
for (AppId consumer : consumers) {
assertEquals(MESSAGE_PAYLOAD, waitForMessage(consumer.port));
assertThat(waitForMessage(consumer.port)).isEqualTo(MESSAGE_PAYLOAD);
}
}
finally {
@@ -146,12 +141,11 @@ public class ConsulBinderTests {
}
/**
* Launch one or more consumers based on the number of consumer groups.
* Blocks execution until the consumers are bound.
*
* Launch one or more consumers based on the number of consumer groups. Blocks
* execution until the consumers are bound.
* @param groups consumer groups; may be {@code null}
* @return a set of {@link AppId}s for the consumers
* @throws InterruptedException
* @throws InterruptedException when waiting for message was interrupted
*/
private Set<AppId> launchConsumers(String[] groups) throws InterruptedException {
Set<AppId> consumers = new HashSet<>();
@@ -170,7 +164,9 @@ public class ConsulBinderTests {
if (groups != null) {
args.add(String.format("--group=%s", groups[i]));
}
consumers.add(new AppId(launchApplication(TestConsumer.class, appProperties, args), consumerPort));
consumers.add(
new AppId(launchApplication(TestConsumer.class, appProperties, args),
consumerPort));
}
for (AppId app : consumers) {
waitForConsumer(app.port);
@@ -181,7 +177,6 @@ public class ConsulBinderTests {
/**
* Launch a producer that publishes a test message.
*
* @return {@link AppId} for producer
*/
private AppId launchProducer() {
@@ -196,16 +191,16 @@ public class ConsulBinderTests {
args.add(String.format("--partitioned=%b", false));
args.add("--debug");
return new AppId(launchApplication(TestProducer.class, appProperties, args), producerPort);
return new AppId(launchApplication(TestProducer.class, appProperties, args),
producerPort);
}
/**
* Block the executing thread until the consumer is bound.
*
* @param port server port of the consumer application
* @throws InterruptedException if the thread is interrupted
* @throws AssertionError if the consumer is not bound after
* {@value #TIMEOUT} milliseconds
* @throws AssertionError if the consumer is not bound after {@value #TIMEOUT}
* milliseconds
*/
private void waitForConsumer(int port) throws InterruptedException {
long start = System.currentTimeMillis();
@@ -217,18 +212,17 @@ public class ConsulBinderTests {
Thread.sleep(1000);
}
}
assertTrue("Consumer not bound", isConsumerBound(port));
assertThat(isConsumerBound(port)).as("Consumer not bound").isTrue();
}
/**
* Return {@code true} if the consumer at the provided port is bound.
*
* @param port http port for consumer
* @return true if consumer is bound
*/
private boolean isConsumerBound(int port) {
try {
return restTemplate.getForObject(
return this.restTemplate.getForObject(
String.format("http://localhost:%d/is-bound", port), Boolean.class);
}
catch (ResourceAccessException e) {
@@ -239,15 +233,14 @@ public class ConsulBinderTests {
/**
* Return the most recent payload message a consumer received.
*
* @param port http port for consumer
* @return the most recent payload message a consumer received;
* may be {@code null}
* @return the most recent payload message a consumer received; may be {@code null}
*/
private String getConsumerMessagePayload(int port) {
try {
return restTemplate.getForObject(
String.format("http://localhost:%d/message-payload", port), String.class);
return this.restTemplate.getForObject(
String.format("http://localhost:%d/message-payload", port),
String.class);
}
catch (ResourceAccessException e) {
logger.debug("getConsumerMessagePayload", e);
@@ -257,13 +250,12 @@ public class ConsulBinderTests {
/**
* Return {@code true} if the producer made use of a custom partition selector.
*
* @param port http port for producer
* @return true if the producer used a custom partition selector
*/
private boolean partitionSelectorUsed(int port) throws InterruptedException {
private boolean partitionSelectorUsed(int port) {
try {
return restTemplate.getForObject(
return this.restTemplate.getForObject(
String.format("http://localhost:%d/partition-strategy-invoked", port),
Boolean.class);
}
@@ -274,9 +266,8 @@ public class ConsulBinderTests {
}
/**
* Block the executing thread until a message is received by the
* consumer application, or until {@value #TIMEOUT} milliseconds elapses.
*
* Block the executing thread until a message is received by the consumer application,
* or until {@value #TIMEOUT} milliseconds elapses.
* @param port server port of the consumer application
* @return the message payload that was received
* @throws InterruptedException if the thread is interrupted
@@ -298,29 +289,31 @@ public class ConsulBinderTests {
/**
* Launch an application in a separate JVM.
*
* @param clz the main class to launch
* @param properties the properties to pass to the application
* @param args the command line arguments for the application
* @return a string identifier for the application
*/
private String launchApplication(Class<?> clz, Map<String, String> properties, List<String> args) {
Resource resource = new UrlResource(clz.getProtectionDomain().getCodeSource().getLocation());
private String launchApplication(Class<?> clz, Map<String, String> properties,
List<String> args) {
Resource resource = new UrlResource(
clz.getProtectionDomain().getCodeSource().getLocation());
properties.put(AppDeployer.GROUP_PROPERTY_KEY, "test-group");
properties.put("main", clz.getName());
properties.put("classpath", System.getProperty("java.class.path"));
String appName = String.format("%s-%s", clz.getSimpleName(), properties.get("server.port"));
String appName = String.format("%s-%s", clz.getSimpleName(),
properties.get("server.port"));
AppDefinition definition = new AppDefinition(appName, properties);
AppDeploymentRequest request = new AppDeploymentRequest(definition, resource, properties, args);
AppDeploymentRequest request = new AppDeploymentRequest(definition, resource,
properties, args);
return this.deployer.deploy(request);
}
/**
* Shut down the application with the provided id.
*
* @param id id of application to shut down
*/
private void shutdownApplication(String id) {
@@ -331,7 +324,6 @@ public class ConsulBinderTests {
/**
* Instantiates a new local app deployer.
*
* @param properties the properties
*/
ClasspathDeployer(LocalDeployerProperties properties) {
@@ -340,12 +332,12 @@ public class ConsulBinderTests {
/**
* Builds the jar execution command.
*
* @param jarPath the jar path
* @param request the request
* @return the string[]
*/
protected String[] buildJarExecutionCommand(String jarPath, AppDeploymentRequest request) {
protected String[] buildJarExecutionCommand(String jarPath,
AppDeploymentRequest request) {
ArrayList<String> commands = new ArrayList<>();
commands.add(super.getLocalDeployerProperties().getJavaCmd());
@@ -356,14 +348,16 @@ public class ConsulBinderTests {
return commands.toArray(new String[commands.size()]);
}
}
}
/**
* String identification and http port for a launched application.
*/
private static class AppId {
final String id;
final int port;
AppId(String id, int port) {
@@ -381,15 +375,16 @@ public class ConsulBinderTests {
}
AppId appId = (AppId) o;
return port == appId.port && id.equals(appId.id);
return this.port == appId.port && this.id.equals(appId.id);
}
@Override
public int hashCode() {
int result = id.hashCode();
result = 31 * result + port;
int result = this.id.hashCode();
result = 31 * result + this.port;
return result;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,10 @@
package org.springframework.cloud.consul.binder;
import com.ecwid.consul.v1.OperationException;
import org.junit.Test;
import com.ecwid.consul.v1.OperationException;
import static org.junit.Assert.fail;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -34,15 +33,16 @@ public class ConsulInboundMessageProducerTests {
EventService eventService = mock(EventService.class);
when(eventService.watch()).thenThrow(new OperationException(500, "error", ""));
ConsulInboundMessageProducer producer = new ConsulInboundMessageProducer(eventService);
ConsulInboundMessageProducer producer = new ConsulInboundMessageProducer(
eventService);
try {
producer.getEvents();
} catch (Exception e) {
fail("ConsulInboundMessageProducer threw unexpected exception: "+e);
}
catch (Exception e) {
fail("ConsulInboundMessageProducer threw unexpected exception: " + e);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.stream.annotation.EnableBinding;
@@ -38,31 +39,33 @@ public class ConsulBinderConfigurationTests {
public ExpectedException exception = ExpectedException.none();
@Test
@Ignore //FIXME 2.0.0 need stream fix
@Ignore // FIXME 2.0.0 need stream fix
public void consulBinderDisabledWorks() {
this.exception.expectMessage(containsString("no proper implementation found"));
new SpringApplicationBuilder(Application.class)
.properties("spring.cloud.consul.binder.enabled=false")
.run();
.properties("spring.cloud.consul.binder.enabled=false").run();
}
@Test
@Ignore //FIXME 2.0.0 need stream fix
@Ignore // FIXME 2.0.0 need stream fix
public void consulDisabledDisablesBinder() {
this.exception.expectMessage(containsString("no proper implementation found"));
new SpringApplicationBuilder(Application.class)
.properties("spring.cloud.consul.enabled=false")
.run();
.properties("spring.cloud.consul.enabled=false").run();
}
interface Events {
@Output
MessageChannel purchases();
}
@Configuration
@EnableAutoConfiguration
@EnableBinding(Events.class)
public static class Application {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.cloud.consul.binder.test.consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
@@ -27,7 +28,6 @@ import org.springframework.cloud.consul.binder.ConsulBinder;
import org.springframework.cloud.consul.binder.ConsulBinderTests;
import org.springframework.cloud.consul.binder.config.ConsulBinderConfiguration;
import org.springframework.cloud.stream.binder.ConsumerProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.messaging.Message;
@@ -39,14 +39,15 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Consumer application that binds a channel to a {@link ConsulBinder}
* and stores the received message payload.
* Consumer application that binds a channel to a {@link ConsulBinder} and stores the
* received message payload.
*/
@RestController
@Import(ConsulBinderConfiguration.class)
@Configuration
@EnableAutoConfiguration
public class TestConsumer implements ApplicationRunner {
private static final Logger logger = LoggerFactory.getLogger(TestConsumer.class);
/**
@@ -64,23 +65,21 @@ public class TestConsumer implements ApplicationRunner {
/**
* Main method.
*
* @param args if present, first arg is consumer group name
* @throws Exception
*/
public static void main(String[] args) throws Exception {
public static void main(String[] args) {
SpringApplication.run(TestConsumer.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
logger.info("Consumer running with binder {}", binder);
logger.info("Consumer running with binder {}", this.binder);
SubscribableChannel consumerChannel = new ExecutorSubscribableChannel();
consumerChannel.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
messagePayload = (String) message.getPayload();
logger.info("Received message: {}", messagePayload);
TestConsumer.this.messagePayload = (String) message.getPayload();
logger.info("Received message: {}", TestConsumer.this.messagePayload);
}
});
String group = null;
@@ -89,19 +88,19 @@ public class TestConsumer implements ApplicationRunner {
group = args.getOptionValues("group").get(0);
}
binder.bindConsumer(ConsulBinderTests.BINDING_NAME, group, consumerChannel,
this.binder.bindConsumer(ConsulBinderTests.BINDING_NAME, group, consumerChannel,
new ConsumerProperties());
isBound = true;
this.isBound = true;
}
@RequestMapping("/is-bound")
public boolean isBound() {
return isBound;
return this.isBound;
}
@RequestMapping("/message-payload")
public String getMessagePayload() {
return messagePayload;
return this.messagePayload;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.cloud.consul.binder.test.producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
@@ -40,8 +41,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Producer application that binds a channel to a {@link ConsulBinder}
* and sends a test message.
* Producer application that binds a channel to a {@link ConsulBinder} and sends a test
* message.
*/
@RestController
@Import(ConsulBinderConfiguration.class)
@@ -60,17 +61,20 @@ public class TestProducer implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
/*if (args.containsOption("partitioned")
&& Boolean.valueOf(args.getOptionValues("partitioned").get(0))) {
binder.setPartitionSelector(stubPartitionSelectorStrategy());
}*/
/*
* if (args.containsOption("partitioned") &&
* Boolean.valueOf(args.getOptionValues("partitioned").get(0))) {
* binder.setPartitionSelector(stubPartitionSelectorStrategy()); }
*/
SubscribableChannel producerChannel = producerChannel();
ProducerProperties properties = new ProducerProperties();
properties.setPartitionKeyExpression(new SpelExpressionParser().parseExpression("payload"));
binder.bindProducer(ConsulBinderTests.BINDING_NAME, producerChannel, properties);
properties.setPartitionKeyExpression(
new SpelExpressionParser().parseExpression("payload"));
this.binder.bindProducer(ConsulBinderTests.BINDING_NAME, producerChannel,
properties);
Message<String> message = new GenericMessage<>(ConsulBinderTests.MESSAGE_PAYLOAD);
logger.info("Writing message to binder {}", binder);
logger.info("Writing message to binder {}", this.binder);
producerChannel.send(message);
}
@@ -89,16 +93,19 @@ public class TestProducer implements ApplicationRunner {
return stubPartitionSelectorStrategy().invoked;
}
public static class StubPartitionSelectorStrategy
implements PartitionSelectorStrategy {
public static class StubPartitionSelectorStrategy implements PartitionSelectorStrategy {
public volatile boolean invoked = false;
@Override
public int selectPartition(Object key, int partitionCount) {
logger.info("Selecting partition for key {}; partition count: {}", key, partitionCount);
invoked = true;
logger.info("Selecting partition for key {}; partition count: {}", key,
partitionCount);
this.invoked = true;
return 1;
}
}
}

View File

@@ -1,4 +1,3 @@
spring:
cloud:
stream:

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,17 +50,33 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc
private static final Log log = LogFactory.getLog(ConfigWatch.class);
private final ConsulConfigProperties properties;
private final ConsulClient consul;
private LinkedHashMap<String, Long> consulIndexes;
private final TaskScheduler taskScheduler;
private final AtomicBoolean running = new AtomicBoolean(false);
private LinkedHashMap<String, Long> consulIndexes;
private ApplicationEventPublisher publisher;
private boolean firstTime = true;
private ScheduledFuture<?> watchFuture;
public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul, LinkedHashMap<String, Long> initialIndexes) {
public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul,
LinkedHashMap<String, Long> initialIndexes) {
this(properties, consul, initialIndexes, getTaskScheduler());
}
}
public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul,
LinkedHashMap<String, Long> initialIndexes, TaskScheduler taskScheduler) {
this.properties = properties;
this.consul = consul;
this.consulIndexes = new LinkedHashMap<>(initialIndexes);
this.taskScheduler = taskScheduler;
}
private static ThreadPoolTaskScheduler getTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
@@ -68,14 +84,6 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc
return taskScheduler;
}
public ConfigWatch(ConsulConfigProperties properties, ConsulClient consul, LinkedHashMap<String, Long> initialIndexes,
TaskScheduler taskScheduler) {
this.properties = properties;
this.consul = consul;
this.consulIndexes = new LinkedHashMap<>(initialIndexes);
this.taskScheduler = taskScheduler;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
@@ -84,8 +92,8 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc
@Override
public void start() {
if (this.running.compareAndSet(false, true)) {
this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(this::watchConfigKeyValues,
this.properties.getWatch().getDelay());
this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(
this::watchConfigKeyValues, this.properties.getWatch().getDelay());
}
}
@@ -117,13 +125,14 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc
return this.running.get();
}
@Timed(value ="consul.watch-config-keys")
@Timed("consul.watch-config-keys")
public void watchConfigKeyValues() {
if (this.running.get()) {
for (String context : this.consulIndexes.keySet()) {
// turn the context into a Consul folder path (unless our config format are FILES)
if (properties.getFormat() != FILES && !context.endsWith("/")) {
// turn the context into a Consul folder path (unless our config format
// are FILES)
if (this.properties.getFormat() != FILES && !context.endsWith("/")) {
context = context + "/";
}
@@ -133,63 +142,85 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc
currentIndex = -1L;
}
log.trace("watching consul for context '"+context+"' with index "+ currentIndex);
log.trace("watching consul for context '" + context + "' with index "
+ currentIndex);
// use the consul ACL token if found
String aclToken = properties.getAclToken();
String aclToken = this.properties.getAclToken();
if (StringUtils.isEmpty(aclToken)) {
aclToken = null;
aclToken = null;
}
Response<List<GetValue>> response = this.consul.getKVValues(context, aclToken,
Response<List<GetValue>> response = this.consul.getKVValues(context,
aclToken,
new QueryParams(this.properties.getWatch().getWaitTime(),
currentIndex));
// if response.value == null, response was a 404, otherwise it was a 200
// if response.value == null, response was a 404, otherwise it was a
// 200
// reducing churn if there wasn't anything
if (response.getValue() != null && !response.getValue().isEmpty()) {
Long newIndex = response.getConsulIndex();
if (newIndex != null && !newIndex.equals(currentIndex)) {
// don't publish the same index again, don't publish the first time (-1) so index can be primed
if (!this.consulIndexes.containsValue(newIndex) && !currentIndex.equals(-1L)) {
log.trace("Context "+context + " has new index " + newIndex);
RefreshEventData data = new RefreshEventData(context, currentIndex, newIndex);
this.publisher.publishEvent(new RefreshEvent(this, data, data.toString()));
} else if (log.isTraceEnabled()) {
log.trace("Event for index already published for context "+context);
// don't publish the same index again, don't publish the first
// time (-1) so index can be primed
if (!this.consulIndexes.containsValue(newIndex)
&& !currentIndex.equals(-1L)) {
log.trace("Context " + context + " has new index "
+ newIndex);
RefreshEventData data = new RefreshEventData(context,
currentIndex, newIndex);
this.publisher.publishEvent(
new RefreshEvent(this, data, data.toString()));
}
else if (log.isTraceEnabled()) {
log.trace("Event for index already published for context "
+ context);
}
this.consulIndexes.put(context, newIndex);
} else if (log.isTraceEnabled()) {
log.trace("Same index for context "+context);
}
} else if (log.isTraceEnabled()) {
log.trace("No value for context "+context);
else if (log.isTraceEnabled()) {
log.trace("Same index for context " + context);
}
}
else if (log.isTraceEnabled()) {
log.trace("No value for context " + context);
}
} catch (Exception e) {
}
catch (Exception e) {
// only fail fast on the initial query, otherwise just log the error
if (firstTime && this.properties.isFailFast()) {
log.error("Fail fast is set and there was an error reading configuration from consul.");
if (this.firstTime && this.properties.isFailFast()) {
log.error(
"Fail fast is set and there was an error reading configuration from consul.");
ReflectionUtils.rethrowRuntimeException(e);
} else if (log.isTraceEnabled()) {
log.trace("Error querying consul Key/Values for context '" + context + "'", e);
} else if (log.isWarnEnabled()) {
// simplified one line log message in the event of an agent failure
log.warn("Error querying consul Key/Values for context '" + context + "'. Message: " + e.getMessage());
}
else if (log.isTraceEnabled()) {
log.trace("Error querying consul Key/Values for context '"
+ context + "'", e);
}
else if (log.isWarnEnabled()) {
// simplified one line log message in the event of an agent
// failure
log.warn("Error querying consul Key/Values for context '"
+ context + "'. Message: " + e.getMessage());
}
}
}
}
firstTime = false;
this.firstTime = false;
}
static class RefreshEventData {
private final String context;
private final Long prevIndex;
private final Long newIndex;
public RefreshEventData(String context, Long prevIndex, Long newIndex) {
RefreshEventData(String context, Long prevIndex, Long newIndex) {
this.context = context;
this.prevIndex = prevIndex;
this.newIndex = newIndex;
@@ -209,26 +240,30 @@ public class ConfigWatch implements ApplicationEventPublisherAware, SmartLifecyc
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RefreshEventData that = (RefreshEventData) o;
return Objects.equals(context, that.context) &&
Objects.equals(prevIndex, that.prevIndex) &&
Objects.equals(newIndex, that.newIndex);
return Objects.equals(this.context, that.context)
&& Objects.equals(this.prevIndex, that.prevIndex)
&& Objects.equals(this.newIndex, that.newIndex);
}
@Override
public int hashCode() {
return Objects.hash(context, prevIndex, newIndex);
return Objects.hash(this.context, this.prevIndex, this.newIndex);
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("context", context)
.append("prevIndex", prevIndex)
.append("newIndex", newIndex)
return new ToStringCreator(this).append("context", this.context)
.append("prevIndex", this.prevIndex).append("newIndex", this.newIndex)
.toString();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,23 +36,30 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@ConditionalOnProperty(name = "spring.cloud.consul.config.enabled", matchIfMissing = true)
public class ConsulConfigAutoConfiguration {
/**
* Name of the config watch task scheduler bean.
*/
public static final String CONFIG_WATCH_TASK_SCHEDULER_NAME = "configWatchTaskScheduler";
@Configuration
@ConditionalOnClass(RefreshEndpoint.class)
protected static class ConsulRefreshConfiguration {
@Bean
@ConditionalOnProperty(name = "spring.cloud.consul.config.watch.enabled", matchIfMissing = true)
public ConfigWatch configWatch(ConsulConfigProperties properties,
ConsulPropertySourceLocator locator, ConsulClient consul,
@Qualifier(CONFIG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) {
return new ConfigWatch(properties, consul, locator.getContextIndexes(), taskScheduler);
@Qualifier(CONFIG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) {
return new ConfigWatch(properties, consul, locator.getContextIndexes(),
taskScheduler);
}
@Bean(name = CONFIG_WATCH_TASK_SCHEDULER_NAME)
@ConditionalOnProperty(name = "spring.cloud.consul.config.watch.enabled", matchIfMissing = true)
public TaskScheduler configWatchTaskScheduler() {
public TaskScheduler configWatchTaskScheduler() {
return new ThreadPoolTaskScheduler();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@ package org.springframework.cloud.consul.config;
import com.ecwid.consul.v1.ConsulClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.consul.ConditionalOnConsulEnabled;
import org.springframework.cloud.consul.ConsulAutoConfiguration;
@@ -41,6 +41,7 @@ public class ConsulConfigBootstrapConfiguration {
@Import(ConsulAutoConfiguration.class)
@ConditionalOnProperty(name = "spring.cloud.consul.config.enabled", matchIfMissing = true)
protected static class ConsulPropertySourceConfiguration {
@Autowired
private ConsulClient consul;
@@ -53,7 +54,9 @@ public class ConsulConfigBootstrapConfiguration {
@Bean
public ConsulPropertySourceLocator consulPropertySourceLocator(
ConsulConfigProperties consulConfigProperties) {
return new ConsulPropertySourceLocator(consul, consulConfigProperties);
return new ConsulPropertySourceLocator(this.consul, consulConfigProperties);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,21 +16,22 @@
package org.springframework.cloud.consul.config;
import javax.annotation.PostConstruct;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.style.ToStringCreator;
import org.springframework.validation.annotation.Validated;
import javax.annotation.PostConstruct;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* @author Spencer Gibb
*/
@ConfigurationProperties("spring.cloud.consul.config")
@Validated
public class ConsulConfigProperties {
private boolean enabled = true;
private String prefix = "config";
@@ -45,8 +46,8 @@ public class ConsulConfigProperties {
private Format format = Format.KEY_VALUE;
/**
* If format is Format.PROPERTIES or Format.YAML
* then the following field is used as key to look up consul for configuration.
* If format is Format.PROPERTIES or Format.YAML then the following field is used as
* key to look up consul for configuration.
*/
@NotEmpty
private String dataKey = "data";
@@ -80,103 +81,154 @@ public class ConsulConfigProperties {
return this.enabled;
}
public String getPrefix() {
return this.prefix;
}
public @NotEmpty String getDefaultContext() {
return this.defaultContext;
}
public @NotEmpty String getProfileSeparator() {
return this.profileSeparator;
}
public @NotNull Format getFormat() {
return this.format;
}
public @NotEmpty String getDataKey() {
return this.dataKey;
}
public String getAclToken() {
return this.aclToken;
}
public Watch getWatch() {
return this.watch;
}
public boolean isFailFast() {
return this.failFast;
}
public String getName() {
return this.name;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public @NotEmpty String getDefaultContext() {
return this.defaultContext;
}
public void setDefaultContext(@NotEmpty String defaultContext) {
this.defaultContext = defaultContext;
}
public @NotEmpty String getProfileSeparator() {
return this.profileSeparator;
}
public void setProfileSeparator(@NotEmpty String profileSeparator) {
this.profileSeparator = profileSeparator;
}
public @NotNull Format getFormat() {
return this.format;
}
public void setFormat(@NotNull Format format) {
this.format = format;
}
public @NotEmpty String getDataKey() {
return this.dataKey;
}
public void setDataKey(@NotEmpty String dataKey) {
this.dataKey = dataKey;
}
public String getAclToken() {
return this.aclToken;
}
public void setAclToken(String aclToken) {
this.aclToken = aclToken;
}
public Watch getWatch() {
return this.watch;
}
public void setWatch(Watch watch) {
this.watch = watch;
}
public boolean isFailFast() {
return this.failFast;
}
public void setFailFast(boolean failFast) {
this.failFast = failFast;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("enabled", enabled)
.append("prefix", prefix)
.append("defaultContext", defaultContext)
.append("profileSeparator", profileSeparator)
.append("format", format)
.append("dataKey", dataKey)
.append("aclToken", aclToken)
.append("watch", watch)
.append("failFast", failFast)
.append("name", name)
.toString();
return new ToStringCreator(this).append("enabled", this.enabled)
.append("prefix", this.prefix)
.append("defaultContext", this.defaultContext)
.append("profileSeparator", this.profileSeparator)
.append("format", this.format).append("dataKey", this.dataKey)
.append("aclToken", this.aclToken).append("watch", this.watch)
.append("failFast", this.failFast).append("name", this.name).toString();
}
/**
* There are many ways in which we can specify configuration in consul i.e.,
*
* <ol>
* <li>Nested key value style: Where value is either a constant or part of the key
* (nested). For e.g., For following configuration a.b.c=something a.b.d=something
* else One can specify the configuration in consul with key as
* "../kv/config/application/a/b/c" and value as "something" and key as
* "../kv/config/application/a/b/d" and value as "something else"</li>
* <li>Entire contents of properties file as value For e.g., For following
* configuration a.b.c=something a.b.d=something else One can specify the
* configuration in consul with key as "../kv/config/application/properties" and value
* as whole configuration " a.b.c=something a.b.d=something else "</li>
* <li>as Json or YML. You get it.</li>
* </ol>
*
* This enum specifies the different Formats/styles supported for loading the
* configuration.
*
* @author srikalyan.swayampakula
*/
public enum Format {
/**
* Indicates that the configuration specified in consul is of type native key
* values.
*/
KEY_VALUE,
/**
* Indicates that the configuration specified in consul is of property style i.e.,
* value of the consul key would be a list of key=value pairs separated by new
* lines.
*/
PROPERTIES,
/**
* Indicates that the configuration specified in consul is of YAML style i.e.,
* value of the consul key would be YAML format.
*/
YAML,
/**
* Indicates that the configuration specified in consul uses keys as files. This
* is useful for tools like git2consul.
*/
FILES,
}
/**
* Consul watch properties.
*/
public static class Watch {
/** The number of seconds to wait (or block) for watch query, defaults to 55.
* Needs to be less than default ConsulClient (defaults to 60). To increase ConsulClient
/**
* The number of seconds to wait (or block) for watch query, defaults to 55. Needs
* to be less than default ConsulClient (defaults to 60). To increase ConsulClient
* timeout create a ConsulClient bean with a custom ConsulRawClient with a custom
* HttpClient. */
* HttpClient.
*/
private int waitTime = 55;
/** If the watch is enabled. Defaults to true. */
@@ -192,83 +244,33 @@ public class ConsulConfigProperties {
return this.waitTime;
}
public boolean isEnabled() {
return this.enabled;
}
public int getDelay() {
return this.delay;
}
public void setWaitTime(int waitTime) {
this.waitTime = waitTime;
}
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public int getDelay() {
return this.delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("waitTime", waitTime)
.append("enabled", enabled)
.append("delay", delay)
return new ToStringCreator(this).append("waitTime", this.waitTime)
.append("enabled", this.enabled).append("delay", this.delay)
.toString();
}
}
/**
* There are many ways in which we can specify configuration in consul i.e.,
*
* <ol>
* <li>
* Nested key value style: Where value is either a constant or part of the key (nested).
* For e.g., For following configuration a.b.c=something a.b.d=something else One can
* specify the configuration in consul with key as "../kv/config/application/a/b/c" and
* value as "something" and key as "../kv/config/application/a/b/d" and value as
* "something else"</li>
* <li>
* Entire contents of properties file as value For e.g., For following configuration
* a.b.c=something a.b.d=something else One can specify the configuration in consul with
* key as "../kv/config/application/properties" and value as whole configuration "
* a.b.c=something a.b.d=something else "</li>
* <li>
* as Json or YML. You get it.</li>
* </ol>
*
* This enum specifies the different Formats/styles supported for loading the
* configuration.
*
* @author srikalyan.swayampakula
*/
public enum Format {
/**
* Indicates that the configuration specified in consul is of type native key values.
*/
KEY_VALUE,
/**
* Indicates that the configuration specified in consul is of property style i.e.,
* value of the consul key would be a list of key=value pairs separated by new lines.
*/
PROPERTIES,
/**
* Indicates that the configuration specified in consul is of YAML style i.e., value
* of the consul key would be YAML format
*/
YAML,
/**
* Indicates that the configuration specified in consul uses keys as files.
* This is useful for tools like git2consul.
*/
FILES,
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,22 +26,28 @@ import static org.springframework.cloud.consul.config.ConsulConfigProperties.For
* @author Spencer Gibb
*/
public class ConsulFilesPropertySource extends ConsulPropertySource {
public ConsulFilesPropertySource(String context, ConsulClient source, ConsulConfigProperties configProperties) {
public ConsulFilesPropertySource(String context, ConsulClient source,
ConsulConfigProperties configProperties) {
super(context, source, configProperties);
}
@Override
public void init() {
//noop
// noop
}
public void init(GetValue value) {
if (this.getContext().endsWith(".yml") || this.getContext().endsWith(".yaml")) {
parseValue(value, YAML);
} else if (this.getContext().endsWith(".properties")) {
}
else if (this.getContext().endsWith(".properties")) {
parseValue(value, PROPERTIES);
} else {
throw new IllegalStateException("Unknown files extension for context " + this.getContext());
}
else {
throw new IllegalStateException(
"Unknown files extension for context " + this.getContext());
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,16 +24,16 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.util.StringUtils;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.kv.model.GetValue;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.util.StringUtils;
import static org.springframework.cloud.consul.config.ConsulConfigProperties.Format.PROPERTIES;
import static org.springframework.cloud.consul.config.ConsulConfigProperties.Format.YAML;
import static org.springframework.util.Base64Utils.decodeFromString;
@@ -43,11 +43,12 @@ import static org.springframework.util.Base64Utils.decodeFromString;
*/
public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient> {
private String context;
private ConsulConfigProperties configProperties;
private final Map<String, Object> properties = new LinkedHashMap<>();
private String context;
private ConsulConfigProperties configProperties;
private Long initialIndex;
public ConsulPropertySource(String context, ConsulClient source,
@@ -63,13 +64,13 @@ public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient>
this.context = this.context + "/";
}
Response<List<GetValue>> response = source.getKVValues(context,
configProperties.getAclToken(), QueryParams.DEFAULT);
Response<List<GetValue>> response = this.source.getKVValues(this.context,
this.configProperties.getAclToken(), QueryParams.DEFAULT);
initialIndex = response.getConsulIndex();
this.initialIndex = response.getConsulIndex();
final List<GetValue> values = response.getValue();
ConsulConfigProperties.Format format = configProperties.getFormat();
ConsulConfigProperties.Format format = this.configProperties.getFormat();
switch (format) {
case KEY_VALUE:
parsePropertiesInKeyValueFormat(values);
@@ -81,14 +82,13 @@ public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient>
}
public Long getInitialIndex() {
return initialIndex;
return this.initialIndex;
}
/**
* Parses the properties in key value style i.e., values are expected to be either a
* sub key or a constant
*
* @param values
* sub key or a constant.
* @param values values to parse
*/
protected void parsePropertiesInKeyValueFormat(List<GetValue> values) {
if (values == null) {
@@ -98,18 +98,18 @@ public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient>
for (GetValue getValue : values) {
String key = getValue.getKey();
if (!StringUtils.endsWithIgnoreCase(key, "/")) {
key = key.replace(context, "").replace('/', '.');
key = key.replace(this.context, "").replace('/', '.');
String value = getValue.getDecodedValue();
properties.put(key, value);
this.properties.put(key, value);
}
}
}
/**
* Parses the properties using the format which is not a key value style i.e., either
* java properties style or YAML style
*
* @param values
* java properties style or YAML style.
* @param values values to parse
* @param format format in which the values should be parsed
*/
protected void parsePropertiesWithNonKeyValueFormat(List<GetValue> values,
ConsulConfigProperties.Format format) {
@@ -118,8 +118,8 @@ public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient>
}
for (GetValue getValue : values) {
String key = getValue.getKey().replace(context, "");
if (configProperties.getDataKey().equals(key)) {
String key = getValue.getKey().replace(this.context, "");
if (this.configProperties.getDataKey().equals(key)) {
parseValue(getValue, format);
}
}
@@ -134,8 +134,7 @@ public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient>
Properties props = generateProperties(value, format);
for (Map.Entry entry : props.entrySet()) {
properties
.put(entry.getKey().toString(), entry.getValue());
this.properties.put(entry.getKey().toString(), entry.getValue());
}
}
@@ -150,8 +149,8 @@ public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient>
props.load(new ByteArrayInputStream(value.getBytes("ISO-8859-1")));
}
catch (IOException e) {
throw new IllegalArgumentException(value
+ " can't be encoded using ISO-8859-1");
throw new IllegalArgumentException(
value + " can't be encoded using ISO-8859-1");
}
return props;
@@ -168,34 +167,38 @@ public class ConsulPropertySource extends EnumerablePropertySource<ConsulClient>
/**
* @deprecated As of 1.1.0 use {@link GetValue#getDecodedValue()}.
* @param value encoded value
* @return the decoded string
*/
@Deprecated
public String getDecoded(String value) {
if (value == null)
if (value == null) {
return null;
}
return new String(decodeFromString(value));
}
protected Map<String, Object> getProperties() {
return properties;
return this.properties;
}
protected ConsulConfigProperties getConfigProperties() {
return configProperties;
return this.configProperties;
}
protected String getContext() {
return context;
return this.context;
}
@Override
public Object getProperty(String name) {
return properties.get(name);
return this.properties.get(name);
}
@Override
public String[] getPropertyNames() {
Set<String> strings = properties.keySet();
Set<String> strings = this.properties.keySet();
return strings.toArray(new String[strings.size()]);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,6 +48,7 @@ import static org.springframework.cloud.consul.config.ConsulConfigProperties.For
public class ConsulPropertySourceLocator implements PropertySourceLocator {
private static final Log log = LogFactory.getLog(ConsulPropertySourceLocator.class);
private final ConsulClient consul;
private final ConsulConfigProperties properties;
@@ -56,18 +57,19 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator {
private final LinkedHashMap<String, Long> contextIndex = new LinkedHashMap<>();
public ConsulPropertySourceLocator(ConsulClient consul, ConsulConfigProperties properties) {
public ConsulPropertySourceLocator(ConsulClient consul,
ConsulConfigProperties properties) {
this.consul = consul;
this.properties = properties;
}
@Deprecated
public List<String> getContexts() {
return contexts;
return this.contexts;
}
public LinkedHashMap<String, Long> getContextIndexes() {
return contextIndex;
return this.contextIndex;
}
@Override
@@ -76,7 +78,7 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator {
if (environment instanceof ConfigurableEnvironment) {
ConfigurableEnvironment env = (ConfigurableEnvironment) environment;
String appName = properties.getName();
String appName = this.properties.getName();
if (appName == null) {
appName = env.getProperty("spring.application.name");
@@ -89,13 +91,15 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator {
List<String> suffixes = new ArrayList<>();
if (this.properties.getFormat() != FILES) {
suffixes.add("/");
} else {
}
else {
suffixes.add(".yml");
suffixes.add(".yaml");
suffixes.add(".properties");
}
String defaultContext = getContext(prefix, this.properties.getDefaultContext());
String defaultContext = getContext(prefix,
this.properties.getDefaultContext());
for (String suffix : suffixes) {
this.contexts.add(defaultContext + suffix);
@@ -121,25 +125,32 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator {
try {
ConsulPropertySource propertySource = null;
if (this.properties.getFormat() == FILES) {
Response<GetValue> response = this.consul.getKVValue(propertySourceContext, this.properties.getAclToken());
Response<GetValue> response = this.consul.getKVValue(
propertySourceContext, this.properties.getAclToken());
addIndex(propertySourceContext, response.getConsulIndex());
if (response.getValue() != null) {
ConsulFilesPropertySource filesPropertySource = new ConsulFilesPropertySource(propertySourceContext, this.consul, this.properties);
ConsulFilesPropertySource filesPropertySource = new ConsulFilesPropertySource(
propertySourceContext, this.consul, this.properties);
filesPropertySource.init(response.getValue());
propertySource = filesPropertySource;
}
} else {
propertySource = create(propertySourceContext, contextIndex);
}
else {
propertySource = create(propertySourceContext, this.contextIndex);
}
if (propertySource != null) {
composite.addPropertySource(propertySource);
}
} catch (Exception e) {
}
catch (Exception e) {
if (this.properties.isFailFast()) {
log.error("Fail fast is set and there was an error reading configuration from consul.");
log.error(
"Fail fast is set and there was an error reading configuration from consul.");
ReflectionUtils.rethrowRuntimeException(e);
} else {
log.warn("Unable to load consul config from "+ propertySourceContext, e);
}
else {
log.warn("Unable to load consul config from "
+ propertySourceContext, e);
}
}
}
@@ -152,26 +163,30 @@ public class ConsulPropertySourceLocator implements PropertySourceLocator {
private String getContext(String prefix, String context) {
if (StringUtils.isEmpty(prefix)) {
return context;
} else {
}
else {
return prefix + "/" + context;
}
}
private void addIndex(String propertySourceContext, Long consulIndex) {
contextIndex.put(propertySourceContext, consulIndex);
this.contextIndex.put(propertySourceContext, consulIndex);
}
private ConsulPropertySource create(String context, Map<String, Long> contextIndex) {
ConsulPropertySource propertySource = new ConsulPropertySource(context, this.consul, this.properties);
ConsulPropertySource propertySource = new ConsulPropertySource(context,
this.consul, this.properties);
propertySource.init();
addIndex(context, propertySource.getInitialIndex());
return propertySource;
}
private void addProfiles(List<String> contexts, String baseContext,
List<String> profiles, String suffix) {
List<String> profiles, String suffix) {
for (String profile : profiles) {
contexts.add(baseContext + this.properties.getProfileSeparator() + profile + suffix);
contexts.add(baseContext + this.properties.getProfileSeparator() + profile
+ suffix);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,10 @@
package org.springframework.cloud.consul.config;
import org.springframework.context.ApplicationEvent;
import java.util.LinkedHashMap;
import org.springframework.context.ApplicationEvent;
/**
* @author Spencer Gibb
*/
@@ -29,15 +29,17 @@ public class PropertySourcesLocatedEvent extends ApplicationEvent {
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
* @param contextsToIndexes contexts to indexes
*/
public PropertySourcesLocatedEvent(Object source, LinkedHashMap<String, Long> contextsToIndexes) {
public PropertySourcesLocatedEvent(Object source,
LinkedHashMap<String, Long> contextsToIndexes) {
super(source);
this.contextsToIndexes = contextsToIndexes;
}
public LinkedHashMap<String, Long> getContextsToIndexes() {
return contextsToIndexes;
return this.contextsToIndexes;
}
}

View File

@@ -1,7 +1,6 @@
# Auto Configuration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.consul.config.ConsulConfigAutoConfiguration
# Bootstrap Configuration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.consul.config.ConsulConfigBootstrapConfiguration

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,21 +16,22 @@
package org.springframework.cloud.consul.config;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.kv.model.GetValue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.endpoint.event.RefreshEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
@@ -52,14 +53,15 @@ public class ConfigWatchTests {
@Before
public void setUp() throws Exception {
configProperties = new ConsulConfigProperties();
this.configProperties = new ConsulConfigProperties();
}
@Test
public void watchPublishesEventWithAcl() {
ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class);
setupWatch(eventPublisher, new GetValue(), "/app/", "2ee647bd-bd69-4118-9f34-b9a6e9e60746");
setupWatch(eventPublisher, new GetValue(), "/app/",
"2ee647bd-bd69-4118-9f34-b9a6e9e60746");
verify(eventPublisher, atLeastOnce()).publishEvent(any(RefreshEvent.class));
}
@@ -86,17 +88,19 @@ public class ConfigWatchTests {
public void watchForFileFormatPublishesEvent() {
ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class);
configProperties.setFormat(FILES);
setupWatch(eventPublisher, new GetValue(), "/config/app.yml" );
this.configProperties.setFormat(FILES);
setupWatch(eventPublisher, new GetValue(), "/config/app.yml");
verify(eventPublisher, times(1)).publishEvent(any(RefreshEvent.class));
}
private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue, String context) {
private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue,
String context) {
setupWatch(eventPublisher, getValue, context, null);
}
private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue, String context, String aclToken) {
private void setupWatch(ApplicationEventPublisher eventPublisher, GetValue getValue,
String context, String aclToken) {
ConsulClient consul = mock(ConsulClient.class);
List<GetValue> getValues = null;
@@ -105,15 +109,17 @@ public class ConfigWatchTests {
}
Response<List<GetValue>> response = new Response<>(getValues, 1L, false, 1L);
when(consul.getKVValues(eq(context), nullable(String.class), any(QueryParams.class))).thenReturn(response);
when(consul.getKVValues(eq(context), nullable(String.class),
any(QueryParams.class))).thenReturn(response);
if (StringUtils.hasText(aclToken)) {
configProperties.setAclToken(aclToken);
this.configProperties.setAclToken(aclToken);
}
LinkedHashMap<String, Long> initialIndexes = new LinkedHashMap<>();
initialIndexes.put(context, 0L);
ConfigWatch watch = new ConfigWatch(configProperties, consul, initialIndexes);
ConfigWatch watch = new ConfigWatch(this.configProperties, consul,
initialIndexes);
watch.setApplicationEventPublisher(eventPublisher);
watch.start();
@@ -123,7 +129,7 @@ public class ConfigWatchTests {
@Test
public void firstCallDoesNotPublishEvent() {
ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class);
configProperties.setFormat(FILES);
this.configProperties.setFormat(FILES);
GetValue getValue = new GetValue();
String context = "/config/app.yml";
@@ -131,9 +137,11 @@ public class ConfigWatchTests {
List<GetValue> getValues = Collections.singletonList(getValue);
Response<List<GetValue>> response = new Response<>(getValues, 1L, false, 1L);
when(consul.getKVValues(eq(context), anyString(), any(QueryParams.class))).thenReturn(response);
when(consul.getKVValues(eq(context), anyString(), any(QueryParams.class)))
.thenReturn(response);
ConfigWatch watch = new ConfigWatch(configProperties, consul, new LinkedHashMap<String, Long>());
ConfigWatch watch = new ConfigWatch(this.configProperties, consul,
new LinkedHashMap<String, Long>());
watch.setApplicationEventPublisher(eventPublisher);
watch.watchConfigKeyValues();

View File

@@ -1,50 +1,76 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
package org.springframework.cloud.consul.config;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Edvin Eriksson
*/
public class ConsulConfigBootstrapConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
/**
* Tests that the auto-config bean backs off if a user provided their own
* Tests that the auto-config bean backs off if a user provided their own.
*/
@Test
public void testConfigPropsBeanBacksOff() {
contextRunner
.withUserConfiguration(TestConfig.class)
.withUserConfiguration(ConsulConfigBootstrapConfiguration.class)
.run(context -> {
ConsulConfigProperties config = context.getBean(ConsulConfigProperties.class);
Assert.assertEquals("Prefix did not match", "platform-config", config.getPrefix());
Assert.assertEquals("Default context did not match", "defaults", config.getDefaultContext());
});
this.contextRunner.withUserConfiguration(TestConfig.class)
.withUserConfiguration(ConsulConfigBootstrapConfiguration.class)
.run(context -> {
ConsulConfigProperties config = context
.getBean(ConsulConfigProperties.class);
assertThat(config.getPrefix()).as("Prefix did not match")
.isEqualTo("platform-config");
assertThat(config.getDefaultContext())
.as("Default context did not match").isEqualTo("defaults");
});
}
/**
* Tests that the auto-config bean kicks in if the user did not provide any custom bean.
* Tests that the auto-config bean kicks in if the user did not provide any custom
* bean.
*/
@Test
public void testConfigPropsBeanKicksIn() {
contextRunner
.withUserConfiguration(ConsulConfigBootstrapConfiguration.class)
.run(context -> {
ConsulConfigProperties config = context.getBean(ConsulConfigProperties.class);
Assert.assertEquals("Prefix did not match", "config", config.getPrefix());
Assert.assertEquals("Default context did not match", "application", config.getDefaultContext());
});
this.contextRunner.withUserConfiguration(ConsulConfigBootstrapConfiguration.class)
.run(context -> {
ConsulConfigProperties config = context
.getBean(ConsulConfigProperties.class);
assertThat(config.getPrefix()).as("Prefix did not match")
.isEqualTo("config");
assertThat(config.getDefaultContext())
.as("Default context did not match").isEqualTo("application");
});
}
}
/**
* Test config that simulates a "user provided bean"
* Test config that simulates a "user provided bean".
*/
class TestConfig {
@Bean
public ConsulConfigProperties consulConfigProperties() {
ConsulConfigProperties config = new ConsulConfigProperties();
@@ -52,4 +78,5 @@ class TestConfig {
config.setDefaultContext("defaults");
return config;
}
}
}

View File

@@ -1,15 +1,29 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
package org.springframework.cloud.consul.config;
import com.ecwid.consul.v1.ConsulClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.consul.ConsulProperties;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
public class ConsulPropertyPrefixTests {
@@ -18,37 +32,44 @@ public class ConsulPropertyPrefixTests {
@Before
public void setup() {
ConsulProperties properties = new ConsulProperties();
client = new ConsulClient(properties.getHost(), properties.getPort());
this.client = new ConsulClient(properties.getHost(), properties.getPort());
}
@After
public void teardown() {
client.deleteKVValues("");
this.client.deleteKVValues("");
}
@Test
public void testEmptyPrefix() {
// because prefix is empty, a leading forward slash is omitted
String kvContext = "appname";
client.setKVValue(kvContext + "/fooprop", "fookvval");
client.setKVValue(kvContext + "/bar/prop", "8080");
this.client.setKVValue(kvContext + "/fooprop", "fookvval");
this.client.setKVValue(kvContext + "/bar/prop", "8080");
ConsulPropertySource source = getConsulPropertySource(new ConsulConfigProperties(), kvContext);
ConsulPropertySource source = getConsulPropertySource(
new ConsulConfigProperties(), kvContext);
assertProperties(source, "fookvval", "8080");
}
private void assertProperties(ConsulPropertySource source, Object fooval, Object barval) {
assertThat("fooprop was wrong", source.getProperty("fooprop"), is(equalTo(fooval)));
assertThat("bar.prop was wrong", source.getProperty("bar.prop"), is(equalTo(barval)));
private void assertProperties(ConsulPropertySource source, Object fooval,
Object barval) {
assertThat(source.getProperty("fooprop")).as("fooprop was wrong")
.isEqualTo(fooval);
assertThat(source.getProperty("bar.prop")).as("bar.prop was wrong")
.isEqualTo(barval);
}
@SuppressWarnings("Duplicates")
private ConsulPropertySource getConsulPropertySource(ConsulConfigProperties configProperties, String context) {
ConsulPropertySource source = new ConsulPropertySource(context, client, configProperties);
private ConsulPropertySource getConsulPropertySource(
ConsulConfigProperties configProperties, String context) {
ConsulPropertySource source = new ConsulPropertySource(context, this.client,
configProperties);
source.init();
String[] names = source.getPropertyNames();
assertThat("names was null", names, is(notNullValue()));
assertThat("names was wrong size", names.length, is(equalTo(2)));
assertThat(names).as("names was null").isNotNull();
assertThat(names.length).as("names was wrong size").isEqualTo(2);
return source;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,11 @@ package org.springframework.cloud.consul.config;
import java.util.UUID;
import com.ecwid.consul.v1.ConsulClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -30,57 +32,58 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.annotation.DirtiesContext;
import com.ecwid.consul.v1.ConsulClient;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
@DirtiesContext
public class ConsulPropertySourceLocatorAppNameCustomizedTests {
private static final String PREFIX = "_propertySourceLocatorAppNameCustomizedTests_config__";
private static final String ROOT = PREFIX + UUID.randomUUID();
private static final String VALUE1 = "testPropVal";
private static final String TEST_PROP = "testProp";
private static final String CONFIG_NAME = "myconfigfolder";
private static final String KEY1 = ROOT + "/"+ CONFIG_NAME +"/"+ TEST_PROP;
private static final String KEY1 = ROOT + "/" + CONFIG_NAME + "/" + TEST_PROP;
private static final String VALUE2 = "testPropVal2";
private static final String TEST_PROP2 = "testProp2";
private static final String KEY2 = ROOT + "/"+ CONFIG_NAME +"/"+ TEST_PROP2;
private static final String KEY2 = ROOT + "/" + CONFIG_NAME + "/" + TEST_PROP2;
private ConfigurableApplicationContext context;
@Configuration
@EnableAutoConfiguration
static class Config {
}
private ConfigurableEnvironment environment;
private ConsulClient client;
private ConsulProperties properties;
@Before
public void setup() {
this.properties = new ConsulProperties();
this.client = new ConsulClient(properties.getHost(), properties.getPort());
this.client = new ConsulClient(this.properties.getHost(),
this.properties.getPort());
this.client.deleteKVValues(PREFIX);
this.client.setKVValue(KEY1, VALUE1);
this.client.setKVValue(KEY2, VALUE2);
this.context = new SpringApplicationBuilder(Config.class)
.web(WebApplicationType.NONE)
.run("--spring.application.name=testConsulPropertySourceLocatorAppNameCustomized",
"--spring.cloud.consul.config.name="+CONFIG_NAME,
"--spring.cloud.consul.config.prefix="+ROOT);
"--spring.cloud.consul.config.name=" + CONFIG_NAME,
"--spring.cloud.consul.config.prefix=" + ROOT);
this.client = context.getBean(ConsulClient.class);
this.properties = context.getBean(ConsulProperties.class);
this.environment = context.getEnvironment();
this.client = this.context.getBean(ConsulClient.class);
this.properties = this.context.getBean(ConsulProperties.class);
this.environment = this.context.getEnvironment();
}
@After
@@ -92,9 +95,16 @@ public class ConsulPropertySourceLocatorAppNameCustomizedTests {
@Test
public void propertyLoaded() throws Exception {
String testProp = this.environment.getProperty(TEST_PROP);
assertThat("testProp was wrong", testProp, is(equalTo(VALUE1)));
assertThat(testProp).as("testProp was wrong").isEqualTo(VALUE1);
String testProp2 = this.environment.getProperty(TEST_PROP2);
assertThat("testProp2 was wrong", testProp2, is(equalTo(VALUE2)));
assertThat(testProp2).as("testProp2 was wrong").isEqualTo(VALUE2);
}
@Configuration
@EnableAutoConfiguration
static class Config {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.cloud.consul.config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
@@ -29,22 +30,21 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Spencer Gibb
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsulPropertySourceLocatorFailFastTests.Config.class,
properties = {"spring.application.name=testConsulPropertySourceLocatorFailFast",
@SpringBootTest(classes = ConsulPropertySourceLocatorFailFastTests.Config.class, properties = {
"spring.application.name=testConsulPropertySourceLocatorFailFast",
"spring.cloud.consul.host=53210a7c-4809-42cb-8b30-057d2db85fcc",
"spring.cloud.consul.port=65530",
"spring.cloud.consul.retry.maxAttempts=0",
"spring.cloud.consul.config.failFast=false"},
webEnvironment = RANDOM_PORT)
"spring.cloud.consul.port=65530", "spring.cloud.consul.retry.maxAttempts=0",
"spring.cloud.consul.config.failFast=false" }, webEnvironment = RANDOM_PORT)
public class ConsulPropertySourceLocatorFailFastTests {
@Configuration
@EnableAutoConfiguration
static class Config {
}
@Test
public void testFailFastFalse() {
}
@Configuration
@EnableAutoConfiguration
static class Config {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,11 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.UUID;
import com.ecwid.consul.v1.ConsulClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -35,62 +37,59 @@ import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.test.annotation.DirtiesContext;
import com.ecwid.consul.v1.ConsulClient;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.typeCompatibleWith;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
@DirtiesContext
public class ConsulPropertySourceLocatorFilesTests {
public static final String PREFIX = "_propertySourceLocatorFilesTests_config__";
public static final String ROOT = PREFIX + UUID.randomUUID();
public static final String APP_NAME = "testFilesFormat";
public static final String APPLICATION_YML = "/application.yml";
public static final String APPLICATION_DEV_YML = "/application-dev.yaml";
public static final String APP_NAME_PROPS = "/"+APP_NAME+".properties";
public static final String APP_NAME_DEV_PROPS = "/"+APP_NAME+"-dev.properties";
public static final String APP_NAME_PROPS = "/" + APP_NAME + ".properties";
public static final String APP_NAME_DEV_PROPS = "/" + APP_NAME + "-dev.properties";
private ConfigurableApplicationContext context;
@Configuration
@EnableAutoConfiguration
static class Config {
}
private ConfigurableEnvironment environment;
private ConsulClient client;
private ConsulProperties properties;
@Before
public void setup() {
this.properties = new ConsulProperties();
this.client = new ConsulClient(properties.getHost(), properties.getPort());
this.client.setKVValue(ROOT+ APPLICATION_YML, "foo: bar\nmy.baz: ${foo}");
this.client.setKVValue(ROOT+ APPLICATION_DEV_YML, "foo: bar-dev\nmy.baz: ${foo}");
this.client.setKVValue(ROOT+"/master.ref", UUID.randomUUID().toString());
this.client.setKVValue(ROOT+APP_NAME_PROPS, "foo: bar-app\nmy.baz: ${foo}");
this.client.setKVValue(ROOT+APP_NAME_DEV_PROPS, "foo: bar-app-dev\nmy.baz: ${foo}");
this.client = new ConsulClient(this.properties.getHost(),
this.properties.getPort());
this.client.setKVValue(ROOT + APPLICATION_YML, "foo: bar\nmy.baz: ${foo}");
this.client.setKVValue(ROOT + APPLICATION_DEV_YML,
"foo: bar-dev\nmy.baz: ${foo}");
this.client.setKVValue(ROOT + "/master.ref", UUID.randomUUID().toString());
this.client.setKVValue(ROOT + APP_NAME_PROPS, "foo: bar-app\nmy.baz: ${foo}");
this.client.setKVValue(ROOT + APP_NAME_DEV_PROPS,
"foo: bar-app-dev\nmy.baz: ${foo}");
this.context = new SpringApplicationBuilder(Config.class)
.web(WebApplicationType.NONE)
.run("--spring.application.name="+ APP_NAME,
"--spring.cloud.consul.config.prefix="+ROOT,
.web(WebApplicationType.NONE).run("--spring.application.name=" + APP_NAME,
"--spring.cloud.consul.config.prefix=" + ROOT,
"--spring.cloud.consul.config.format=FILES",
"--spring.profiles.active=dev",
"spring.cloud.consul.config.watch.delay=1");
this.client = context.getBean(ConsulClient.class);
this.properties = context.getBean(ConsulProperties.class);
this.environment = context.getEnvironment();
this.client = this.context.getBean(ConsulClient.class);
this.properties = this.context.getBean(ConsulProperties.class);
this.environment = this.context.getEnvironment();
}
@After
@@ -104,32 +103,48 @@ public class ConsulPropertySourceLocatorFilesTests {
@Test
public void propertySourcesFound() throws Exception {
String foo = this.environment.getProperty("foo");
assertThat("foo was wrong", foo, is(equalTo("bar-app-dev")));
assertThat(foo).as("foo was wrong").isEqualTo("bar-app-dev");
String myBaz = this.environment.getProperty("my.baz");
assertThat("my.baz was wrong", myBaz, is(equalTo("bar-app-dev")));
assertThat(myBaz).as("my.baz was wrong").isEqualTo("bar-app-dev");
MutablePropertySources propertySources = this.environment.getPropertySources();
PropertySource<?> bootstrapProperties = propertySources.get("bootstrapProperties");
assertThat("bootstrapProperties was null", bootstrapProperties, is(notNullValue()));
assertThat("bootstrapProperties was wrong type", bootstrapProperties.getClass(), is(typeCompatibleWith(CompositePropertySource.class)));
PropertySource<?> bootstrapProperties = propertySources
.get("bootstrapProperties");
assertThat(bootstrapProperties).as("bootstrapProperties was null").isNotNull();
assertThat(bootstrapProperties.getClass())
.as("bootstrapProperties was wrong type")
.isInstanceOf(CompositePropertySource.class);
Collection<PropertySource<?>> consulSources = ((CompositePropertySource) bootstrapProperties).getPropertySources();
assertThat("consulSources was wrong size", consulSources, hasSize(1));
Collection<PropertySource<?>> consulSources = ((CompositePropertySource) bootstrapProperties)
.getPropertySources();
assertThat(consulSources).as("consulSources was wrong size").hasSize(1);
PropertySource<?> consulSource = consulSources.iterator().next();
assertThat("consulSource was wrong type", consulSource.getClass(), is(typeCompatibleWith(CompositePropertySource.class)));
Collection<PropertySource<?>> fileSources = ((CompositePropertySource) consulSource).getPropertySources();
assertThat("fileSources was wrong size", fileSources, hasSize(4));
assertThat(consulSource.getClass()).as("consulSource was wrong type")
.isInstanceOf(CompositePropertySource.class);
Collection<PropertySource<?>> fileSources = ((CompositePropertySource) consulSource)
.getPropertySources();
assertThat(fileSources).as("fileSources was wrong size").hasSize(4);
assertFileSourceNames(fileSources, APP_NAME_DEV_PROPS, APP_NAME_PROPS, APPLICATION_DEV_YML, APPLICATION_YML);
assertFileSourceNames(fileSources, APP_NAME_DEV_PROPS, APP_NAME_PROPS,
APPLICATION_DEV_YML, APPLICATION_YML);
}
private void assertFileSourceNames(Collection<PropertySource<?>> fileSources, String... names) {
private void assertFileSourceNames(Collection<PropertySource<?>> fileSources,
String... names) {
Iterator<PropertySource<?>> iterator = fileSources.iterator();
for (String name : names) {
PropertySource<?> fileSource = iterator.next();
assertThat("fileSources was wrong name", fileSource.getName(), endsWith(name));
assertThat(fileSource.getName()).as("fileSources was wrong name")
.endsWith(name);
}
}
@Configuration
@EnableAutoConfiguration
static class Config {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,10 +20,12 @@ import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.ecwid.consul.v1.ConsulClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -36,35 +38,117 @@ import org.springframework.context.event.EventListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.annotation.DirtiesContext;
import com.ecwid.consul.v1.ConsulClient;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
@DirtiesContext
public class ConsulPropertySourceLocatorTests {
private static final String APP_NAME = "testConsulPropertySourceLocator";
private static final String PREFIX = "_propertySourceLocatorTests_config__";
private static final String ROOT = PREFIX + UUID.randomUUID();
private static final String VALUE1 = "testPropVal";
private static final String TEST_PROP = "testProp";
private static final String TEST_PROP_CANONICAL = "test-prop";
private static final String KEY1 = ROOT + "/application/"+ TEST_PROP;
private static final String KEY1 = ROOT + "/application/" + TEST_PROP;
private static final String VALUE2 = "testPropVal2";
private static final String TEST_PROP2 = "testProp2";
private static final String TEST_PROP2_CANONICAL = "test-prop2";
private static final String KEY2 = ROOT + "/application/"+ TEST_PROP2;
private static final String KEY2 = ROOT + "/application/" + TEST_PROP2;
private static final String TEST_PROP3 = "testProp3";
private static final String TEST_PROP3_CANONICAL = "test-prop3";
private static final String KEY3 = ROOT + "/"+APP_NAME+"/"+ TEST_PROP3;
private static final String KEY3 = ROOT + "/" + APP_NAME + "/" + TEST_PROP3;
private ConfigurableApplicationContext context;
private ConfigurableEnvironment environment;
private ConsulClient client;
private ConsulProperties properties;
@Before
public void setup() {
this.properties = new ConsulProperties();
this.client = new ConsulClient(this.properties.getHost(),
this.properties.getPort());
this.client.deleteKVValues(PREFIX);
this.client.setKVValue(KEY1, VALUE1);
this.client.setKVValue(KEY2, VALUE2);
this.context = new SpringApplicationBuilder(Config.class)
.web(WebApplicationType.NONE).run("--SPRING_APPLICATION_NAME=" + APP_NAME,
"--spring.cloud.consul.config.prefix=" + ROOT,
"spring.cloud.consul.config.watch.delay=10");
this.client = this.context.getBean(ConsulClient.class);
this.properties = this.context.getBean(ConsulProperties.class);
this.environment = this.context.getEnvironment();
}
@After
public void teardown() {
this.client.deleteKVValues(PREFIX);
this.context.close();
}
@Test
public void propertyLoaded() throws Exception {
String testProp = this.environment.getProperty(TEST_PROP2_CANONICAL);
assertThat(testProp).as("testProp was wrong").isEqualTo(VALUE2);
}
@Test
@Ignore // FIXME broken tests with boot 2.0.0
public void propertyLoadedAndUpdated() throws Exception {
String testProp = this.environment.getProperty(TEST_PROP_CANONICAL);
assertThat(testProp).as("testProp was wrong").isEqualTo(VALUE1);
this.client.setKVValue(KEY1, "testPropValUpdate");
CountDownLatch latch = this.context.getBean("countDownLatch1",
CountDownLatch.class);
boolean receivedEvent = latch.await(15, TimeUnit.SECONDS);
assertThat(receivedEvent).as("listener didn't receive event").isTrue();
testProp = this.environment.getProperty(TEST_PROP_CANONICAL);
assertThat(testProp).as("testProp was wrong after update")
.isEqualTo("testPropValUpdate");
}
@Test
@Ignore // FIXME broken tests with boot 2.0.0
public void contextDoesNotExistThenExists() throws Exception {
String testProp = this.environment.getProperty(TEST_PROP3_CANONICAL);
assertThat(testProp).as("testProp was wrong").isNull();
this.client.setKVValue(KEY3, "testPropValInsert");
CountDownLatch latch = this.context.getBean("countDownLatch2",
CountDownLatch.class);
boolean receivedEvent = latch.await(15, TimeUnit.SECONDS);
assertThat(receivedEvent).as("listener didn't receive event").isTrue();
testProp = this.environment.getProperty(TEST_PROP3_CANONICAL);
assertThat(testProp).as(TEST_PROP3 + " was wrong after update")
.isEqualTo("testPropValInsert");
}
@Configuration
@EnableAutoConfiguration
static class Config {
@@ -83,77 +167,12 @@ public class ConsulPropertySourceLocatorTests {
public void handle(EnvironmentChangeEvent event) {
if (event.getKeys().contains(TEST_PROP)) {
countDownLatch1().countDown();
} else if (event.getKeys().contains(TEST_PROP3)) {
}
else if (event.getKeys().contains(TEST_PROP3)) {
countDownLatch2().countDown();
}
}
}
private ConfigurableEnvironment environment;
private ConsulClient client;
private ConsulProperties properties;
@Before
public void setup() {
this.properties = new ConsulProperties();
this.client = new ConsulClient(properties.getHost(), properties.getPort());
this.client.deleteKVValues(PREFIX);
this.client.setKVValue(KEY1, VALUE1);
this.client.setKVValue(KEY2, VALUE2);
this.context = new SpringApplicationBuilder(Config.class)
.web(WebApplicationType.NONE)
.run("--SPRING_APPLICATION_NAME="+ APP_NAME,
"--spring.cloud.consul.config.prefix="+ROOT,
"spring.cloud.consul.config.watch.delay=10");
this.client = context.getBean(ConsulClient.class);
this.properties = context.getBean(ConsulProperties.class);
this.environment = context.getEnvironment();
}
@After
public void teardown() {
this.client.deleteKVValues(PREFIX);
this.context.close();
}
@Test
public void propertyLoaded() throws Exception {
String testProp = this.environment.getProperty(TEST_PROP2_CANONICAL);
assertThat("testProp was wrong", testProp, is(equalTo(VALUE2)));
}
@Test
@Ignore // FIXME broken tests with boot 2.0.0
public void propertyLoadedAndUpdated() throws Exception {
String testProp = this.environment.getProperty(TEST_PROP_CANONICAL);
assertThat("testProp was wrong", testProp, is(equalTo(VALUE1)));
this.client.setKVValue(KEY1, "testPropValUpdate");
CountDownLatch latch = this.context.getBean("countDownLatch1", CountDownLatch.class);
boolean receivedEvent = latch.await(15, TimeUnit.SECONDS);
assertThat("listener didn't receive event", receivedEvent, is(true));
testProp = this.environment.getProperty(TEST_PROP_CANONICAL);
assertThat("testProp was wrong after update", testProp, is(equalTo("testPropValUpdate")));
}
@Test
@Ignore // FIXME broken tests with boot 2.0.0
public void contextDoesNotExistThenExists() throws Exception {
String testProp = this.environment.getProperty(TEST_PROP3_CANONICAL);
assertThat("testProp was wrong", testProp, is(nullValue()));
this.client.setKVValue(KEY3, "testPropValInsert");
CountDownLatch latch = this.context.getBean("countDownLatch2", CountDownLatch.class);
boolean receivedEvent = latch.await(15, TimeUnit.SECONDS);
assertThat("listener didn't receive event", receivedEvent, is(true));
testProp = this.environment.getProperty(TEST_PROP3_CANONICAL);
assertThat(TEST_PROP3 + " was wrong after update", testProp, is(equalTo("testPropValInsert")));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,67 +16,78 @@
package org.springframework.cloud.consul.config;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import java.util.Random;
import com.ecwid.consul.v1.ConsulClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.consul.ConsulProperties;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
public class ConsulPropertySourceTests {
private ConsulClient client;
private ConsulProperties properties;
private String prefix;
private String kvContext;
private String propertiesContext;
@Before
public void setup() {
properties = new ConsulProperties();
prefix = "consulPropertySourceTests" + new Random().nextInt(Integer.MAX_VALUE);
client = new ConsulClient(properties.getHost(), properties.getPort());
this.properties = new ConsulProperties();
this.prefix = "consulPropertySourceTests"
+ new Random().nextInt(Integer.MAX_VALUE);
this.client = new ConsulClient(this.properties.getHost(),
this.properties.getPort());
}
@After
public void teardown() {
client.deleteKVValues(prefix);
this.client.deleteKVValues(this.prefix);
}
@Test
public void testKv() {
// key value properties
kvContext = prefix + "/kv";
client.setKVValue(kvContext + "/fooprop", "fookvval");
client.setKVValue(prefix+"/kv"+"/bar/prop", "8080");
this.kvContext = this.prefix + "/kv";
this.client.setKVValue(this.kvContext + "/fooprop", "fookvval");
this.client.setKVValue(this.prefix + "/kv" + "/bar/prop", "8080");
ConsulPropertySource source = getConsulPropertySource(new ConsulConfigProperties(), kvContext);
ConsulPropertySource source = getConsulPropertySource(
new ConsulConfigProperties(), this.kvContext);
assertProperties(source, "fookvval", "8080");
}
private void assertProperties(ConsulPropertySource source, Object fooval, Object barval) {
assertThat("fooprop was wrong", source.getProperty("fooprop"), is(equalTo(fooval)));
assertThat("bar.prop was wrong", source.getProperty("bar.prop"), is(equalTo(barval)));
private void assertProperties(ConsulPropertySource source, Object fooval,
Object barval) {
assertThat(source.getProperty("fooprop")).as("fooprop was wrong")
.isEqualTo(fooval);
assertThat(source.getProperty("bar.prop")).as("bar.prop was wrong")
.isEqualTo(barval);
}
@Test
public void testProperties() {
// properties file property
propertiesContext = prefix + "/properties";
client.setKVValue(propertiesContext+"/data", "fooprop=foopropval\nbar.prop=8080");
this.propertiesContext = this.prefix + "/properties";
this.client.setKVValue(this.propertiesContext + "/data",
"fooprop=foopropval\nbar.prop=8080");
ConsulConfigProperties configProperties = new ConsulConfigProperties();
configProperties.setFormat(ConsulConfigProperties.Format.PROPERTIES);
ConsulPropertySource source = getConsulPropertySource(configProperties, propertiesContext);
ConsulPropertySource source = getConsulPropertySource(configProperties,
this.propertiesContext);
assertProperties(source, "foopropval", "8080");
}
@@ -84,12 +95,14 @@ public class ConsulPropertySourceTests {
@Test
public void testYaml() {
// yaml file property
String yamlContext = prefix + "/yaml";
client.setKVValue(yamlContext+"/data", "fooprop: fooymlval\nbar:\n prop: 8080");
String yamlContext = this.prefix + "/yaml";
this.client.setKVValue(yamlContext + "/data",
"fooprop: fooymlval\nbar:\n prop: 8080");
ConsulConfigProperties configProperties = new ConsulConfigProperties();
configProperties.setFormat(ConsulConfigProperties.Format.YAML);
ConsulPropertySource source = getConsulPropertySource(configProperties, yamlContext);
ConsulPropertySource source = getConsulPropertySource(configProperties,
yamlContext);
assertProperties(source, "fooymlval", 8080);
}
@@ -97,22 +110,26 @@ public class ConsulPropertySourceTests {
@Test
public void testEmptyYaml() {
// yaml file property
String yamlContext = prefix + "/yaml";
client.setKVValue(yamlContext+"/data", "");
String yamlContext = this.prefix + "/yaml";
this.client.setKVValue(yamlContext + "/data", "");
ConsulConfigProperties configProperties = new ConsulConfigProperties();
configProperties.setFormat(ConsulConfigProperties.Format.YAML);
ConsulPropertySource source = new ConsulPropertySource(yamlContext, client, configProperties);
ConsulPropertySource source = new ConsulPropertySource(yamlContext, this.client,
configProperties);
// Should NOT throw a NPE
source.init();
}
private ConsulPropertySource getConsulPropertySource(ConsulConfigProperties configProperties, String context) {
ConsulPropertySource source = new ConsulPropertySource(context, client, configProperties);
private ConsulPropertySource getConsulPropertySource(
ConsulConfigProperties configProperties, String context) {
ConsulPropertySource source = new ConsulPropertySource(context, this.client,
configProperties);
source.init();
String[] names = source.getPropertyNames();
assertThat("names was null", names, is(notNullValue()));
assertThat("names was wrong size", names.length, is(equalTo(2)));
assertThat(names).as("names was null").isNotNull();
assertThat(names.length).as("names was wrong size").isEqualTo(2);
return source;
}
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,26 +22,46 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.ecwid.consul.v1.ConsulClient;
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Conditional;
/**
* When both property and consul classes are on the classpath.
* @author Spencer Gibb
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(ConditionalOnConsulEnabled.OnConsulEnabledCondition.class)
public @interface ConditionalOnConsulEnabled {
/**
* Verifies multiple conditions to see if Consul should be enabled.
*/
class OnConsulEnabledCondition extends AllNestedConditions {
public OnConsulEnabledCondition() {
OnConsulEnabledCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
/**
* Consul property is enabled.
*/
@ConditionalOnProperty(value = "spring.cloud.consul.enabled", matchIfMissing = true)
static class FoundProperty {}
static class FoundProperty {
}
/**
* Consul client class found.
*/
@ConditionalOnClass(ConsulClient.class)
static class FoundClass {}
static class FoundClass {
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.cloud.consul;
import com.ecwid.consul.transport.TLSConfig;
import com.ecwid.consul.v1.ConsulClient;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@@ -33,8 +34,6 @@ import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.interceptor.RetryInterceptorBuilder;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
import com.ecwid.consul.v1.ConsulClient;
import org.springframework.util.StringUtils;
/**
@@ -61,13 +60,9 @@ public class ConsulAutoConfiguration {
if (consulProperties.getTls() != null) {
ConsulProperties.TLSConfig tls = consulProperties.getTls();
TLSConfig tlsConfig = new TLSConfig(
tls.getKeyStoreInstanceType(),
tls.getCertificatePath(),
tls.getCertificatePassword(),
tls.getKeyStorePath(),
tls.getKeyStorePassword()
);
TLSConfig tlsConfig = new TLSConfig(tls.getKeyStoreInstanceType(),
tls.getCertificatePath(), tls.getCertificatePassword(),
tls.getKeyStorePath(), tls.getKeyStorePassword());
return new ConsulClient(agentHost, agentPort, tlsConfig);
}
return new ConsulClient(agentHost, agentPort);
@@ -90,6 +85,7 @@ public class ConsulAutoConfiguration {
public ConsulHealthIndicator consulHealthIndicator(ConsulClient consulClient) {
return new ConsulHealthIndicator(consulClient);
}
}
@ConditionalOnClass({ Retryable.class, Aspect.class, AopAutoConfiguration.class })
@@ -103,11 +99,12 @@ public class ConsulAutoConfiguration {
@ConditionalOnMissingBean(name = "consulRetryInterceptor")
public RetryOperationsInterceptor consulRetryInterceptor(
RetryProperties properties) {
return RetryInterceptorBuilder
.stateless()
return RetryInterceptorBuilder.stateless()
.backOffOptions(properties.getInitialInterval(),
properties.getMultiplier(), properties.getMaxInterval())
.maxAttempts(properties.getMaxAttempts()).build();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,25 +47,30 @@ public class ConsulEndpoint {
public ConsulData invoke() {
ConsulData data = new ConsulData();
// data.setKeyValues(kvClient.getKeyValueRecurse());
Response<Map<String, Service>> agentServices = consul.getAgentServices();
Response<Map<String, Service>> agentServices = this.consul.getAgentServices();
data.setAgentServices(agentServices.getValue());
Response<Map<String, List<String>>> catalogServices = consul
Response<Map<String, List<String>>> catalogServices = this.consul
.getCatalogServices(QueryParams.DEFAULT);
for (String serviceId : catalogServices.getValue().keySet()) {
Response<List<CatalogService>> response = consul.getCatalogService(serviceId,
QueryParams.DEFAULT);
Response<List<CatalogService>> response = this.consul
.getCatalogService(serviceId, QueryParams.DEFAULT);
data.getCatalogServices().put(serviceId, response.getValue());
}
Response<List<Node>> catalogNodes = consul.getCatalogNodes(QueryParams.DEFAULT);
Response<List<Node>> catalogNodes = this.consul
.getCatalogNodes(QueryParams.DEFAULT);
data.setCatalogNodes(catalogNodes.getValue());
return data;
}
/**
* Represents Consul data related to catalog entries and agent servies.
*/
public static class ConsulData {
Map<String, List<CatalogService>> catalogServices = new LinkedHashMap<>();
Map<String, Service> agentServices;
@@ -79,22 +84,23 @@ public class ConsulEndpoint {
return this.catalogServices;
}
public void setCatalogServices(
Map<String, List<CatalogService>> catalogServices) {
this.catalogServices = catalogServices;
}
public Map<String, Service> getAgentServices() {
return this.agentServices;
}
public List<Node> getCatalogNodes() {
return this.catalogNodes;
}
public void setCatalogServices(Map<String, List<CatalogService>> catalogServices) {
this.catalogServices = catalogServices;
}
public void setAgentServices(Map<String, Service> agentServices) {
this.agentServices = agentServices;
}
public List<Node> getCatalogNodes() {
return this.catalogNodes;
}
public void setCatalogNodes(List<Node> catalogNodes) {
this.catalogNodes = catalogNodes;
}
@@ -102,10 +108,11 @@ public class ConsulEndpoint {
@Override
public String toString() {
return new ToStringCreator(this)
.append("catalogServices", catalogServices)
.append("agentServices", agentServices)
.append("catalogNodes", catalogNodes)
.toString();
.append("catalogServices", this.catalogServices)
.append("agentServices", this.agentServices)
.append("catalogNodes", this.catalogNodes).toString();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,13 +19,13 @@ package org.springframework.cloud.consul;
import java.util.List;
import java.util.Map;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
/**
* @author Spencer Gibb
*/
@@ -39,10 +39,11 @@ public class ConsulHealthIndicator extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
final Response<String> leaderStatus = consul.getStatusLeader();
final Response<Map<String, List<String>>> services = consul
final Response<String> leaderStatus = this.consul.getStatusLeader();
final Response<Map<String, List<String>>> services = this.consul
.getCatalogServices(QueryParams.DEFAULT);
builder.up().withDetail("leader", leaderStatus.getValue()).withDetail("services",
services.getValue());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,26 +30,29 @@ import org.springframework.validation.annotation.Validated;
@ConfigurationProperties("spring.cloud.consul")
@Validated
public class ConsulProperties {
/** Consul agent hostname. Defaults to 'localhost'. */
@NotNull
private String host = "localhost";
/** Consul agent scheme (HTTP/HTTPS). If there is no scheme in address - client will use HTTP. */
/**
* Consul agent scheme (HTTP/HTTPS). If there is no scheme in address - client will
* use HTTP.
*/
private String scheme;
/** Consul agent port. Defaults to '8500'. */
@NotNull
private int port = 8500;
/** Is spring cloud consul enabled */
/** Is spring cloud consul enabled. */
private boolean enabled = true;
/** configuration for TLS */
/** configuration for TLS. */
private TLSConfig tls;
public String getHost() {
return host;
return this.host;
}
public void setHost(String host) {
@@ -57,7 +60,7 @@ public class ConsulProperties {
}
public int getPort() {
return port;
return this.port;
}
public void setPort(int port) {
@@ -65,7 +68,7 @@ public class ConsulProperties {
}
public boolean isEnabled() {
return enabled;
return this.enabled;
}
public void setEnabled(boolean enabled) {
@@ -73,7 +76,7 @@ public class ConsulProperties {
}
public String getScheme() {
return scheme;
return this.scheme;
}
public void setScheme(String scheme) {
@@ -81,7 +84,7 @@ public class ConsulProperties {
}
public TLSConfig getTls() {
return tls;
return this.tls;
}
public void setTls(TLSConfig tls) {
@@ -90,26 +93,26 @@ public class ConsulProperties {
@Override
public String toString() {
return "ConsulProperties{" +
"host='" + host + '\'' +
", port=" + port +
", scheme=" + scheme +
", tls=" + tls +
", enabled=" + enabled +
'}';
return "ConsulProperties{" + "host='" + this.host + '\'' + ", port=" + this.port
+ ", scheme=" + this.scheme + ", tls=" + this.tls + ", enabled="
+ this.enabled + '}';
}
/**
* TLS configuration.
*/
public static class TLSConfig {
/** Type of key framework to use. */
private KeyStoreInstanceType keyStoreInstanceType;
/** Path to an external keystore */
/** Path to an external keystore. */
private String keyStorePath;
/** Password to an external keystore */
/** Password to an external keystore. */
private String keyStorePassword;
/**File path to the certificate. */
/** File path to the certificate. */
private String certificatePath;
/** Password to open the certificate. */
@@ -118,7 +121,9 @@ public class ConsulProperties {
public TLSConfig() {
}
public TLSConfig(KeyStoreInstanceType keyStoreInstanceType, String keyStorePath, String keyStorePassword, String certificatePath, String certificatePassword) {
public TLSConfig(KeyStoreInstanceType keyStoreInstanceType, String keyStorePath,
String keyStorePassword, String certificatePath,
String certificatePassword) {
this.keyStoreInstanceType = keyStoreInstanceType;
this.keyStorePath = keyStorePath;
this.keyStorePassword = keyStorePassword;
@@ -127,7 +132,7 @@ public class ConsulProperties {
}
public KeyStoreInstanceType getKeyStoreInstanceType() {
return keyStoreInstanceType;
return this.keyStoreInstanceType;
}
public void setKeyStoreInstanceType(KeyStoreInstanceType keyStoreInstanceType) {
@@ -135,7 +140,7 @@ public class ConsulProperties {
}
public String getKeyStorePath() {
return keyStorePath;
return this.keyStorePath;
}
public void setKeyStorePath(String keyStorePath) {
@@ -143,7 +148,7 @@ public class ConsulProperties {
}
public String getKeyStorePassword() {
return keyStorePassword;
return this.keyStorePassword;
}
public void setKeyStorePassword(String keyStorePassword) {
@@ -151,7 +156,7 @@ public class ConsulProperties {
}
public String getCertificatePath() {
return certificatePath;
return this.certificatePath;
}
public void setCertificatePath(String certificatePath) {
@@ -159,7 +164,7 @@ public class ConsulProperties {
}
public String getCertificatePassword() {
return certificatePassword;
return this.certificatePassword;
}
public void setCertificatePassword(String certificatePassword) {
@@ -169,12 +174,13 @@ public class ConsulProperties {
@Override
public String toString() {
return new ToStringCreator(this)
.append("keyStoreInstanceType", keyStoreInstanceType)
.append("keyStorePath", keyStorePath)
.append("keyStorePassword", keyStorePassword)
.append("certificatePath", certificatePath)
.append("certificatePassword", certificatePassword)
.toString();
.append("keyStoreInstanceType", this.keyStoreInstanceType)
.append("keyStorePath", this.keyStorePath)
.append("keyStorePassword", this.keyStorePassword)
.append("certificatePath", this.certificatePath)
.append("certificatePassword", this.certificatePassword).toString();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,41 +44,40 @@ public class RetryProperties {
return this.initialInterval;
}
public double getMultiplier() {
return this.multiplier;
}
public long getMaxInterval() {
return this.maxInterval;
}
public int getMaxAttempts() {
return this.maxAttempts;
}
public void setInitialInterval(long initialInterval) {
this.initialInterval = initialInterval;
}
public double getMultiplier() {
return this.multiplier;
}
public void setMultiplier(double multiplier) {
this.multiplier = multiplier;
}
public long getMaxInterval() {
return this.maxInterval;
}
public void setMaxInterval(long maxInterval) {
this.maxInterval = maxInterval;
}
public int getMaxAttempts() {
return this.maxAttempts;
}
public void setMaxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("initialInterval", initialInterval)
.append("multiplier", multiplier)
.append("maxInterval", maxInterval)
.append("maxAttempts", maxAttempts)
.toString();
return new ToStringCreator(this).append("initialInterval", this.initialInterval)
.append("multiplier", this.multiplier)
.append("maxInterval", this.maxInterval)
.append("maxAttempts", this.maxAttempts).toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,30 @@ package org.springframework.cloud.consul.model;
/**
* Gossip pool (serf) statuses. Created by nicu on 10.03.2015.
* @author Nicu Marasoiu
*/
public enum SerfStatusEnum {
StatusAlive(1), StatusLeaving(2), StatusLeft(3), StatusFailed(4);
/**
* Alive status.
*/
StatusAlive(1),
/**
* Leaving status.
*/
StatusLeaving(2),
/**
* Left status.
*/
StatusLeft(3),
/**
* Failed status.
*/
StatusFailed(4);
private final int code;
SerfStatusEnum(int code) {
@@ -28,7 +49,7 @@ public enum SerfStatusEnum {
}
public int getCode() {
return code;
return this.code;
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
package org.springframework.cloud.consul;
import com.ecwid.consul.transport.DefaultHttpsTransport;
@@ -18,11 +34,11 @@ import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"spring.cloud.consul.tls.key-store-instance-type=JKS",
@SpringBootTest(properties = { "spring.cloud.consul.tls.key-store-instance-type=JKS",
"spring.cloud.consul.tls.key-store-path=src/test/resources/server.jks",
"spring.cloud.consul.tls.key-store-password=letmein",
"spring.cloud.consul.tls.certificate-path=src/test/resources/trustStore.jks",
"spring.cloud.consul.tls.certificate-password=change_me", })
"spring.cloud.consul.tls.certificate-password=change_me" })
public class ConsulAutoConfigurationTests {
@Autowired
@@ -30,13 +46,19 @@ public class ConsulAutoConfigurationTests {
@Test
public void tlsConfigured() {
CatalogConsulClient client = (CatalogConsulClient) ReflectionTestUtils.getField(consulClient, "catalogClient");
ConsulRawClient rawClient = (ConsulRawClient) ReflectionTestUtils.getField(client, "rawClient");
HttpTransport httpTransport = (HttpTransport) ReflectionTestUtils.getField(rawClient, "httpTransport");
CatalogConsulClient client = (CatalogConsulClient) ReflectionTestUtils
.getField(this.consulClient, "catalogClient");
ConsulRawClient rawClient = (ConsulRawClient) ReflectionTestUtils.getField(client,
"rawClient");
HttpTransport httpTransport = (HttpTransport) ReflectionTestUtils
.getField(rawClient, "httpTransport");
assertThat(httpTransport).isInstanceOf(DefaultHttpsTransport.class);
}
@EnableAutoConfiguration
@SpringBootConfiguration
protected static class TestConfig {}
protected static class TestConfig {
}
}

View File

@@ -1,9 +1,24 @@
package org.springframework.cloud.consul;
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
import static org.junit.Assert.assertEquals;
package org.springframework.cloud.consul;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.actuate.health.HealthEndpoint;
@@ -12,6 +27,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Lomesh Patel (lomeshpatel)
*/
@@ -24,12 +41,14 @@ public class ConsulHealthIndicatorDownTest {
@Test
public void doHealthCheck() {
assertEquals("health status was not DOWN", Status.DOWN,
healthEndpoint.health().getStatus());
assertThat(this.healthEndpoint.health().getStatus())
.as("health status was not DOWN").isEqualTo(Status.DOWN);
}
@EnableAutoConfiguration
@SpringBootConfiguration
protected static class TestConfig {
}
}
}

View File

@@ -1,9 +1,24 @@
package org.springframework.cloud.consul;
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
import static org.junit.Assert.assertEquals;
package org.springframework.cloud.consul;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.actuate.health.HealthEndpoint;
@@ -12,6 +27,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Lomesh Patel (lomeshpatel)
*/
@@ -24,12 +41,14 @@ public class ConsulHealthIndicatorUpTest {
@Test
public void doHealthCheck() {
assertEquals("health status was not UP", Status.UP,
healthEndpoint.health().getStatus());
assertThat(this.healthEndpoint.health().getStatus())
.as("health status was not UP").isEqualTo(Status.UP);
}
@EnableAutoConfiguration
@SpringBootConfiguration
protected static class TestConfig {
}
}
}

View File

@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>
<parent>
<artifactId>spring-cloud-dependencies-parent</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>2.1.3.BUILD-SNAPSHOT</version>
<relativePath/>
<relativePath/>
</parent>
<artifactId>spring-cloud-consul-dependencies</artifactId>
<version>2.1.1.BUILD-SNAPSHOT</version>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,20 +40,35 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
* @author Spencer Gibb
*/
public class ConsulCatalogWatch implements ApplicationEventPublisherAware, SmartLifecycle {
public class ConsulCatalogWatch
implements ApplicationEventPublisherAware, SmartLifecycle {
private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class);
private final ConsulDiscoveryProperties properties;
private final ConsulClient consul;
private final TaskScheduler taskScheduler;
private final AtomicReference<BigInteger> catalogServicesIndex = new AtomicReference<>();
private final AtomicBoolean running = new AtomicBoolean(false);
private ApplicationEventPublisher publisher;
private ScheduledFuture<?> watchFuture;
public ConsulCatalogWatch(ConsulDiscoveryProperties properties, ConsulClient consul) {
this(properties, consul, getTaskScheduler());
}
}
public ConsulCatalogWatch(ConsulDiscoveryProperties properties, ConsulClient consul,
TaskScheduler taskScheduler) {
this.properties = properties;
this.consul = consul;
this.taskScheduler = taskScheduler;
}
private static ThreadPoolTaskScheduler getTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
@@ -61,12 +76,6 @@ public class ConsulCatalogWatch implements ApplicationEventPublisherAware, Smart
return taskScheduler;
}
public ConsulCatalogWatch(ConsulDiscoveryProperties properties, ConsulClient consul, TaskScheduler taskScheduler) {
this.properties = properties;
this.consul = consul;
this.taskScheduler = taskScheduler;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
@@ -86,7 +95,8 @@ public class ConsulCatalogWatch implements ApplicationEventPublisherAware, Smart
@Override
public void start() {
if (this.running.compareAndSet(false, true)) {
this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(this::catalogServicesWatch,
this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(
this::catalogServicesWatch,
this.properties.getCatalogServicesWatchDelay());
}
}
@@ -108,30 +118,32 @@ public class ConsulCatalogWatch implements ApplicationEventPublisherAware, Smart
return 0;
}
@Timed(value ="consul.watch-catalog-services")
@Timed("consul.watch-catalog-services")
public void catalogServicesWatch() {
try {
long index = -1;
if (catalogServicesIndex.get() != null) {
index = catalogServicesIndex.get().longValue();
if (this.catalogServicesIndex.get() != null) {
index = this.catalogServicesIndex.get().longValue();
}
Response<Map<String, List<String>>> response = consul
.getCatalogServices(new QueryParams(properties
.getCatalogServicesWatchTimeout(), index), properties.getAclToken());
Response<Map<String, List<String>>> response = this.consul.getCatalogServices(
new QueryParams(this.properties.getCatalogServicesWatchTimeout(),
index),
this.properties.getAclToken());
Long consulIndex = response.getConsulIndex();
if (consulIndex != null) {
catalogServicesIndex.set(BigInteger.valueOf(consulIndex));
this.catalogServicesIndex.set(BigInteger.valueOf(consulIndex));
}
if (log.isTraceEnabled()) {
log.trace("Received services update from consul: "+response.getValue()
+", index: "+ consulIndex);
log.trace("Received services update from consul: " + response.getValue()
+ ", index: " + consulIndex);
}
publisher.publishEvent(new HeartbeatEvent(this, consulIndex));
this.publisher.publishEvent(new HeartbeatEvent(this, consulIndex));
}
catch (Exception e) {
log.error("Error watching Consul CatalogServices", e);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,16 +44,12 @@ public class ConsulDiscoveryClient implements DiscoveryClient {
private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class);
@Deprecated
public interface LocalResolver {
String getInstanceId();
Integer getPort();
}
private final ConsulClient client;
private final ConsulDiscoveryProperties properties;
public ConsulDiscoveryClient(ConsulClient client, ConsulDiscoveryProperties properties) {
public ConsulDiscoveryClient(ConsulClient client,
ConsulDiscoveryProperties properties) {
this.client = client;
this.properties = properties;
}
@@ -80,15 +76,15 @@ public class ConsulDiscoveryClient implements DiscoveryClient {
private void addInstancesToList(List<ServiceInstance> instances, String serviceId,
QueryParams queryParams) {
String aclToken = properties.getAclToken();
String aclToken = this.properties.getAclToken();
Response<List<HealthService>> services;
if (StringUtils.hasText(aclToken)) {
services = client.getHealthServices(serviceId,
services = this.client.getHealthServices(serviceId,
this.properties.getDefaultQueryTag(),
this.properties.isQueryPassing(), queryParams, aclToken);
}
else {
services = client.getHealthServices(serviceId,
services = this.client.getHealthServices(serviceId,
this.properties.getDefaultQueryTag(),
this.properties.isQueryPassing(), queryParams);
}
@@ -100,15 +96,15 @@ public class ConsulDiscoveryClient implements DiscoveryClient {
if (metadata.containsKey("secure")) {
secure = Boolean.parseBoolean(metadata.get("secure"));
}
instances.add(new DefaultServiceInstance(service.getService().getId(), serviceId, host, service
.getService().getPort(), secure, metadata));
instances.add(new DefaultServiceInstance(service.getService().getId(),
serviceId, host, service.getService().getPort(), secure, metadata));
}
}
public List<ServiceInstance> getAllInstances() {
List<ServiceInstance> instances = new ArrayList<>();
Response<Map<String, List<String>>> services = client
Response<Map<String, List<String>>> services = this.client
.getCatalogServices(QueryParams.DEFAULT);
for (String serviceId : services.getValue().keySet()) {
addInstancesToList(instances, serviceId, QueryParams.DEFAULT);
@@ -118,14 +114,16 @@ public class ConsulDiscoveryClient implements DiscoveryClient {
@Override
public List<String> getServices() {
String aclToken = properties.getAclToken();
String aclToken = this.properties.getAclToken();
if (StringUtils.hasText(aclToken)) {
return new ArrayList<>(client.getCatalogServices(QueryParams.DEFAULT, aclToken).getValue()
.keySet());
} else {
return new ArrayList<>(client.getCatalogServices(QueryParams.DEFAULT).getValue()
.keySet());
return new ArrayList<>(
this.client.getCatalogServices(QueryParams.DEFAULT, aclToken)
.getValue().keySet());
}
else {
return new ArrayList<>(this.client.getCatalogServices(QueryParams.DEFAULT)
.getValue().keySet());
}
}
@@ -133,4 +131,17 @@ public class ConsulDiscoveryClient implements DiscoveryClient {
public int getOrder() {
return this.properties.getOrder();
}
/**
* Depreacted local resolver.
*/
@Deprecated
public interface LocalResolver {
String getInstanceId();
Integer getPort();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,6 +45,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
CommonsClientAutoConfiguration.class })
public class ConsulDiscoveryClientConfiguration {
/**
* Name of the catalog watch task scheduler bean.
*/
public static final String CATALOG_WATCH_TASK_SCHEDULER_NAME = "catalogWatchTaskScheduler";
@Autowired
@@ -53,29 +56,30 @@ public class ConsulDiscoveryClientConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty("spring.cloud.consul.discovery.heartbeat.enabled")
//TODO: move to service-registry for Edgware
// TODO: move to service-registry for Edgware
public TtlScheduler ttlScheduler(HeartbeatProperties heartbeatProperties) {
return new TtlScheduler(heartbeatProperties, consulClient);
return new TtlScheduler(heartbeatProperties, this.consulClient);
}
@Bean
@ConditionalOnMissingBean
//TODO: move to service-registry for Edgware
// TODO: move to service-registry for Edgware
public HeartbeatProperties heartbeatProperties() {
return new HeartbeatProperties();
}
@Bean
@ConditionalOnMissingBean
//TODO: Split appropriate values to service-registry for Edgware
// TODO: Split appropriate values to service-registry for Edgware
public ConsulDiscoveryProperties consulDiscoveryProperties(InetUtils inetUtils) {
return new ConsulDiscoveryProperties(inetUtils);
}
@Bean
@ConditionalOnMissingBean
public ConsulDiscoveryClient consulDiscoveryClient(ConsulDiscoveryProperties discoveryProperties) {
return new ConsulDiscoveryClient(consulClient, discoveryProperties);
public ConsulDiscoveryClient consulDiscoveryClient(
ConsulDiscoveryProperties discoveryProperties) {
return new ConsulDiscoveryClient(this.consulClient, discoveryProperties);
}
@Bean
@@ -84,7 +88,8 @@ public class ConsulDiscoveryClientConfiguration {
public ConsulCatalogWatch consulCatalogWatch(
ConsulDiscoveryProperties discoveryProperties,
@Qualifier(CATALOG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) {
return new ConsulCatalogWatch(discoveryProperties, consulClient, taskScheduler);
return new ConsulCatalogWatch(discoveryProperties, this.consulClient,
taskScheduler);
}
@Bean(name = CATALOG_WATCH_TASK_SCHEDULER_NAME)
@@ -92,4 +97,5 @@ public class ConsulDiscoveryClientConfiguration {
public TaskScheduler catalogWatchTaskScheduler() {
return new ThreadPoolTaskScheduler();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,17 +16,17 @@
package org.springframework.cloud.consul.discovery;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtils.HostInfo;
import org.springframework.core.style.ToStringCreator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Defines configuration for service discovery and registration.
*
@@ -45,22 +45,22 @@ public class ConsulDiscoveryProperties {
@Value("${consul.token:${CONSUL_TOKEN:${spring.cloud.consul.token:${SPRING_CLOUD_CONSUL_TOKEN:}}}}")
private String aclToken;
/** Tags to use when registering service */
/** Tags to use when registering service. */
private List<String> tags = new ArrayList<>();
/** Is service discovery enabled? */
private boolean enabled = true;
/** Tags to use when registering management service */
/** Tags to use when registering management service. */
private List<String> managementTags = new ArrayList<>();
/** Alternate server path to invoke for health checking */
/** Alternate server path to invoke for health checking. */
private String healthCheckPath = "/actuator/health";
/** Custom health check url to override default */
/** Custom health check url to override default. */
private String healthCheckUrl;
/** Headers to be applied to the Health Check calls */
/** Headers to be applied to the Health Check calls. */
private Map<String, List<String>> healthCheckHeaders = new HashMap<>();
/** How often to perform the health check (e.g. 10s), defaults to 10s. */
@@ -75,24 +75,26 @@ public class ConsulDiscoveryProperties {
*/
private String healthCheckCriticalTimeout;
/** IP address to use when accessing service (must also set preferIpAddress to use) */
/**
* IP address to use when accessing service (must also set preferIpAddress to use).
*/
private String ipAddress;
/** Hostname to use when accessing server */
/** Hostname to use when accessing server. */
private String hostname;
/** Port to register the service under (defaults to listening port) */
/** Port to register the service under (defaults to listening port). */
private Integer port;
/** Port to register the management service under (defaults to management port) */
/** Port to register the management service under (defaults to management port). */
private Integer managementPort;
private Lifecycle lifecycle = new Lifecycle();
/** Use ip address rather than hostname during registration */
/** Use ip address rather than hostname during registration. */
private boolean preferIpAddress = false;
/** Source of how we will determine the address to use */
/** Source of how we will determine the address to use. */
private boolean preferAgentAddress = false;
/** The delay between calls to watch consul catalog in millis, default is 1000. */
@@ -101,40 +103,39 @@ public class ConsulDiscoveryProperties {
/** The number of seconds to block while watching consul catalog, default is 2. */
private int catalogServicesWatchTimeout = 2;
/** Service name */
/** Service name. */
private String serviceName;
/** Unique service instance id */
/** Unique service instance id. */
private String instanceId;
/** Service instance zone */
/** Service instance zone. */
private String instanceZone;
/** Service instance group*/
/** Service instance group. */
private String instanceGroup;
/**
* Service instance zone comes from metadata.
* This allows changing the metadata tag name.
* Service instance zone comes from metadata. This allows changing the metadata tag
* name.
*/
private String defaultZoneMetadataName = "zone";
/** Whether to register an http or https service */
/** Whether to register an http or https service. */
private String scheme = "http";
/** Suffix to use when registering management service */
/** Suffix to use when registering management service. */
private String managementSuffix = MANAGEMENT;
/**
* Map of serviceId's -> tag to query for in server list.
* This allows filtering services by a single tag.
* Map of serviceId's -> tag to query for in server list. This allows filtering
* services by a single tag.
*/
private Map<String, String> serverListQueryTags = new HashMap<>();
/**
* Map of serviceId's -> datacenter to query for in server list.
* This allows looking up services in another datacenters.
* Map of serviceId's -> datacenter to query for in server list. This allows looking
* up services in another datacenters.
*/
private Map<String, String> datacenters = new HashMap<>();
@@ -142,8 +143,8 @@ public class ConsulDiscoveryProperties {
private String defaultQueryTag;
/**
* Add the 'passing` parameter to /v1/health/service/serviceName.
* This pushes health check passing to the server.
* Add the 'passing` parameter to /v1/health/service/serviceName. This pushes health
* check passing to the server.
*/
private boolean queryPassing = false;
@@ -157,19 +158,20 @@ public class ConsulDiscoveryProperties {
private boolean registerHealthCheck = true;
/**
* Throw exceptions during service registration if true, otherwise, log
* warnings (defaults to true).
* Throw exceptions during service registration if true, otherwise, log warnings
* (defaults to true).
*/
private boolean failFast = true;
/**
* Skips certificate verification during service checks if true, otherwise
* runs certificate verification.
* Skips certificate verification during service checks if true, otherwise runs
* certificate verification.
*/
private Boolean healthCheckTlsSkipVerify;
/**
* Order of the discovery client used by `CompositeDiscoveryClient` for sorting available clients.
* Order of the discovery client used by `CompositeDiscoveryClient` for sorting
* available clients.
*/
private int order = 0;
@@ -189,9 +191,9 @@ public class ConsulDiscoveryProperties {
* @param serviceId The service who's filtering tag is being looked up
* @return The tag the given service id should be filtered by, or null.
*/
public String getQueryTagForService(String serviceId){
String tag = serverListQueryTags.get(serviceId);
return tag != null ? tag : defaultQueryTag;
public String getQueryTagForService(String serviceId) {
String tag = this.serverListQueryTags.get(serviceId);
return tag != null ? tag : this.defaultQueryTag;
}
public String getHostname() {
@@ -203,13 +205,8 @@ public class ConsulDiscoveryProperties {
this.hostInfo.override = true;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
this.hostInfo.override = true;
}
private HostInfo getHostInfo() {
return hostInfo;
return this.hostInfo;
}
private void setHostInfo(HostInfo hostInfo) {
@@ -217,7 +214,7 @@ public class ConsulDiscoveryProperties {
}
public String getAclToken() {
return aclToken;
return this.aclToken;
}
public void setAclToken(String aclToken) {
@@ -225,7 +222,7 @@ public class ConsulDiscoveryProperties {
}
public List<String> getTags() {
return tags;
return this.tags;
}
public void setTags(List<String> tags) {
@@ -233,7 +230,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isEnabled() {
return enabled;
return this.enabled;
}
public void setEnabled(boolean enabled) {
@@ -241,7 +238,7 @@ public class ConsulDiscoveryProperties {
}
public List<String> getManagementTags() {
return managementTags;
return this.managementTags;
}
public void setManagementTags(List<String> managementTags) {
@@ -249,7 +246,7 @@ public class ConsulDiscoveryProperties {
}
public String getHealthCheckPath() {
return healthCheckPath;
return this.healthCheckPath;
}
public void setHealthCheckPath(String healthCheckPath) {
@@ -257,7 +254,7 @@ public class ConsulDiscoveryProperties {
}
public String getHealthCheckUrl() {
return healthCheckUrl;
return this.healthCheckUrl;
}
public void setHealthCheckUrl(String healthCheckUrl) {
@@ -265,7 +262,7 @@ public class ConsulDiscoveryProperties {
}
public Map<String, List<String>> getHealthCheckHeaders() {
return healthCheckHeaders;
return this.healthCheckHeaders;
}
public void setHealthCheckHeaders(Map<String, List<String>> healthCheckHeaders) {
@@ -273,7 +270,7 @@ public class ConsulDiscoveryProperties {
}
public String getHealthCheckInterval() {
return healthCheckInterval;
return this.healthCheckInterval;
}
public void setHealthCheckInterval(String healthCheckInterval) {
@@ -281,7 +278,7 @@ public class ConsulDiscoveryProperties {
}
public String getHealthCheckTimeout() {
return healthCheckTimeout;
return this.healthCheckTimeout;
}
public void setHealthCheckTimeout(String healthCheckTimeout) {
@@ -289,7 +286,7 @@ public class ConsulDiscoveryProperties {
}
public String getHealthCheckCriticalTimeout() {
return healthCheckCriticalTimeout;
return this.healthCheckCriticalTimeout;
}
public void setHealthCheckCriticalTimeout(String healthCheckCriticalTimeout) {
@@ -297,11 +294,16 @@ public class ConsulDiscoveryProperties {
}
public String getIpAddress() {
return ipAddress;
return this.ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
this.hostInfo.override = true;
}
public Integer getPort() {
return port;
return this.port;
}
public void setPort(Integer port) {
@@ -309,7 +311,7 @@ public class ConsulDiscoveryProperties {
}
public Integer getManagementPort() {
return managementPort;
return this.managementPort;
}
public void setManagementPort(Integer managementPort) {
@@ -317,7 +319,7 @@ public class ConsulDiscoveryProperties {
}
public Lifecycle getLifecycle() {
return lifecycle;
return this.lifecycle;
}
public void setLifecycle(Lifecycle lifecycle) {
@@ -325,7 +327,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isPreferIpAddress() {
return preferIpAddress;
return this.preferIpAddress;
}
public void setPreferIpAddress(boolean preferIpAddress) {
@@ -333,7 +335,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isPreferAgentAddress() {
return preferAgentAddress;
return this.preferAgentAddress;
}
public void setPreferAgentAddress(boolean preferAgentAddress) {
@@ -341,7 +343,7 @@ public class ConsulDiscoveryProperties {
}
public int getCatalogServicesWatchDelay() {
return catalogServicesWatchDelay;
return this.catalogServicesWatchDelay;
}
public void setCatalogServicesWatchDelay(int catalogServicesWatchDelay) {
@@ -349,7 +351,7 @@ public class ConsulDiscoveryProperties {
}
public int getCatalogServicesWatchTimeout() {
return catalogServicesWatchTimeout;
return this.catalogServicesWatchTimeout;
}
public void setCatalogServicesWatchTimeout(int catalogServicesWatchTimeout) {
@@ -357,7 +359,7 @@ public class ConsulDiscoveryProperties {
}
public String getServiceName() {
return serviceName;
return this.serviceName;
}
public void setServiceName(String serviceName) {
@@ -365,7 +367,7 @@ public class ConsulDiscoveryProperties {
}
public String getInstanceId() {
return instanceId;
return this.instanceId;
}
public void setInstanceId(String instanceId) {
@@ -373,7 +375,7 @@ public class ConsulDiscoveryProperties {
}
public String getInstanceZone() {
return instanceZone;
return this.instanceZone;
}
public void setInstanceZone(String instanceZone) {
@@ -381,7 +383,7 @@ public class ConsulDiscoveryProperties {
}
public String getInstanceGroup() {
return instanceGroup;
return this.instanceGroup;
}
public void setInstanceGroup(String instanceGroup) {
@@ -389,7 +391,7 @@ public class ConsulDiscoveryProperties {
}
public String getDefaultZoneMetadataName() {
return defaultZoneMetadataName;
return this.defaultZoneMetadataName;
}
public void setDefaultZoneMetadataName(String defaultZoneMetadataName) {
@@ -397,7 +399,7 @@ public class ConsulDiscoveryProperties {
}
public String getScheme() {
return scheme;
return this.scheme;
}
public void setScheme(String scheme) {
@@ -405,7 +407,7 @@ public class ConsulDiscoveryProperties {
}
public String getManagementSuffix() {
return managementSuffix;
return this.managementSuffix;
}
public void setManagementSuffix(String managementSuffix) {
@@ -413,7 +415,7 @@ public class ConsulDiscoveryProperties {
}
public Map<String, String> getServerListQueryTags() {
return serverListQueryTags;
return this.serverListQueryTags;
}
public void setServerListQueryTags(Map<String, String> serverListQueryTags) {
@@ -421,7 +423,7 @@ public class ConsulDiscoveryProperties {
}
public Map<String, String> getDatacenters() {
return datacenters;
return this.datacenters;
}
public void setDatacenters(Map<String, String> datacenters) {
@@ -429,7 +431,7 @@ public class ConsulDiscoveryProperties {
}
public String getDefaultQueryTag() {
return defaultQueryTag;
return this.defaultQueryTag;
}
public void setDefaultQueryTag(String defaultQueryTag) {
@@ -437,7 +439,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isQueryPassing() {
return queryPassing;
return this.queryPassing;
}
public void setQueryPassing(boolean queryPassing) {
@@ -445,7 +447,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isRegister() {
return register;
return this.register;
}
public void setRegister(boolean register) {
@@ -453,7 +455,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isDeregister() {
return deregister;
return this.deregister;
}
public void setDeregister(boolean deregister) {
@@ -461,7 +463,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isRegisterHealthCheck() {
return registerHealthCheck;
return this.registerHealthCheck;
}
public void setRegisterHealthCheck(boolean registerHealthCheck) {
@@ -469,7 +471,7 @@ public class ConsulDiscoveryProperties {
}
public boolean isFailFast() {
return failFast;
return this.failFast;
}
public void setFailFast(boolean failFast) {
@@ -477,7 +479,7 @@ public class ConsulDiscoveryProperties {
}
public Boolean getHealthCheckTlsSkipVerify() {
return healthCheckTlsSkipVerify;
return this.healthCheckTlsSkipVerify;
}
public void setHealthCheckTlsSkipVerify(Boolean healthCheckTlsSkipVerify) {
@@ -485,7 +487,7 @@ public class ConsulDiscoveryProperties {
}
public int getOrder() {
return order;
return this.order;
}
public void setOrder(int order) {
@@ -494,52 +496,50 @@ public class ConsulDiscoveryProperties {
@Override
public String toString() {
return new ToStringCreator(this)
.append("hostInfo", hostInfo)
.append("aclToken", aclToken)
.append("tags", tags)
.append("enabled", enabled)
.append("managementTags", managementTags)
.append("healthCheckPath", healthCheckPath)
.append("healthCheckUrl", healthCheckUrl)
.append("healthCheckHeaders", healthCheckHeaders)
.append("healthCheckInterval", healthCheckInterval)
.append("healthCheckTimeout", healthCheckTimeout)
.append("healthCheckCriticalTimeout", healthCheckCriticalTimeout)
.append("ipAddress", ipAddress)
.append("hostname", hostname)
.append("port", port)
.append("managementPort", managementPort)
.append("lifecycle", lifecycle)
.append("preferIpAddress", preferIpAddress)
.append("preferAgentAddress", preferAgentAddress)
.append("catalogServicesWatchDelay", catalogServicesWatchDelay)
.append("catalogServicesWatchTimeout", catalogServicesWatchTimeout)
.append("serviceName", serviceName)
.append("instanceId", instanceId)
.append("instanceZone", instanceZone)
.append("instanceGroup", instanceGroup)
.append("defaultZoneMetadataName", defaultZoneMetadataName)
.append("scheme", scheme)
.append("managementSuffix", managementSuffix)
.append("serverListQueryTags", serverListQueryTags)
.append("datacenters", datacenters)
.append("defaultQueryTag", defaultQueryTag)
.append("queryPassing", queryPassing)
.append("register", register)
.append("deregister", deregister)
.append("registerHealthCheck", registerHealthCheck)
.append("failFast", failFast)
.append("healthCheckTlsSkipVerify", healthCheckTlsSkipVerify)
.append("order", order)
.toString();
return new ToStringCreator(this).append("hostInfo", this.hostInfo)
.append("aclToken", this.aclToken).append("tags", this.tags)
.append("enabled", this.enabled)
.append("managementTags", this.managementTags)
.append("healthCheckPath", this.healthCheckPath)
.append("healthCheckUrl", this.healthCheckUrl)
.append("healthCheckHeaders", this.healthCheckHeaders)
.append("healthCheckInterval", this.healthCheckInterval)
.append("healthCheckTimeout", this.healthCheckTimeout)
.append("healthCheckCriticalTimeout", this.healthCheckCriticalTimeout)
.append("ipAddress", this.ipAddress).append("hostname", this.hostname)
.append("port", this.port).append("managementPort", this.managementPort)
.append("lifecycle", this.lifecycle)
.append("preferIpAddress", this.preferIpAddress)
.append("preferAgentAddress", this.preferAgentAddress)
.append("catalogServicesWatchDelay", this.catalogServicesWatchDelay)
.append("catalogServicesWatchTimeout", this.catalogServicesWatchTimeout)
.append("serviceName", this.serviceName)
.append("instanceId", this.instanceId)
.append("instanceZone", this.instanceZone)
.append("instanceGroup", this.instanceGroup)
.append("defaultZoneMetadataName", this.defaultZoneMetadataName)
.append("scheme", this.scheme)
.append("managementSuffix", this.managementSuffix)
.append("serverListQueryTags", this.serverListQueryTags)
.append("datacenters", this.datacenters)
.append("defaultQueryTag", this.defaultQueryTag)
.append("queryPassing", this.queryPassing)
.append("register", this.register).append("deregister", this.deregister)
.append("registerHealthCheck", this.registerHealthCheck)
.append("failFast", this.failFast)
.append("healthCheckTlsSkipVerify", this.healthCheckTlsSkipVerify)
.append("order", this.order).toString();
}
/**
* Properties releated to the lifecycle.
*/
public static class Lifecycle {
private boolean enabled = true;
public boolean isEnabled() {
return enabled;
return this.enabled;
}
public void setEnabled(boolean enabled) {
@@ -548,9 +548,9 @@ public class ConsulDiscoveryProperties {
@Override
public String toString() {
return "Lifecycle{" +
"enabled=" + enabled +
'}';
return "Lifecycle{" + "enabled=" + this.enabled + '}';
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,11 +20,13 @@ import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.Server;
/**
* "Ping" Consul
* i.e. we dont do a real "ping". We just assume that the server is up if Consul says so
* "Ping" Consul i.e. we dont do a real "ping". We just assume that the server is up if
* Consul says so
*
* @author Spencer Gibb
*/
public class ConsulPing implements IPing {
@Override
public boolean isAlive(Server server) {
boolean isAlive = true;
@@ -36,4 +38,5 @@ public class ConsulPing implements IPing {
return isAlive;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,16 +47,17 @@ import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity
*/
@Configuration
public class ConsulRibbonClientConfiguration {
protected static final String VALUE_NOT_SET = "__not__set__";
protected static final String DEFAULT_NAMESPACE = "ribbon";
@Autowired
private ConsulClient client;
@Value("${ribbon.client.name}")
private String serviceId = "client";
protected static final String VALUE_NOT_SET = "__not__set__";
protected static final String DEFAULT_NAMESPACE = "ribbon";
public ConsulRibbonClientConfiguration() {
}
@@ -66,8 +67,9 @@ public class ConsulRibbonClientConfiguration {
@Bean
@ConditionalOnMissingBean
public ServerList<?> ribbonServerList(IClientConfig config, ConsulDiscoveryProperties properties) {
ConsulServerList serverList = new ConsulServerList(client, properties);
public ServerList<?> ribbonServerList(IClientConfig config,
ConsulDiscoveryProperties properties) {
ConsulServerList serverList = new ConsulServerList(this.client, properties);
serverList.initWithNiwsConfig(config);
return serverList;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,17 +30,19 @@ import static org.springframework.cloud.consul.discovery.ConsulServerUtils.findH
public class ConsulServer extends Server {
private final MetaInfo metaInfo;
private final HealthService service;
private final Map<String, String> metadata;
public ConsulServer(final HealthService healthService) {
super(findHost(healthService), healthService.getService().getPort());
this.service = healthService;
this.metadata = ConsulServerUtils.getMetadata(this.service);
metaInfo = new MetaInfo() {
this.metaInfo = new MetaInfo() {
@Override
public String getAppName() {
return service.getService().getService();
return ConsulServer.this.service.getService().getService();
}
@Override
@@ -55,7 +57,7 @@ public class ConsulServer extends Server {
@Override
public String getInstanceId() {
return service.getService().getId();
return ConsulServer.this.service.getService().getId();
}
};
@@ -64,7 +66,7 @@ public class ConsulServer extends Server {
@Override
public MetaInfo getMetaInfo() {
return metaInfo;
return this.metaInfo;
}
public HealthService getHealthService() {
@@ -72,7 +74,7 @@ public class ConsulServer extends Server {
}
public Map<String, String> getMetadata() {
return metadata;
return this.metadata;
}
public boolean isPassingChecks() {
@@ -83,4 +85,5 @@ public class ConsulServer extends Server {
}
return true;
}
}

View File

@@ -1,10 +1,30 @@
package org.springframework.cloud.consul.discovery;
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
import com.netflix.loadbalancer.Server;
import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector;
package org.springframework.cloud.consul.discovery;
import java.util.Map;
import com.netflix.loadbalancer.Server;
import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector;
/**
* @author Spencer Gibb
*/
public class ConsulServerIntrospector extends DefaultServerIntrospector {
@Override
@@ -24,4 +44,5 @@ public class ConsulServerIntrospector extends DefaultServerIntrospector {
}
return super.getMetadata(server);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ import com.netflix.loadbalancer.AbstractServerList;
public class ConsulServerList extends AbstractServerList<ConsulServer> {
private final ConsulClient client;
private final ConsulDiscoveryProperties properties;
private String serviceId;
@@ -44,15 +45,15 @@ public class ConsulServerList extends AbstractServerList<ConsulServer> {
}
protected ConsulClient getClient() {
return client;
return this.client;
}
protected ConsulDiscoveryProperties getProperties() {
return properties;
return this.properties;
}
protected String getServiceId() {
return serviceId;
return this.serviceId;
}
@Override
@@ -86,8 +87,8 @@ public class ConsulServerList extends AbstractServerList<ConsulServer> {
/**
* Transforms the response from Consul in to a list of usable {@link ConsulServer}s.
*
* @param healthServices the initial list of servers from Consul. Guaranteed to be non-empty list
* @param healthServices the initial list of servers from Consul. Guaranteed to be
* non-empty list
* @return ConsulServer instances
* @see ConsulServer#ConsulServer(HealthService)
*/
@@ -95,8 +96,10 @@ public class ConsulServerList extends AbstractServerList<ConsulServer> {
List<ConsulServer> servers = new ArrayList<>();
for (HealthService service : healthServices) {
ConsulServer server = new ConsulServer(service);
if (server.getMetadata().containsKey(this.properties.getDefaultZoneMetadataName())) {
server.setZone(server.getMetadata().get(this.properties.getDefaultZoneMetadataName()));
if (server.getMetadata()
.containsKey(this.properties.getDefaultZoneMetadataName())) {
server.setZone(server.getMetadata()
.get(this.properties.getDefaultZoneMetadataName()));
}
servers.add(server);
}
@@ -104,9 +107,9 @@ public class ConsulServerList extends AbstractServerList<ConsulServer> {
}
/**
* This method will create the {@link QueryParams} to use when retrieving the
* services from Consul. By default {@link QueryParams#DEFAULT} is used. In case
* a datacenter is specified for the current serviceId {@link QueryParams#datacenter} is set.
* This method will create the {@link QueryParams} to use when retrieving the services
* from Consul. By default {@link QueryParams#DEFAULT} is used. In case a datacenter
* is specified for the current serviceId {@link QueryParams#datacenter} is set.
* @return an instance of {@link QueryParams}
*/
protected QueryParams createQueryParamsForClientRequest() {
@@ -128,9 +131,10 @@ public class ConsulServerList extends AbstractServerList<ConsulServer> {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ConsulServerList{");
sb.append("serviceId='").append(serviceId).append('\'');
sb.append("serviceId='").append(this.serviceId).append('\'');
sb.append(", tag=").append(getTag());
sb.append('}');
return sb.toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,17 +34,22 @@ import org.springframework.util.StringUtils;
* @author Spencer Gibb
* @author Semenkov Alexey
*/
public class ConsulServerUtils {
public final class ConsulServerUtils {
private static final Log log = LogFactory.getLog(ConsulServerUtils.class);
private ConsulServerUtils() {
throw new IllegalStateException("Can't instantiate a utility class");
}
public static String findHost(HealthService healthService) {
HealthService.Service service = healthService.getService();
HealthService.Node node = healthService.getNode();
if (StringUtils.hasText(service.getAddress())) {
return fixIPv6Address(service.getAddress());
} else if (StringUtils.hasText(node.getAddress())) {
}
else if (StringUtils.hasText(node.getAddress())) {
return fixIPv6Address(node.getAddress());
}
return node.getNode();
@@ -57,13 +62,13 @@ public class ConsulServerUtils {
return "[" + inetAdr.getHostName() + "]";
}
return address;
} catch (UnknownHostException e) {
}
catch (UnknownHostException e) {
log.debug("Not InetAddress: " + address + " , resolved as is.");
return address;
}
}
public static Map<String, String> getMetadata(HealthService healthService) {
return getMetadata(healthService.getService().getTags());
}
@@ -74,18 +79,18 @@ public class ConsulServerUtils {
for (String tag : tags) {
String[] parts = StringUtils.delimitedListToStringArray(tag, "=");
switch (parts.length) {
case 0:
break;
case 1:
metadata.put(parts[0], parts[0]);
break;
case 2:
metadata.put(parts[0], parts[1]);
break;
default:
String[] end = Arrays.copyOfRange(parts, 1, parts.length);
metadata.put(parts[0], StringUtils.arrayToDelimitedString(end, "="));
break;
case 0:
break;
case 1:
metadata.put(parts[0], parts[0]);
break;
case 2:
metadata.put(parts[0], parts[1]);
break;
default:
String[] end = Arrays.copyOfRange(parts, 1, parts.length);
metadata.put(parts[0], StringUtils.arrayToDelimitedString(end, "="));
break;
}
}
@@ -93,4 +98,5 @@ public class ConsulServerUtils {
return metadata;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,10 +25,13 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* ServerList implementation that filters ConsulServers based on if all their Health Checks are PASSING.
* ServerList implementation that filters ConsulServers based on if all their Health
* Checks are PASSING.
*
* @author Spencer Gibb
*/
public class HealthServiceServerListFilter implements ServerListFilter<Server> {
private static final Log log = LogFactory.getLog(HealthServiceServerListFilter.class);
@Override
@@ -43,9 +46,11 @@ public class HealthServiceServerListFilter implements ServerListFilter<Server> {
filtered.add(server);
}
} else {
if (log.isDebugEnabled()) {
log.debug("Unable to determine aliveness of server type " + server.getClass() + ", " + server);
}
else {
if (log.isDebugEnabled()) {
log.debug("Unable to determine aliveness of server type "
+ server.getClass() + ", " + server);
}
filtered.add(server);
}
@@ -53,4 +58,5 @@ public class HealthServiceServerListFilter implements ServerListFilter<Server> {
return filtered;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,11 +28,18 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.style.ToStringCreator;
import org.springframework.validation.annotation.Validated;
/**
* Properties related to hearbeat verification.
*
* @author Spencer Gibb
*/
@ConfigurationProperties(prefix = "spring.cloud.consul.discovery.heartbeat")
@Validated
public class HeartbeatProperties {
private static final Log log = org.apache.commons.logging.LogFactory.getLog(HeartbeatProperties.class);
private static final Log log = org.apache.commons.logging.LogFactory
.getLog(HeartbeatProperties.class);
// TODO: change enabled to default to true when I stop seeing messages like
// [WARN] agent: Check 'service:testConsulApp:xtest:8080' missed TTL, is now critical
boolean enabled = false;
@@ -47,63 +54,62 @@ public class HeartbeatProperties {
@DecimalMax("0.9")
private double intervalRatio = 2.0 / 3.0;
//TODO: did heartbeatInterval need to be a field?
// TODO: did heartbeatInterval need to be a field?
protected Period computeHearbeatInterval() {
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
// priority), no sooner than 1s from now
double interval = ttlValue * intervalRatio;
double max = Math.max(interval, 1);
int ttlMinus1 = ttlValue - 1;
double min = Math.min(ttlMinus1, max);
protected Period computeHearbeatInterval() {
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
// priority), no sooner than 1s from now
double interval = this.ttlValue * this.intervalRatio;
double max = Math.max(interval, 1);
int ttlMinus1 = this.ttlValue - 1;
double min = Math.min(ttlMinus1, max);
Period heartbeatInterval = new Period(Math.round(1000 * min));
log.debug("Computed heartbeatInterval: " + heartbeatInterval);
return heartbeatInterval;
}
}
public String getTtl() {
return ttlValue + ttlUnit;
public String getTtl() {
return this.ttlValue + this.ttlUnit;
}
public boolean isEnabled() {
return this.enabled;
}
public @Min(1) int getTtlValue() {
return this.ttlValue;
}
public @NotNull String getTtlUnit() {
return this.ttlUnit;
}
public @DecimalMin("0.1") @DecimalMax("0.9") double getIntervalRatio() {
return this.intervalRatio;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public @Min(1) int getTtlValue() {
return this.ttlValue;
}
public void setTtlValue(@Min(1) int ttlValue) {
this.ttlValue = ttlValue;
}
public @NotNull String getTtlUnit() {
return this.ttlUnit;
}
public void setTtlUnit(@NotNull String ttlUnit) {
this.ttlUnit = ttlUnit;
}
public void setIntervalRatio(@DecimalMin("0.1") @DecimalMax("0.9") double intervalRatio) {
public @DecimalMin("0.1") @DecimalMax("0.9") double getIntervalRatio() {
return this.intervalRatio;
}
public void setIntervalRatio(
@DecimalMin("0.1") @DecimalMax("0.9") double intervalRatio) {
this.intervalRatio = intervalRatio;
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("enabled", enabled)
.append("ttlValue", ttlValue)
.append("ttlUnit", ttlUnit)
.append("intervalRatio", intervalRatio)
.toString();
return new ToStringCreator(this).append("enabled", this.enabled)
.append("ttlValue", this.ttlValue).append("ttlUnit", this.ttlUnit)
.append("intervalRatio", this.intervalRatio).toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,9 +31,11 @@ import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
/**
* Created by nicu on 11.03.2015.
*
* @author Stéphane LEROY
*/
public class TtlScheduler {
private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class);
private final Map<String, ScheduledFuture> serviceHeartbeats = new ConcurrentHashMap<>();
@@ -57,41 +59,45 @@ public class TtlScheduler {
/**
* Add a service to the checks loop.
* @param instanceId instance id
*/
public void add(String instanceId) {
ScheduledFuture task = scheduler.scheduleAtFixedRate(new ConsulHeartbeatTask(
instanceId), configuration.computeHearbeatInterval()
.toStandardDuration().getMillis());
ScheduledFuture previousTask = serviceHeartbeats.put(instanceId, task);
ScheduledFuture task = this.scheduler.scheduleAtFixedRate(
new ConsulHeartbeatTask(instanceId), this.configuration
.computeHearbeatInterval().toStandardDuration().getMillis());
ScheduledFuture previousTask = this.serviceHeartbeats.put(instanceId, task);
if (previousTask != null) {
previousTask.cancel(true);
}
}
public void remove(String instanceId) {
ScheduledFuture task = serviceHeartbeats.get(instanceId);
ScheduledFuture task = this.serviceHeartbeats.get(instanceId);
if (task != null) {
task.cancel(true);
}
serviceHeartbeats.remove(instanceId);
this.serviceHeartbeats.remove(instanceId);
}
private class ConsulHeartbeatTask implements Runnable {
private String checkId;
ConsulHeartbeatTask(String serviceId) {
this.checkId = serviceId;
if (!checkId.startsWith("service:")) {
checkId = "service:" + checkId;
if (!this.checkId.startsWith("service:")) {
this.checkId = "service:" + this.checkId;
}
}
@Override
public void run() {
client.agentCheckPass(checkId);
TtlScheduler.this.client.agentCheckPass(this.checkId);
if (log.isDebugEnabled()) {
log.debug("Sending consul heartbeat for: " + checkId);
log.debug("Sending consul heartbeat for: " + this.checkId);
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@ package org.springframework.cloud.consul.discovery.configclient;
import javax.annotation.PostConstruct;
import com.ecwid.consul.v1.ConsulClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -26,8 +28,6 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import com.ecwid.consul.v1.ConsulClient;
/**
* Extra configuration for config server if it happens to be registered with Consul.
*
@@ -52,7 +52,7 @@ public class ConsulConfigServerAutoConfiguration {
}
String prefix = this.server.getPrefix();
if (StringUtils.hasText(prefix)) {
this.properties.getTags().add("configPath="+prefix);
this.properties.getTags().add("configPath=" + prefix);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,8 @@ import org.springframework.context.annotation.Configuration;
@ConditionalOnClass(ConfigServicePropertySourceLocator.class)
@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
@Configuration
@ImportAutoConfiguration({ ConsulAutoConfiguration.class, ConsulDiscoveryClientConfiguration.class})
@ImportAutoConfiguration({ ConsulAutoConfiguration.class,
ConsulDiscoveryClientConfiguration.class })
public class ConsulDiscoveryClientConfigServiceBootstrapConfiguration {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,21 +20,23 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.springframework.cloud.consul.discovery.ConsulServer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerListFilter;
import org.springframework.cloud.consul.discovery.ConsulServer;
/**
* Server filter: returns only alive servers. Each consul agent runs a serf agent which is
* a member of the serf gossip pool. The serf status (alive/failed/etc) is reflected in 2
* consul APIs: in the agent API and in the catalog API. We prefer the agent API because
* it is most up to date (or perhaps we should intersect them and pick members that are
* live in both).
*
* @author nicu marasoiu on 10.03.2015.
*/
@Deprecated
public class AliveServerListFilter implements ServerListFilter<Server> {
private FilteringAgentClient filteringAgentClient;
public AliveServerListFilter(FilteringAgentClient filteringAgentClient) {
@@ -43,14 +45,16 @@ public class AliveServerListFilter implements ServerListFilter<Server> {
@Override
public List<Server> getFilteredListOfServers(List<Server> servers) {
Set<String> liveNodes = filteringAgentClient.getAliveAgentsAddresses();
Set<String> liveNodes = this.filteringAgentClient.getAliveAgentsAddresses();
List<Server> filteredServers = new ArrayList<>();
for (Server server : servers) {
ConsulServer consulServer = ConsulServer.class.cast(server);
if (liveNodes.contains(consulServer.getHealthService().getService().getAddress())) {
if (liveNodes.contains(
consulServer.getHealthService().getService().getAddress())) {
filteredServers.add(server);
}
}
return filteredServers;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,11 +21,14 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.cloud.consul.model.SerfStatusEnum;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.Member;
import org.springframework.cloud.consul.model.SerfStatusEnum;
/**
* @author Nicu Marasoiu
*/
@Deprecated
public class FilteringAgentClient {
@@ -38,7 +41,7 @@ public class FilteringAgentClient {
}
public List<Member> getAliveAgents() {
List<Member> members = client.getAgentMembers().getValue();
List<Member> members = this.client.getAgentMembers().getValue();
List<Member> liveMembers = new ArrayList<>(members.size());
for (Member peer : members) {
if (peer.getStatus() == ALIVE_STATUS) {
@@ -55,4 +58,5 @@ public class FilteringAgentClient {
}
return addresses;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@ import com.netflix.loadbalancer.ServerListFilter;
/**
* Created by nicu on 12.03.2015.
*
* @author Nicu Marasoiu
*/
@Deprecated
public class ServiceCheckServerListFilter implements ServerListFilter<Server> {
@@ -44,9 +46,9 @@ public class ServiceCheckServerListFilter implements ServerListFilter<Server> {
for (Server server : servers) {
String appName = server.getMetaInfo().getAppName();
String instanceId = server.getMetaInfo().getInstanceId();
//TODO: cache getHealthChecks? this is hit often
List<Check> serviceChecks = client.getHealthChecksForService(appName,
QueryParams.DEFAULT).getValue();
// TODO: cache getHealthChecks? this is hit often
List<Check> serviceChecks = this.client
.getHealthChecksForService(appName, QueryParams.DEFAULT).getValue();
boolean serviceOk = true;
for (Check check : serviceChecks) {
if (check.getServiceId().equals(instanceId)

View File

@@ -20,6 +20,8 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import com.ecwid.consul.v1.agent.model.NewService;
import org.springframework.cloud.client.discovery.ManagementServerPortUtils;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
@@ -31,29 +33,38 @@ import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.ecwid.consul.v1.agent.model.NewService;
/**
* @author Spencer Gibb
*/
public class ConsulAutoRegistration extends ConsulRegistration {
/**
* Instance ID separator.
*/
public static final char SEPARATOR = '-';
private final AutoServiceRegistrationProperties autoServiceRegistrationProperties;
private final ApplicationContext context;
private final HeartbeatProperties heartbeatProperties;
private final List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers;
@Deprecated
public ConsulAutoRegistration(NewService service, AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties, ApplicationContext context, HeartbeatProperties heartbeatProperties) {
this(service, autoServiceRegistrationProperties, properties, context, heartbeatProperties, Collections.emptyList());
public ConsulAutoRegistration(NewService service,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties, ApplicationContext context,
HeartbeatProperties heartbeatProperties) {
this(service, autoServiceRegistrationProperties, properties, context,
heartbeatProperties, Collections.emptyList());
}
public ConsulAutoRegistration(NewService service, AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties, ApplicationContext context, HeartbeatProperties heartbeatProperties,
List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers) {
public ConsulAutoRegistration(NewService service,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties, ApplicationContext context,
HeartbeatProperties heartbeatProperties,
List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers) {
super(service, properties);
this.autoServiceRegistrationProperties = autoServiceRegistrationProperties;
this.context = context;
@@ -61,24 +72,8 @@ public class ConsulAutoRegistration extends ConsulRegistration {
this.managementRegistrationCustomizers = managementRegistrationCustomizers;
}
public void initializePort(int knownPort) {
if (getService().getPort() == null) {
// not set by properties
getService().setPort(knownPort);
}
// we might not have a port until now, so this is the earliest we
// can create a check
setCheck(getService(), this.autoServiceRegistrationProperties, getProperties(),
this.context, this.heartbeatProperties);
}
public ConsulAutoRegistration managementRegistration() {
return managementRegistration(this.autoServiceRegistrationProperties, getProperties(),
this.context, this.managementRegistrationCustomizers, this.heartbeatProperties);
}
public static ConsulAutoRegistration registration(AutoServiceRegistrationProperties autoServiceRegistrationProperties,
public static ConsulAutoRegistration registration(
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties, ApplicationContext context,
List<ConsulRegistrationCustomizer> registrationCustomizers,
List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers,
@@ -87,7 +82,7 @@ public class ConsulAutoRegistration extends ConsulRegistration {
NewService service = new NewService();
String appName = getAppName(properties, context.getEnvironment());
service.setId(getInstanceId(properties, context));
if(!properties.isPreferAgentAddress()) {
if (!properties.isPreferAgentAddress()) {
service.setAddress(properties.getHostname());
}
service.setName(normalizeForDns(appName));
@@ -96,16 +91,20 @@ public class ConsulAutoRegistration extends ConsulRegistration {
if (properties.getPort() != null) {
service.setPort(properties.getPort());
// we know the port and can set the check
setCheck(service, autoServiceRegistrationProperties, properties, context, heartbeatProperties);
setCheck(service, autoServiceRegistrationProperties, properties, context,
heartbeatProperties);
}
ConsulAutoRegistration registration = new ConsulAutoRegistration(service, autoServiceRegistrationProperties,
properties, context, heartbeatProperties, managementRegistrationCustomizers);
ConsulAutoRegistration registration = new ConsulAutoRegistration(service,
autoServiceRegistrationProperties, properties, context,
heartbeatProperties, managementRegistrationCustomizers);
customize(registrationCustomizers, registration);
return registration;
}
public static void customize(List<ConsulRegistrationCustomizer> registrationCustomizers, ConsulAutoRegistration registration) {
public static void customize(
List<ConsulRegistrationCustomizer> registrationCustomizers,
ConsulAutoRegistration registration) {
if (registrationCustomizers != null) {
for (ConsulRegistrationCustomizer customizer : registrationCustomizers) {
customizer.customize(registration);
@@ -119,9 +118,11 @@ public class ConsulAutoRegistration extends ConsulRegistration {
HeartbeatProperties heartbeatProperties) {
if (properties.isRegisterHealthCheck() && service.getCheck() == null) {
Integer checkPort;
if (shouldRegisterManagement(autoServiceRegistrationProperties, properties, context)) {
if (shouldRegisterManagement(autoServiceRegistrationProperties, properties,
context)) {
checkPort = getManagementPort(properties, context);
} else {
}
else {
checkPort = service.getPort();
}
Assert.notNull(checkPort, "checkPort may not be null");
@@ -137,18 +138,24 @@ public class ConsulAutoRegistration extends ConsulRegistration {
NewService management = new NewService();
management.setId(getManagementServiceId(properties, context));
management.setAddress(properties.getHostname());
management.setName(getManagementServiceName(properties, context.getEnvironment()));
management
.setName(getManagementServiceName(properties, context.getEnvironment()));
management.setPort(getManagementPort(properties, context));
management.setTags(properties.getManagementTags());
if (properties.isRegisterHealthCheck()) {
management.setCheck(createCheck(getManagementPort(properties, context), heartbeatProperties, properties));
management.setCheck(createCheck(getManagementPort(properties, context),
heartbeatProperties, properties));
}
ConsulAutoRegistration registration = new ConsulAutoRegistration(management, autoServiceRegistrationProperties, properties, context, heartbeatProperties, managementRegistrationCustomizers);
ConsulAutoRegistration registration = new ConsulAutoRegistration(management,
autoServiceRegistrationProperties, properties, context,
heartbeatProperties, managementRegistrationCustomizers);
managementCustomize(managementRegistrationCustomizers, registration);
return registration;
}
public static void managementCustomize(List<ConsulManagementRegistrationCustomizer> registrationCustomizers, ConsulAutoRegistration registration) {
public static void managementCustomize(
List<ConsulManagementRegistrationCustomizer> registrationCustomizers,
ConsulAutoRegistration registration) {
if (registrationCustomizers != null) {
for (ConsulManagementRegistrationCustomizer customizer : registrationCustomizers) {
customizer.customize(registration);
@@ -156,17 +163,23 @@ public class ConsulAutoRegistration extends ConsulRegistration {
}
}
public static String getInstanceId(ConsulDiscoveryProperties properties, ApplicationContext context) {
public static String getInstanceId(ConsulDiscoveryProperties properties,
ApplicationContext context) {
if (!StringUtils.hasText(properties.getInstanceId())) {
return normalizeForDns(IdUtils.getDefaultInstanceId(context.getEnvironment(), false));
return normalizeForDns(
IdUtils.getDefaultInstanceId(context.getEnvironment(), false));
}
return normalizeForDns(properties.getInstanceId());
}
public static String normalizeForDns(String s) {
if (s == null || !Character.isLetter(s.charAt(0))
|| !Character.isLetterOrDigit(s.charAt(s.length()-1))) {
throw new IllegalArgumentException("Consul service ids must not be empty, must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen: "+s);
|| !Character.isLetterOrDigit(s.charAt(s.length() - 1))) {
throw new IllegalArgumentException(
"Consul service ids must not be empty, must start "
+ "with a letter, end with a letter or digit, "
+ "and have as interior characters only letters, "
+ "digits, and hyphen: " + s);
}
StringBuilder normalized = new StringBuilder();
@@ -175,7 +188,8 @@ public class ConsulAutoRegistration extends ConsulRegistration {
Character toAppend = null;
if (Character.isLetterOrDigit(curr)) {
toAppend = curr;
} else if (prev == null || !(prev == SEPARATOR)) {
}
else if (prev == null || !(prev == SEPARATOR)) {
toAppend = SEPARATOR;
}
if (toAppend != null) {
@@ -191,20 +205,23 @@ public class ConsulAutoRegistration extends ConsulRegistration {
List<String> tags = new LinkedList<>(properties.getTags());
if (!StringUtils.isEmpty(properties.getInstanceZone())) {
tags.add(properties.getDefaultZoneMetadataName() + "=" + properties.getInstanceZone());
tags.add(properties.getDefaultZoneMetadataName() + "="
+ properties.getInstanceZone());
}
if (!StringUtils.isEmpty(properties.getInstanceGroup())) {
tags.add("group=" + properties.getInstanceGroup());
}
//store the secure flag in the tags so that clients will be able to figure out whether to use http or https automatically
tags.add("secure=" + Boolean.toString(properties.getScheme().equalsIgnoreCase("https")));
// store the secure flag in the tags so that clients will be able to figure out
// whether to use http or https automatically
tags.add("secure="
+ Boolean.toString(properties.getScheme().equalsIgnoreCase("https")));
return tags;
}
public static NewService.Check createCheck(Integer port, HeartbeatProperties ttlConfig,
ConsulDiscoveryProperties properties) {
public static NewService.Check createCheck(Integer port,
HeartbeatProperties ttlConfig, ConsulDiscoveryProperties properties) {
NewService.Check check = new NewService.Check();
if (ttlConfig.isEnabled()) {
check.setTtl(ttlConfig.getTtl());
@@ -216,25 +233,29 @@ public class ConsulAutoRegistration extends ConsulRegistration {
if (properties.getHealthCheckUrl() != null) {
check.setHttp(properties.getHealthCheckUrl());
} else {
}
else {
check.setHttp(String.format("%s://%s:%s%s", properties.getScheme(),
properties.getHostname(), port,
properties.getHealthCheckPath()));
properties.getHostname(), port, properties.getHealthCheckPath()));
}
check.setHeader(properties.getHealthCheckHeaders());
check.setInterval(properties.getHealthCheckInterval());
check.setTimeout(properties.getHealthCheckTimeout());
if (StringUtils.hasText(properties.getHealthCheckCriticalTimeout())) {
check.setDeregisterCriticalServiceAfter(properties.getHealthCheckCriticalTimeout());
check.setDeregisterCriticalServiceAfter(
properties.getHealthCheckCriticalTimeout());
}
check.setTlsSkipVerify(properties.getHealthCheckTlsSkipVerify());
return check;
}
/**
* @param properties consul discovery properties
* @param env Spring environment
* @return the app name, currently the spring.application.name property
*/
public static String getAppName(ConsulDiscoveryProperties properties, Environment env) {
public static String getAppName(ConsulDiscoveryProperties properties,
Environment env) {
final String appName = properties.getServiceName();
if (StringUtils.hasText(appName)) {
return appName;
@@ -243,44 +264,83 @@ public class ConsulAutoRegistration extends ConsulRegistration {
}
/**
* @return if the management service should be registered with the {@link ServiceRegistry}
* @param autoServiceRegistrationProperties registration properties
* @param properties discovery properties
* @param context Spring application context
* @return if the management service should be registered with the
* {@link ServiceRegistry}
*/
public static boolean shouldRegisterManagement(AutoServiceRegistrationProperties autoServiceRegistrationProperties, ConsulDiscoveryProperties properties, ApplicationContext context) {
public static boolean shouldRegisterManagement(
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties, ApplicationContext context) {
return autoServiceRegistrationProperties.isRegisterManagement()
&& getManagementPort(properties, context) != null
&& ManagementServerPortUtils.isDifferent(context);
}
/**
* @param properties discovery properties
* @param context Spring application context
* @return the serviceId of the Management Service
*/
public static String getManagementServiceId(ConsulDiscoveryProperties properties, ApplicationContext context) {
public static String getManagementServiceId(ConsulDiscoveryProperties properties,
ApplicationContext context) {
final String instanceId = properties.getInstanceId();
if (StringUtils.hasText(instanceId)) {
return normalizeForDns(instanceId + SEPARATOR + properties.getManagementSuffix());
return normalizeForDns(
instanceId + SEPARATOR + properties.getManagementSuffix());
}
return normalizeForDns(IdUtils.getDefaultInstanceId(context.getEnvironment(), false)) + SEPARATOR + properties.getManagementSuffix();
return normalizeForDns(
IdUtils.getDefaultInstanceId(context.getEnvironment(), false)) + SEPARATOR
+ properties.getManagementSuffix();
}
/**
* @param properties discovery properties
* @param env Spring environment
* @return the service name of the Management Service
*/
public static String getManagementServiceName(ConsulDiscoveryProperties properties, Environment env) {
public static String getManagementServiceName(ConsulDiscoveryProperties properties,
Environment env) {
final String appName = properties.getServiceName();
if (StringUtils.hasText(appName)) {
return normalizeForDns(appName + SEPARATOR + properties.getManagementSuffix());
return normalizeForDns(
appName + SEPARATOR + properties.getManagementSuffix());
}
return normalizeForDns(getAppName(properties, env)) + SEPARATOR + properties.getManagementSuffix();
return normalizeForDns(getAppName(properties, env)) + SEPARATOR
+ properties.getManagementSuffix();
}
/**
* @param properties discovery properties
* @param context Spring application context
* @return the port of the Management Service
*/
public static Integer getManagementPort(ConsulDiscoveryProperties properties, ApplicationContext context) {
public static Integer getManagementPort(ConsulDiscoveryProperties properties,
ApplicationContext context) {
// If an alternate external port is specified, use it instead
if (properties.getManagementPort() != null) {
return properties.getManagementPort();
}
return ManagementServerPortUtils.getPort(context);
}
public void initializePort(int knownPort) {
if (getService().getPort() == null) {
// not set by properties
getService().setPort(knownPort);
}
// we might not have a port until now, so this is the earliest we
// can create a check
setCheck(getService(), this.autoServiceRegistrationProperties, getProperties(),
this.context, this.heartbeatProperties);
}
public ConsulAutoRegistration managementRegistration() {
return managementRegistration(this.autoServiceRegistrationProperties,
getProperties(), this.context, this.managementRegistrationCustomizers,
this.heartbeatProperties);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.cloud.consul.serviceregistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
@@ -29,11 +30,13 @@ import org.springframework.util.StringUtils;
/**
* @author Spencer Gibb
*/
public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistration<ConsulRegistration> {
public class ConsulAutoServiceRegistration
extends AbstractAutoServiceRegistration<ConsulRegistration> {
private static Log log = LogFactory.getLog(ConsulAutoServiceRegistration.class);
private ConsulDiscoveryProperties properties;
private ConsulAutoRegistration registration;
public ConsulAutoServiceRegistration(ConsulServiceRegistry serviceRegistry,
@@ -50,10 +53,12 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati
@Override
protected ConsulAutoRegistration getRegistration() {
if (this.registration.getService().getPort() == null && this.getPort().get() > 0) {
if (this.registration.getService().getPort() == null
&& this.getPort().get() > 0) {
this.registration.initializePort(this.getPort().get());
}
Assert.notNull(this.registration.getService().getPort(), "service.port has not been set");
Assert.notNull(this.registration.getService().getPort(),
"service.port has not been set");
return this.registration;
}
@@ -89,7 +94,7 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati
@Override
protected Object getConfiguration() {
return properties;
return this.properties;
}
@Override
@@ -116,7 +121,7 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati
@Override
@SuppressWarnings("deprecation")
protected String getAppName() {
String appName = properties.getServiceName();
String appName = this.properties.getServiceName();
return StringUtils.isEmpty(appName) ? super.getAppName() : appName;
}
@@ -125,4 +130,5 @@ public class ConsulAutoServiceRegistration extends AbstractAutoServiceRegistrati
// do nothing so we can listen for this event in a different class
// this ensures start() can be retried if spring-retry is available
}
}

View File

@@ -44,7 +44,8 @@ import org.springframework.context.annotation.Configuration;
@ConditionalOnMissingBean(type = "org.springframework.cloud.consul.discovery.ConsulLifecycle")
@ConditionalOnConsulEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
@AutoConfigureAfter({AutoServiceRegistrationConfiguration.class, ConsulServiceRegistryAutoConfiguration.class})
@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
ConsulServiceRegistryAutoConfiguration.class })
public class ConsulAutoServiceRegistrationAutoConfiguration {
@Autowired
@@ -62,31 +63,34 @@ public class ConsulAutoServiceRegistrationAutoConfiguration {
}
@Bean
public ConsulAutoServiceRegistrationListener consulAutoServiceRegistrationListener(ConsulAutoServiceRegistration registration) {
public ConsulAutoServiceRegistrationListener consulAutoServiceRegistrationListener(
ConsulAutoServiceRegistration registration) {
return new ConsulAutoServiceRegistrationListener(registration);
}
@Bean
@ConditionalOnMissingBean
public ConsulAutoRegistration consulRegistration(AutoServiceRegistrationProperties autoServiceRegistrationProperties,
public ConsulAutoRegistration consulRegistration(
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties, ApplicationContext applicationContext,
ObjectProvider<List<ConsulRegistrationCustomizer>> registrationCustomizers,
ObjectProvider<List<ConsulManagementRegistrationCustomizer>> managementRegistrationCustomizers,
HeartbeatProperties heartbeatProperties) {
return ConsulAutoRegistration.registration(autoServiceRegistrationProperties, properties,
applicationContext, registrationCustomizers.getIfAvailable(),
managementRegistrationCustomizers.getIfAvailable(),
heartbeatProperties);
return ConsulAutoRegistration.registration(autoServiceRegistrationProperties,
properties, applicationContext, registrationCustomizers.getIfAvailable(),
managementRegistrationCustomizers.getIfAvailable(), heartbeatProperties);
}
@Configuration
@ConditionalOnClass(ServletContext.class)
protected static class ConsulServletConfiguration {
@Bean
public ConsulRegistrationCustomizer servletConsulCustomizer(ObjectProvider<ServletContext> servletContext) {
public ConsulRegistrationCustomizer servletConsulCustomizer(
ObjectProvider<ServletContext> servletContext) {
return new ConsulServletRegistrationCustomizer(servletContext);
}
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
package org.springframework.cloud.consul.serviceregistry;
import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext;
@@ -6,10 +22,17 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
/**
* Auto registers service upon web server initialization.
*
* @author Spencer Gibb
*/
public class ConsulAutoServiceRegistrationListener implements SmartApplicationListener {
private final ConsulAutoServiceRegistration autoServiceRegistration;
public ConsulAutoServiceRegistrationListener(ConsulAutoServiceRegistration autoServiceRegistration) {
public ConsulAutoServiceRegistrationListener(
ConsulAutoServiceRegistration autoServiceRegistration) {
this.autoServiceRegistration = autoServiceRegistration;
}
@@ -30,8 +53,9 @@ public class ConsulAutoServiceRegistrationListener implements SmartApplicationLi
ApplicationContext context = event.getApplicationContext();
if (context instanceof ConfigurableWebServerApplicationContext) {
if ("management".equals(
((ConfigurableWebServerApplicationContext) context).getServerNamespace())) {
if ("management"
.equals(((ConfigurableWebServerApplicationContext) context)
.getServerNamespace())) {
return;
}
}
@@ -44,4 +68,5 @@ public class ConsulAutoServiceRegistrationListener implements SmartApplicationLi
public int getOrder() {
return 0;
}
}

View File

@@ -20,5 +20,11 @@ package org.springframework.cloud.consul.serviceregistry;
* @author Alexey Savchuk (devpreview)
*/
public interface ConsulManagementRegistrationCustomizer {
/**
* Customizes a registration.
* @param managementRegistration registration to customize
*/
void customize(ConsulRegistration managementRegistration);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,22 +16,23 @@
package org.springframework.cloud.consul.serviceregistry;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
import com.ecwid.consul.v1.agent.model.NewService;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
import java.net.URI;
import java.util.Map;
import com.ecwid.consul.v1.agent.model.NewService;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
/**
* @author Spencer Gibb
*/
public class ConsulRegistration implements Registration {
private final NewService service;
private ConsulDiscoveryProperties properties;
public ConsulRegistration(NewService service, ConsulDiscoveryProperties properties) {
@@ -40,11 +41,11 @@ public class ConsulRegistration implements Registration {
}
public NewService getService() {
return service;
return this.service;
}
protected ConsulDiscoveryProperties getProperties() {
return properties;
return this.properties;
}
public String getInstanceId() {
@@ -79,4 +80,5 @@ public class ConsulRegistration implements Registration {
public Map<String, String> getMetadata() {
return ConsulServerUtils.getMetadata(getService().getTags());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,5 +20,7 @@ package org.springframework.cloud.consul.serviceregistry;
* @author Piotr Wielgolaski
*/
public interface ConsulRegistrationCustomizer {
void customize(ConsulRegistration registration);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,21 +18,21 @@ package org.springframework.cloud.consul.serviceregistry;
import java.util.List;
import com.ecwid.consul.ConsulException;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.agent.model.NewService;
import com.ecwid.consul.v1.health.model.Check;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.HeartbeatProperties;
import org.springframework.cloud.consul.discovery.TtlScheduler;
import org.springframework.util.ReflectionUtils;
import com.ecwid.consul.ConsulException;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.health.model.Check;
import com.ecwid.consul.v1.agent.model.NewService;
import static org.springframework.boot.actuate.health.Status.OUT_OF_SERVICE;
import static org.springframework.boot.actuate.health.Status.UP;
@@ -51,7 +51,9 @@ public class ConsulServiceRegistry implements ServiceRegistry<ConsulRegistration
private final HeartbeatProperties heartbeatProperties;
public ConsulServiceRegistry(ConsulClient client, ConsulDiscoveryProperties properties, TtlScheduler ttlScheduler, HeartbeatProperties heartbeatProperties) {
public ConsulServiceRegistry(ConsulClient client,
ConsulDiscoveryProperties properties, TtlScheduler ttlScheduler,
HeartbeatProperties heartbeatProperties) {
this.client = client;
this.properties = properties;
this.ttlScheduler = ttlScheduler;
@@ -62,30 +64,36 @@ public class ConsulServiceRegistry implements ServiceRegistry<ConsulRegistration
public void register(ConsulRegistration reg) {
log.info("Registering service with consul: " + reg.getService());
try {
client.agentServiceRegister(reg.getService(), properties.getAclToken());
this.client.agentServiceRegister(reg.getService(),
this.properties.getAclToken());
NewService service = reg.getService();
if (heartbeatProperties.isEnabled() && ttlScheduler != null && service.getCheck() != null && service.getCheck().getTtl() != null) {
ttlScheduler.add(reg.getInstanceId());
if (this.heartbeatProperties.isEnabled() && this.ttlScheduler != null
&& service.getCheck() != null
&& service.getCheck().getTtl() != null) {
this.ttlScheduler.add(reg.getInstanceId());
}
}
catch (ConsulException e) {
if (this.properties.isFailFast()) {
log.error("Error registering service with consul: " + reg.getService(), e);
log.error("Error registering service with consul: " + reg.getService(),
e);
ReflectionUtils.rethrowRuntimeException(e);
}
log.warn("Failfast is false. Error registering service with consul: " + reg.getService(), e);
log.warn("Failfast is false. Error registering service with consul: "
+ reg.getService(), e);
}
}
@Override
public void deregister(ConsulRegistration reg) {
if (ttlScheduler != null) {
ttlScheduler.remove(reg.getInstanceId());
if (this.ttlScheduler != null) {
this.ttlScheduler.remove(reg.getInstanceId());
}
if (log.isInfoEnabled()) {
log.info("Deregistering service with consul: " + reg.getInstanceId());
}
client.agentServiceDeregister(reg.getInstanceId(), properties.getAclToken());
this.client.agentServiceDeregister(reg.getInstanceId(),
this.properties.getAclToken());
}
@Override
@@ -96,11 +104,13 @@ public class ConsulServiceRegistry implements ServiceRegistry<ConsulRegistration
@Override
public void setStatus(ConsulRegistration registration, String status) {
if (status.equalsIgnoreCase(OUT_OF_SERVICE.getCode())) {
client.agentServiceSetMaintenance(registration.getInstanceId(), true);
} else if (status.equalsIgnoreCase(UP.getCode())) {
client.agentServiceSetMaintenance(registration.getInstanceId(), false);
} else {
throw new IllegalArgumentException("Unknown status: "+status);
this.client.agentServiceSetMaintenance(registration.getInstanceId(), true);
}
else if (status.equalsIgnoreCase(UP.getCode())) {
this.client.agentServiceSetMaintenance(registration.getInstanceId(), false);
}
else {
throw new IllegalArgumentException("Unknown status: " + status);
}
}
@@ -108,7 +118,8 @@ public class ConsulServiceRegistry implements ServiceRegistry<ConsulRegistration
@Override
public Object getStatus(ConsulRegistration registration) {
String serviceId = registration.getServiceId();
Response<List<Check>> response = client.getHealthChecksForService(serviceId, QueryParams.DEFAULT);
Response<List<Check>> response = this.client.getHealthChecksForService(serviceId,
QueryParams.DEFAULT);
List<Check> checks = response.getValue();
for (Check check : checks) {
@@ -121,4 +132,5 @@ public class ConsulServiceRegistry implements ServiceRegistry<ConsulRegistration
return UP.getCode();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
package org.springframework.cloud.consul.serviceregistry;
import com.ecwid.consul.v1.ConsulClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -29,8 +31,6 @@ import org.springframework.cloud.consul.discovery.TtlScheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ecwid.consul.v1.ConsulClient;
/**
* @author Spencer Gibb
*/
@@ -45,15 +45,18 @@ public class ConsulServiceRegistryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ConsulServiceRegistry consulServiceRegistry(ConsulClient consulClient, ConsulDiscoveryProperties properties,
HeartbeatProperties heartbeatProperties) {
return new ConsulServiceRegistry(consulClient, properties, ttlScheduler, heartbeatProperties);
public ConsulServiceRegistry consulServiceRegistry(ConsulClient consulClient,
ConsulDiscoveryProperties properties,
HeartbeatProperties heartbeatProperties) {
return new ConsulServiceRegistry(consulClient, properties, this.ttlScheduler,
heartbeatProperties);
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty("spring.cloud.consul.discovery.heartbeat.enabled")
public TtlScheduler ttlScheduler(ConsulClient consulClient, HeartbeatProperties heartbeatProperties) {
public TtlScheduler ttlScheduler(ConsulClient consulClient,
HeartbeatProperties heartbeatProperties) {
return new TtlScheduler(heartbeatProperties, consulClient);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,11 @@
package org.springframework.cloud.consul.serviceregistry;
import javax.servlet.ServletContext;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.util.StringUtils;
@@ -27,20 +28,21 @@ import org.springframework.util.StringUtils;
* @author Piotr Wielgolaski
*/
public class ConsulServletRegistrationCustomizer implements ConsulRegistrationCustomizer {
private ObjectProvider<ServletContext> servletContext;
public ConsulServletRegistrationCustomizer(ObjectProvider<ServletContext> servletContext) {
public ConsulServletRegistrationCustomizer(
ObjectProvider<ServletContext> servletContext) {
this.servletContext = servletContext;
}
@Override
public void customize(ConsulRegistration registration) {
if (servletContext == null) {
if (this.servletContext == null) {
return;
}
ServletContext sc = servletContext.getIfAvailable();
if(sc != null
&& StringUtils.hasText(sc.getContextPath())
ServletContext sc = this.servletContext.getIfAvailable();
if (sc != null && StringUtils.hasText(sc.getContextPath())
&& StringUtils.hasText(sc.getContextPath().replaceAll("/", ""))) {
List<String> tags = registration.getService().getTags();
if (tags == null) {
@@ -50,4 +52,5 @@ public class ConsulServletRegistrationCustomizer implements ConsulRegistrationCu
registration.getService().setTags(tags);
}
}
}

View File

@@ -4,8 +4,6 @@ org.springframework.cloud.consul.discovery.configclient.ConsulConfigServerAutoCo
org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration,\
org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration,\
org.springframework.cloud.consul.discovery.ConsulDiscoveryClientConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.consul.discovery.configclient.ConsulDiscoveryClientConfigServiceBootstrapConfiguration

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -29,19 +30,17 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
* @author Spencer Gibb
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsulDiscoveryClientAclTests.MyTestConfig.class,
properties = {"spring.application.name=testConsulDiscoveryAcl",
"spring.cloud.consul.discovery.preferIpAddress=true",
"consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304"},
webEnvironment = RANDOM_PORT)
@SpringBootTest(classes = ConsulDiscoveryClientAclTests.MyTestConfig.class, properties = {
"spring.application.name=testConsulDiscoveryAcl",
"spring.cloud.consul.discovery.preferIpAddress=true",
"consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304" }, webEnvironment = RANDOM_PORT)
public class ConsulDiscoveryClientAclTests {
@Autowired
@@ -49,24 +48,25 @@ public class ConsulDiscoveryClientAclTests {
@Test
public void getInstancesForThisServiceWorks() {
List<ServiceInstance> instances = discoveryClient.getInstances("testConsulDiscoveryAcl");
assertNotNull("instances was null", instances);
assertFalse("instances was empty", instances.isEmpty());
List<ServiceInstance> instances = this.discoveryClient
.getInstances("testConsulDiscoveryAcl");
assertThat(instances).as("instances was null").isNotNull();
assertThat(instances.isEmpty()).as("instances was empty").isFalse();
}
@Test
public void getInstancesForSecondServiceWorks() throws Exception {
new SpringApplicationBuilder(MyTestConfig.class)
.run("--spring.application.name=testSecondServiceAcl",
"--server.port=0",
"--spring.cloud.consul.discovery.preferIpAddress=true",
"--consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304");
new SpringApplicationBuilder(MyTestConfig.class).run(
"--spring.application.name=testSecondServiceAcl", "--server.port=0",
"--spring.cloud.consul.discovery.preferIpAddress=true",
"--consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304");
List<ServiceInstance> instances = discoveryClient.getInstances("testSecondServiceAcl");
assertNotNull("second service instances was null", instances);
assertFalse("second service instances was empty", instances.isEmpty());
List<ServiceInstance> instances = this.discoveryClient
.getInstances("testSecondServiceAcl");
assertThat(instances).as("second service instances was null").isNotNull();
assertThat(instances.isEmpty()).as("second service instances was empty")
.isFalse();
}
@Configuration
@@ -75,4 +75,5 @@ public class ConsulDiscoveryClientAclTests {
public static class MyTestConfig {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import java.util.Map;
import org.apache.http.conn.util.InetAddressUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -30,9 +31,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
@@ -40,13 +39,12 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Tim Ysewyn
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsulDiscoveryClientCustomizedTests.MyTestConfig.class,
properties = { "spring.application.name=testConsulDiscovery2",
@SpringBootTest(classes = ConsulDiscoveryClientCustomizedTests.MyTestConfig.class, properties = {
"spring.application.name=testConsulDiscovery2",
"spring.cloud.consul.discovery.instanceId=testConsulDiscovery2Id",
"spring.cloud.consul.discovery.hostname=testConsulDiscovery2Host",
"spring.cloud.consul.discovery.registerHealthCheck=false",
"spring.cloud.consul.discovery.tags=plaintag,foo=bar,foo2=bar2=baz2" },
webEnvironment = RANDOM_PORT)
"spring.cloud.consul.discovery.tags=plaintag,foo=bar,foo2=bar2=baz2" }, webEnvironment = RANDOM_PORT)
public class ConsulDiscoveryClientCustomizedTests {
@Autowired
@@ -54,42 +52,44 @@ public class ConsulDiscoveryClientCustomizedTests {
@Test
public void getInstancesForServiceWorks() {
List<ServiceInstance> instances = discoveryClient.getInstances("consul");
assertNotNull("instances was null", instances);
assertFalse("instances was empty", instances.isEmpty());
List<ServiceInstance> instances = this.discoveryClient.getInstances("consul");
assertThat(instances).as("instances was null").isNotNull();
assertThat(instances.isEmpty()).as("instances was empty").isFalse();
}
private void assertNotIpAddress(ServiceInstance instance) {
assertFalse("host is an ip address",
InetAddressUtils.isIPv4Address(instance.getHost()));
assertThat(InetAddressUtils.isIPv4Address(instance.getHost()))
.as("host is an ip address").isFalse();
}
@Test
public void getMetadataWorks() throws InterruptedException {
List<ServiceInstance> instances = discoveryClient
List<ServiceInstance> instances = this.discoveryClient
.getInstances("testConsulDiscovery2");
assertNotNull("instances was null", instances);
assertFalse("instances was empty", instances.isEmpty());
assertThat(instances).as("instances was null").isNotNull();
assertThat(instances.isEmpty()).as("instances was empty").isFalse();
ServiceInstance instance = instances.get(0);
assertInstance(instance);
}
private void assertInstance(ServiceInstance instance) {
assertEquals("instance id was wrong", "testConsulDiscovery2Id", instance.getInstanceId());
assertEquals("service id was wrong", "testConsulDiscovery2", instance.getServiceId());
assertThat(instance.getInstanceId()).as("instance id was wrong")
.isEqualTo("testConsulDiscovery2Id");
assertThat(instance.getServiceId()).as("service id was wrong")
.isEqualTo("testConsulDiscovery2");
Map<String, String> metadata = instance.getMetadata();
assertNotNull("metadata was null", metadata);
assertThat(metadata).as("metadata was null").isNotNull();
String foo = metadata.get("foo");
assertEquals("metadata key foo was wrong", "bar", foo);
assertThat(foo).as("metadata key foo was wrong").isEqualTo("bar");
String plaintag = metadata.get("plaintag");
assertEquals("metadata key plaintag was wrong", "plaintag", plaintag);
assertThat(plaintag).as("metadata key plaintag was wrong").isEqualTo("plaintag");
String foo2 = metadata.get("foo2");
assertEquals("metadata key foo2 was wrong", "bar2=baz2", foo2);
assertThat(foo2).as("metadata key foo2 was wrong").isEqualTo("bar2=baz2");
}
@Configuration
@@ -98,4 +98,5 @@ public class ConsulDiscoveryClientCustomizedTests {
public static class MyTestConfig {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,38 +19,33 @@ package org.springframework.cloud.consul.discovery;
import java.util.Arrays;
import java.util.List;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasSize;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.MOCK;
/**
* @author Piotr Wielgolaski
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = MOCK,
classes = ConsulDiscoveryClientDefaultQueryTagTests.TestConfig.class,
properties = {
"spring.application.name=consulServiceDefaultTag",
"spring.cloud.consul.discovery.catalogServicesWatch.enabled=false",
"spring.cloud.consul.discovery.defaultQueryTag=intg"})
@SpringBootTest(webEnvironment = MOCK, classes = ConsulDiscoveryClientDefaultQueryTagTests.TestConfig.class, properties = {
"spring.application.name=consulServiceDefaultTag",
"spring.cloud.consul.discovery.catalogServicesWatch.enabled=false",
"spring.cloud.consul.discovery.defaultQueryTag=intg" })
@DirtiesContext
public class ConsulDiscoveryClientDefaultQueryTagTests {
@@ -63,25 +58,27 @@ public class ConsulDiscoveryClientDefaultQueryTagTests {
private ConsulClient consulClient;
private NewService intgService = serviceForEnvironment("intg", 9081);
private NewService uatService = serviceForEnvironment("uat", 9080);
@Before
public void setUp() throws Exception {
consulClient.agentServiceRegister(intgService);
consulClient.agentServiceRegister(uatService);
this.consulClient.agentServiceRegister(this.intgService);
this.consulClient.agentServiceRegister(this.uatService);
}
@After
public void tearDown() throws Exception {
consulClient.agentServiceDeregister(intgService.getId());
consulClient.agentServiceDeregister(uatService.getId());
this.consulClient.agentServiceDeregister(this.intgService.getId());
this.consulClient.agentServiceDeregister(this.uatService.getId());
}
@Test
public void shouldReturnOnlyIntgInstance() {
List<ServiceInstance> instances = discoveryClient.getInstances(NAME);
assertThat("instances was wrong size", instances, hasSize(1));
assertThat("instance is not intg", instances.get(0).getMetadata(), hasEntry("intg", "intg"));
List<ServiceInstance> instances = this.discoveryClient.getInstances(NAME);
assertThat(instances).as("instances was wrong size").hasSize(1);
assertThat(instances.get(0).getMetadata()).as("instance is not intg")
.containsEntry("intg", "intg");
}
private NewService serviceForEnvironment(String env, int port) {
@@ -100,4 +97,5 @@ public class ConsulDiscoveryClientDefaultQueryTagTests {
protected static class TestConfig {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +16,11 @@
package org.springframework.cloud.consul.discovery;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -33,15 +29,16 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
* @author Glen Lockhart
*/
@RunWith(SpringRunner.class)
@SpringBootTest(properties = { "spring.application.name=testConsulDiscoveryHttps",
"spring.cloud.consul.discovery.prefer-ip-address=true",
"spring.cloud.consul.discovery.scheme=https"},
classes = ConsulDiscoveryClientHttpsTests.MyTestConfig.class,
webEnvironment = RANDOM_PORT)
"spring.cloud.consul.discovery.prefer-ip-address=true",
"spring.cloud.consul.discovery.scheme=https" }, classes = ConsulDiscoveryClientHttpsTests.MyTestConfig.class, webEnvironment = RANDOM_PORT)
public class ConsulDiscoveryClientHttpsTests {
@Autowired
@@ -49,12 +46,13 @@ public class ConsulDiscoveryClientHttpsTests {
@Test
public void getInstancesForServiceWorks() {
List<ServiceInstance> instances = discoveryClient.getInstances("testConsulDiscoveryHttps");
assertNotNull("instances was null", instances);
assertFalse("instances was empty", instances.isEmpty());
List<ServiceInstance> instances = this.discoveryClient
.getInstances("testConsulDiscoveryHttps");
assertThat(instances).as("instances was null").isNotNull();
assertThat(instances.isEmpty()).as("instances was empty").isFalse();
ServiceInstance instance = instances.get(0);
assertTrue("instance was not secure (https)", instance.isSecure());
assertThat(instance.isSecure()).as("instance was not secure (https)").isTrue();
}
@Configuration
@@ -63,4 +61,5 @@ public class ConsulDiscoveryClientHttpsTests {
public static class MyTestConfig {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,14 @@
package org.springframework.cloud.consul.discovery;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import java.util.List;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -34,9 +32,8 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
* @author Spencer Gibb
@@ -45,46 +42,46 @@ import com.ecwid.consul.v1.Response;
@RunWith(SpringRunner.class)
@SpringBootTest(properties = { "spring.application.name=testConsulDiscovery",
"spring.cloud.consul.discovery.prefer-ip-address=true",
"spring.cloud.consul.discovery.tags=foo=bar", },
classes = ConsulDiscoveryClientTests.MyTestConfig.class,
webEnvironment = RANDOM_PORT)
"spring.cloud.consul.discovery.tags=foo=bar" }, classes = ConsulDiscoveryClientTests.MyTestConfig.class, webEnvironment = RANDOM_PORT)
public class ConsulDiscoveryClientTests {
@Autowired
private ConsulDiscoveryClient discoveryClient;
@Autowired
private ConsulClient consulClient;
@Test
public void getInstancesForServiceWorks() {
List<ServiceInstance> instances = discoveryClient.getInstances("testConsulDiscovery");
assertNotNull("instances was null", instances);
assertFalse("instances was empty", instances.isEmpty());
List<ServiceInstance> instances = this.discoveryClient
.getInstances("testConsulDiscovery");
assertThat(instances).as("instances was null").isNotNull();
assertThat(instances.isEmpty()).as("instances was empty").isFalse();
ServiceInstance instance = instances.get(0);
assertFalse("instance was secure (https)", instance.isSecure());
assertThat(instance.isSecure()).as("instance was secure (https)").isFalse();
assertIpAddress(instance);
assertThat(instance.getMetadata())
.containsEntry("foo", "bar");
assertThat(instance.getMetadata()).containsEntry("foo", "bar");
}
@Test
public void getInstancesForServiceRespectsQueryParams() {
Response<List<String>> catalogDatacenters = consulClient.getCatalogDatacenters();
Response<List<String>> catalogDatacenters = this.consulClient
.getCatalogDatacenters();
List<String> dataCenterList = catalogDatacenters.getValue();
assertFalse("no data centers found", dataCenterList.isEmpty());
List<ServiceInstance> instances = discoveryClient.getInstances("testConsulDiscovery",
new QueryParams(dataCenterList.get(0)));
assertFalse("instances was empty", instances.isEmpty());
assertThat(dataCenterList.isEmpty()).as("no data centers found").isFalse();
List<ServiceInstance> instances = this.discoveryClient.getInstances(
"testConsulDiscovery", new QueryParams(dataCenterList.get(0)));
assertThat(instances.isEmpty()).as("instances was empty").isFalse();
ServiceInstance instance = instances.get(0);
assertIpAddress(instance);
}
private void assertIpAddress(ServiceInstance instance) {
assertTrue("host isn't an ip address",
Character.isDigit(instance.getHost().charAt(0)));
assertThat(Character.isDigit(instance.getHost().charAt(0)))
.as("host isn't an ip address").isTrue();
}
@Configuration
@@ -93,4 +90,5 @@ public class ConsulDiscoveryClientTests {
public static class MyTestConfig {
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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.
*/
package org.springframework.cloud.consul.discovery;
import java.util.Collections;
@@ -10,59 +26,73 @@ import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class ConsulDiscoveryPropertiesTests {
private static final String DEFAULT_TAG = "defaultTag";
private static final String MAP_TAG = "mapTag";
private static final String MAP_DC = "mapDc";
private static final String SERVICE_NAME_IN_MAP = "serviceNameInMap";
private static final String SERVICE_NAME_NOT_IN_MAP = "serviceNameNotInMap";
private final Map<String, String> serverListQueryTags = Collections
.singletonMap(SERVICE_NAME_IN_MAP, MAP_TAG);
private final Map<String, String> datacenters = Collections
.singletonMap(SERVICE_NAME_IN_MAP, MAP_DC);
private ConsulDiscoveryProperties properties;
private final Map<String, String> serverListQueryTags = Collections.singletonMap(SERVICE_NAME_IN_MAP, MAP_TAG);
private final Map<String, String> datacenters = Collections.singletonMap(SERVICE_NAME_IN_MAP, MAP_DC);
@Before
public void setUp() {
properties = new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties()));
properties.setDefaultQueryTag(DEFAULT_TAG);
properties.setServerListQueryTags(serverListQueryTags);
properties.setDatacenters(datacenters);
this.properties = new ConsulDiscoveryProperties(
new InetUtils(new InetUtilsProperties()));
this.properties.setDefaultQueryTag(DEFAULT_TAG);
this.properties.setServerListQueryTags(this.serverListQueryTags);
this.properties.setDatacenters(this.datacenters);
}
@Test
public void testReturnsNullWhenNoDefaultAndNotInMap() {
properties.setDefaultQueryTag(null);
this.properties.setDefaultQueryTag(null);
assertNull(properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP));
assertThat(this.properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP))
.isNull();
}
@Test
public void testGetTagReturnsDefaultWhenNotInMap() {
assertEquals(DEFAULT_TAG, properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP));
assertThat(this.properties.getQueryTagForService(SERVICE_NAME_NOT_IN_MAP))
.isEqualTo(DEFAULT_TAG);
}
@Test
public void testGetTagReturnsMapValueWhenInMap() {
assertEquals(MAP_TAG, properties.getQueryTagForService(SERVICE_NAME_IN_MAP));
assertThat(this.properties.getQueryTagForService(SERVICE_NAME_IN_MAP))
.isEqualTo(MAP_TAG);
}
@Test
public void testGetDcReturnsNullWhenNotInMap() {
assertNull(properties.getDatacenters().get(SERVICE_NAME_NOT_IN_MAP));
assertThat(this.properties.getDatacenters().get(SERVICE_NAME_NOT_IN_MAP))
.isNull();
}
@Test
public void testGetDcReturnsMapValueWhenInMap() {
assertEquals(MAP_DC, properties.getDatacenters().get(SERVICE_NAME_IN_MAP));
assertThat(this.properties.getDatacenters().get(SERVICE_NAME_IN_MAP))
.isEqualTo(MAP_DC);
}
@Test
public void testAddManagementTag() {
properties.getManagementTags().add("newTag");
assertThat(properties.getManagementTags())
this.properties.getManagementTags().add("newTag");
assertThat(this.properties.getManagementTags())
.containsOnly(ConsulDiscoveryProperties.MANAGEMENT, "newTag");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertTrue;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
@@ -42,8 +41,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@RunWith(SpringRunner.class)
@SpringBootTest(properties = { "spring.application.name=testConsulLoadBalancer",
"spring.cloud.consul.discovery.prefer-ip-address=true",
"spring.cloud.consul.discovery.tags=foo=bar", },
webEnvironment = RANDOM_PORT)
"spring.cloud.consul.discovery.tags=foo=bar" }, webEnvironment = RANDOM_PORT)
public class ConsulLoadbalancerClientTests {
@Autowired
@@ -51,25 +49,26 @@ public class ConsulLoadbalancerClientTests {
@Test
public void chooseWorks() {
ServiceInstance instance = client.choose("testConsulLoadBalancer");
ServiceInstance instance = this.client.choose("testConsulLoadBalancer");
assertThat(instance).isNotNull();
assertThat(instance.isSecure()).isFalse();
assertIpAddress(instance);
assertThat(instance.getMetadata())
.containsEntry("foo", "bar");
assertThat(instance.getMetadata()).containsEntry("foo", "bar");
}
private void assertIpAddress(ServiceInstance instance) {
assertTrue("host isn't an ip address",
Character.isDigit(instance.getHost().charAt(0)));
assertThat(Character.isDigit(instance.getHost().charAt(0)))
.as("host isn't an ip address").isTrue();
}
@SpringBootConfiguration
@EnableAutoConfiguration
@EnableDiscoveryClient
@RibbonClient(name = "testConsulLoadBalancer", configuration = MyRibbonConfig.class)
public static class MyTestConfig { }
public static class MyTestConfig {
}
public static class MyRibbonConfig {
@@ -81,5 +80,7 @@ public class ConsulLoadbalancerClientTests {
public ServerListFilter<Server> ribbonServerListFilter() {
return servers -> servers;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,11 @@ package org.springframework.cloud.consul.discovery;
import java.util.List;
import com.ecwid.consul.v1.ConsulClient;
import com.netflix.client.config.DefaultClientConfigImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -27,45 +30,42 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
import com.ecwid.consul.v1.ConsulClient;
import com.netflix.client.config.DefaultClientConfigImpl;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
* @author bomee
* @author b omee
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsulServerListAclTests.TestConfig.class,
properties = {"spring.application.name=testConsulServerListAcl",
"spring.cloud.consul.discovery.preferIpAddress=true",
"consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304"},
webEnvironment = RANDOM_PORT)
@SpringBootTest(classes = ConsulServerListAclTests.TestConfig.class, properties = {
"spring.application.name=testConsulServerListAcl",
"spring.cloud.consul.discovery.preferIpAddress=true",
"consul.token=2d2e6b3b-1c82-40ab-8171-54609d8ad304" }, webEnvironment = RANDOM_PORT)
public class ConsulServerListAclTests {
@Autowired
private ConsulClient consulClient;
@Autowired
private ConsulClient consulClient;
@Autowired
private ConsulDiscoveryProperties properties;
@Autowired
private ConsulDiscoveryProperties properties;
@Test
public void serverListWorksWithAcl() {
ConsulServerList consulServerList = new ConsulServerList(consulClient, properties);
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.setClientName("testConsulServerListAcl");
consulServerList.initWithNiwsConfig(config);
List<ConsulServer> servers = consulServerList.getUpdatedListOfServers();
assertNotNull("servers was null", servers);
assertFalse("servers was empty", servers.isEmpty());
}
@Test
public void serverListWorksWithAcl() {
ConsulServerList consulServerList = new ConsulServerList(this.consulClient,
this.properties);
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.setClientName("testConsulServerListAcl");
consulServerList.initWithNiwsConfig(config);
List<ConsulServer> servers = consulServerList.getUpdatedListOfServers();
assertThat(servers).as("servers was null").isNotNull();
assertThat(servers.isEmpty()).as("servers was empty").isFalse();
}
@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient
public static class TestConfig {
@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient
public static class TestConfig {
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,22 +20,21 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.junit.Test;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
import com.netflix.client.config.DefaultClientConfigImpl;
import org.junit.Test;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
public class ConsulServerListTests {
private final String name = "consulServerListTestsService";
@Test
@@ -48,10 +47,12 @@ public class ConsulServerListTests {
NewService tagged = createService("Tagged", 9080, Arrays.asList(tag));
String zone = "myzone";
NewService withZone = createService("WithZone", 10080, Arrays.asList("zone=" + zone));
NewService withZone = createService("WithZone", 10080,
Arrays.asList("zone=" + zone));
String group = "test";
NewService withGroup = createService("WithGroup", 11080, Arrays.asList("group=" + group));
NewService withGroup = createService("WithGroup", 11080,
Arrays.asList("group=" + group));
try {
consul.agentServiceRegister(nonTagged);
@@ -61,43 +62,51 @@ public class ConsulServerListTests {
InetUtils inetUtils = new InetUtils(new InetUtilsProperties());
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.setClientName(name);
config.setClientName(this.name);
ConsulServerList serverList = new ConsulServerList(consul, new ConsulDiscoveryProperties(inetUtils));
ConsulServerList serverList = new ConsulServerList(consul,
new ConsulDiscoveryProperties(inetUtils));
serverList.initWithNiwsConfig(config);
List<ConsulServer> servers = serverList.getInitialListOfServers();
assertThat("servers was wrong size", servers, hasSize(4));
assertThat(servers).as("servers was wrong size").hasSize(4);
int serverWithZoneCount = 0;
for (ConsulServer server : servers) {
if (server.getMetadata().containsKey("zone")) {
serverWithZoneCount++;
assertThat("server was wrong zone", server.getZone(), is(zone));
} else {
assertThat("server was wrong zone", server.getZone(), is(ConsulServer.UNKNOWN_ZONE));
assertThat(server.getZone()).as("server was wrong zone")
.isEqualTo(zone);
}
else {
assertThat(server.getZone()).as("server was wrong zone")
.isEqualTo(ConsulServer.UNKNOWN_ZONE);
}
}
assertThat("server was wrong zone", serverWithZoneCount, is(1));
assertThat(serverWithZoneCount).as("server was wrong zone").isEqualTo(1);
serverList = new ConsulServerList(consul, getProperties(name, tag, inetUtils));
serverList = new ConsulServerList(consul,
getProperties(this.name, tag, inetUtils));
serverList.initWithNiwsConfig(config);
servers = serverList.getInitialListOfServers();
assertThat("servers was wrong size", servers, hasSize(1));
assertThat(servers).as("servers was wrong size").hasSize(1);
ConsulServer server = servers.get(0);
assertThat("server was wrong", server.getPort(), is(9080));
assertThat(server.getPort()).as("server was wrong").isEqualTo(9080);
// test server group
serverList = new ConsulServerList(consul, getProperties(name, "group=" + group, inetUtils));
serverList = new ConsulServerList(consul,
getProperties(this.name, "group=" + group, inetUtils));
serverList.initWithNiwsConfig(config);
servers = serverList.getInitialListOfServers();
assertThat("servers was wrong size", servers, hasSize(1));
assertThat(servers).as("servers was wrong size").hasSize(1);
server = servers.get(0);
assertThat("server was wrong", server.getPort(), is(11080));
assertThat("server group was wrong", server.getMetaInfo().getServerGroup(), is(group));
} finally {
assertThat(server.getPort()).as("server was wrong").isEqualTo(11080);
assertThat(server.getMetaInfo().getServerGroup()).as("server group was wrong")
.isEqualTo(group);
}
finally {
consul.agentServiceDeregister(nonTagged.getId());
consul.agentServiceDeregister(tagged.getId());
consul.agentServiceDeregister(withZone.getId());
@@ -105,7 +114,8 @@ public class ConsulServerListTests {
}
}
private ConsulDiscoveryProperties getProperties(String name, String tag, InetUtils inetUtils) {
private ConsulDiscoveryProperties getProperties(String name, String tag,
InetUtils inetUtils) {
ConsulDiscoveryProperties properties = new ConsulDiscoveryProperties(inetUtils);
HashMap<String, String> map = new HashMap<>();
map.put(name, tag);
@@ -115,8 +125,8 @@ public class ConsulServerListTests {
private NewService createService(String id, int port, List<String> tags) {
NewService service = new NewService();
service.setName(name);
service.setId(name + id);
service.setName(this.name);
service.setId(this.name + id);
service.setAddress("localhost");
service.setPort(port);
if (tags != null) {
@@ -124,4 +134,5 @@ public class ConsulServerListTests {
}
return service;
}
}

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