diff --git a/.editorconfig b/.editorconfig index 19546e0e2a..0e33fa5c7f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,7 +1,18 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file root = true [*] -end_of_line = lf -insert_final_newline = 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 diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 0000000000..f3e6046f04 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -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(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar old mode 100644 new mode 100755 index 5fd4d5023f..01e6799737 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties old mode 100644 new mode 100755 index 56bb0164ec..00d32aab1d --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip \ No newline at end of file +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip \ No newline at end of file diff --git a/.springformat b/.springformat new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/pom.xml b/docs/pom.xml index c6ddcae91f..bb0d01673e 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 org.springframework.cloud diff --git a/mvnw b/mvnw index a69491ac29..5551fde8e7 100755 --- a/mvnw +++ b/mvnw @@ -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)} -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 - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -echo "Running version check" -VERSION=$( sed '\!//' -e 's!.*$!!' ) -echo "The found version is [${VERSION}]" +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi -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" +########################################################################################## +# 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 - echo Deactivating \"milestone\" profile for version=\"$VERSION\" - echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//') + 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 +########################################################################################## -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//') +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" + +# 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 exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@" \ No newline at end of file + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd old mode 100644 new mode 100755 index b0dc0e7e98..48363fa60b --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,145 +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 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 - -set MAVEN_CMD_LINE_ARGS=%* - -@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="".\.mvn\wrapper\maven-wrapper.jar"" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% -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% +@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% diff --git a/pom.xml b/pom.xml index 96777c515c..8a3aeefe3f 100644 --- a/pom.xml +++ b/pom.xml @@ -16,8 +16,8 @@ ~ --> - 4.0.0 @@ -52,8 +52,11 @@ https://github.com/spring-cloud-incubator/spring-cloud-kubernetes - scm:git:git://github.com/spring-cloud-incubator/spring-cloud-kubernetes.git - scm:git:ssh://git@github.com/spring-cloud-incubator/spring-cloud-kubernetes.git + + scm:git:git://github.com/spring-cloud-incubator/spring-cloud-kubernetes.git + + + scm:git:ssh://git@github.com/spring-cloud-incubator/spring-cloud-kubernetes.git HEAD @@ -74,6 +77,12 @@ 2.4.12 3.0.2 1.1-groovy-2.4 + + true + true + + true + @@ -176,9 +185,26 @@ false + + org.apache.maven.plugins + maven-checkstyle-plugin + + + io.spring.javaformat + spring-javaformat-maven-plugin + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + spring diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml index 04efcd01e5..30d4514d94 100644 --- a/spring-cloud-kubernetes-config/pom.xml +++ b/spring-cloud-kubernetes-config/pom.xml @@ -1,6 +1,6 @@ - spring-cloud-kubernetes diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/AbstractConfigProperties.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/AbstractConfigProperties.java index 59a26f2ee6..b6078d6127 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/AbstractConfigProperties.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/AbstractConfigProperties.java @@ -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. @@ -12,21 +12,27 @@ * 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.kubernetes.config; +/** + * Abstraction over configuration properties. + * + * @author Ioannis Canellos + */ public abstract class AbstractConfigProperties { protected boolean enabled = true; + protected String name; + protected String namespace; public abstract String getConfigurationTarget(); public boolean isEnabled() { - return enabled; + return this.enabled; } public void setEnabled(boolean enabled) { @@ -34,7 +40,7 @@ public void setEnabled(boolean enabled) { } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -42,10 +48,11 @@ public void setName(String name) { } public String getNamespace() { - return namespace; + return this.namespace; } public void setNamespace(String namespace) { this.namespace = namespace; } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java index 9eecc82dbb..b9f644c255 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/BootstrapConfiguration.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config; @@ -30,6 +29,11 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +/** + * Auto configuration that reuses Kubernetes config maps as property sources. + * + * @author Ioannis Canellos + */ @Configuration @ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true) @ConditionalOnClass({ ConfigMap.class, Secret.class }) @@ -40,6 +44,7 @@ public class BootstrapConfiguration { @EnableConfigurationProperties({ ConfigMapConfigProperties.class, SecretsConfigProperties.class }) protected static class KubernetesPropertySourceConfiguration { + @Autowired private KubernetesClient client; @@ -47,14 +52,16 @@ protected static class KubernetesPropertySourceConfiguration { @ConditionalOnProperty(name = "spring.cloud.kubernetes.config.enabled", matchIfMissing = true) public ConfigMapPropertySourceLocator configMapPropertySourceLocator( ConfigMapConfigProperties properties) { - return new ConfigMapPropertySourceLocator(client, properties); + return new ConfigMapPropertySourceLocator(this.client, properties); } @Bean @ConditionalOnProperty(name = "spring.cloud.kubernetes.secrets.enabled", matchIfMissing = true) public SecretsPropertySourceLocator secretsPropertySourceLocator( SecretsConfigProperties properties) { - return new SecretsPropertySourceLocator(client, properties); + return new SecretsPropertySourceLocator(this.client, properties); } + } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapConfigProperties.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapConfigProperties.java index da3579e3c9..4a9634d16c 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapConfigProperties.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapConfigProperties.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config; @@ -25,33 +24,40 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.StringUtils; +/** + * Config map configuration properties. + * + * @author Ioannis Canellos + */ @ConfigurationProperties("spring.cloud.kubernetes.config") public class ConfigMapConfigProperties extends AbstractConfigProperties { private static final String TARGET = "Config Map"; private boolean enableApi = true; + private List paths = new LinkedList<>(); + private List sources = new LinkedList<>(); public boolean isEnableApi() { - return enableApi; + return this.enableApi; } public void setEnableApi(boolean enableApi) { this.enableApi = enableApi; } - public void setPaths(List paths) { - this.paths = paths; + public List getPaths() { + return this.paths; } - public List getPaths() { - return paths; + public void setPaths(List paths) { + this.paths = paths; } public List getSources() { - return sources; + return this.sources; } public void setSources(List sources) { @@ -67,15 +73,16 @@ public void setSources(List sources) { * ConfigMapPropertySource */ public List determineSources() { - if (sources.isEmpty()) { + if (this.sources.isEmpty()) { return new ArrayList() { { - add(new NormalizedSource(name, namespace)); + add(new NormalizedSource(ConfigMapConfigProperties.this.name, + ConfigMapConfigProperties.this.namespace)); } }; } - return sources.stream().map(s -> s.normalize(name, namespace)) + return this.sources.stream().map(s -> s.normalize(this.name, this.namespace)) .collect(Collectors.toList()); } @@ -84,15 +91,18 @@ public String getConfigurationTarget() { return TARGET; } + /** + * Config map source. + */ public static class Source { /** - * The name of the ConfigMap + * The name of the ConfigMap. */ private String name; /** - * The namespace where the ConfigMap is found + * The namespace where the ConfigMap is found. */ private String namespace; @@ -105,7 +115,7 @@ public Source(String name, String namespace) { } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -113,7 +123,7 @@ public void setName(String name) { } public String getNamespace() { - return namespace; + return this.namespace; } public void setNamespace(String namespace) { @@ -121,7 +131,7 @@ public void setNamespace(String namespace) { } public boolean isEmpty() { - return StringUtils.isEmpty(name) && StringUtils.isEmpty(namespace); + return StringUtils.isEmpty(this.name) && StringUtils.isEmpty(this.namespace); } public NormalizedSource normalize(String defaultName, String defaultNamespace) { @@ -132,23 +142,28 @@ public NormalizedSource normalize(String defaultName, String defaultNamespace) { return new NormalizedSource(normalizedName, normalizedNamespace); } + } static class NormalizedSource { + private final String name; + private final String namespace; - public NormalizedSource(String name, String namespace) { + NormalizedSource(String name, String namespace) { this.name = name; this.namespace = namespace; } public String getName() { - return name; + return this.name; } public String getNamespace() { - return namespace; + return this.namespace; } + } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java index affb8ccc89..4c809fe6c5 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java @@ -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. @@ -12,32 +12,41 @@ * 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.kubernetes.config; -import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.KEY_VALUE_TO_PROPERTIES; -import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.PROPERTIES_TO_MAP; -import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.yamlParserGenerator; - -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.client.KubernetesClient; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.client.KubernetesClient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.core.env.MapPropertySource; import org.springframework.util.StringUtils; +import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.KEY_VALUE_TO_PROPERTIES; +import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.PROPERTIES_TO_MAP; +import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.yamlParserGenerator; + +/** + * A {@link MapPropertySource} that uses Kubernetes config maps. + * + * @author Ioannis Canellos + */ public class ConfigMapPropertySource extends MapPropertySource { + private static final Log LOG = LogFactory.getLog(ConfigMapPropertySource.class); private static final String APPLICATION_YML = "application.yml"; + private static final String APPLICATION_YAML = "application.yaml"; + private static final String APPLICATION_PROPERTIES = "application.properties"; private static final String PREFIX = "configmap"; @@ -47,7 +56,7 @@ public ConfigMapPropertySource(KubernetesClient client, String name) { } public ConfigMapPropertySource(KubernetesClient client, String name, String namespace, - String[] profiles) { + String[] profiles) { super(getName(client, name, namespace), asObjectMap(getData(client, name, namespace, profiles))); } @@ -63,11 +72,11 @@ private static String getName(KubernetesClient client, String name, } private static Map getData(KubernetesClient client, String name, - String namespace, String[] profiles) { + String namespace, String[] profiles) { try { ConfigMap map = StringUtils.isEmpty(namespace) - ? client.configMaps().withName(name).get() - : client.configMaps().inNamespace(namespace).withName(name).get(); + ? client.configMaps().withName(name).get() + : client.configMaps().inNamespace(namespace).withName(name).get(); if (map != null) { return processAllEntries(map.getData(), profiles); @@ -75,7 +84,7 @@ private static Map getData(KubernetesClient client, String name, } catch (Exception e) { LOG.warn("Can't read configMap with name: [" + name + "] in namespace:[" - + namespace + "]. Ignoring"); + + namespace + "]. Ignoring"); } return new HashMap<>(); @@ -97,8 +106,7 @@ private static Map processAllEntries(Map input, + "] will be treated as a yaml file"); } - return yamlParserGenerator(profiles).andThen( - PROPERTIES_TO_MAP) + return yamlParserGenerator(profiles).andThen(PROPERTIES_TO_MAP) .apply(propertyValue); } else if (propertyName.endsWith(".properties")) { @@ -107,8 +115,7 @@ else if (propertyName.endsWith(".properties")) { + "] will be treated as a properties file"); } - return KEY_VALUE_TO_PROPERTIES.andThen( - PROPERTIES_TO_MAP) + return KEY_VALUE_TO_PROPERTIES.andThen(PROPERTIES_TO_MAP) .apply(propertyValue); } else { @@ -124,24 +131,27 @@ private static Map defaultProcessAllEntries(Map return input.entrySet().stream() .map(e -> extractProperties(e.getKey(), e.getValue(), profiles)) - .filter(m -> !m.isEmpty()) - .flatMap(m -> m.entrySet().stream()) + .filter(m -> !m.isEmpty()).flatMap(m -> m.entrySet().stream()) .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); } private static Map extractProperties(String resourceName, String content, String[] profiles) { - if (resourceName.equals(APPLICATION_YAML) || resourceName.equals(APPLICATION_YML)) { - return yamlParserGenerator(profiles).andThen(PROPERTIES_TO_MAP).apply(content); + if (resourceName.equals(APPLICATION_YAML) + || resourceName.equals(APPLICATION_YML)) { + return yamlParserGenerator(profiles).andThen(PROPERTIES_TO_MAP) + .apply(content); } else if (resourceName.equals(APPLICATION_PROPERTIES)) { return KEY_VALUE_TO_PROPERTIES.andThen(PROPERTIES_TO_MAP).apply(content); } - return new HashMap() {{ - put(resourceName, content); - }}; + return new HashMap() { + { + put(resourceName, content); + } + }; } private static Map asObjectMap(Map source) { diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java index 8ff1236f17..e6079b14bb 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java @@ -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. @@ -12,27 +12,22 @@ * 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.kubernetes.config; -import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationName; -import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationNamespace; -import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.KEY_VALUE_TO_PROPERTIES; -import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.PROPERTIES_TO_MAP; -import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.yamlParserGenerator; - -import io.fabric8.kubernetes.api.builder.Function; -import io.fabric8.kubernetes.client.KubernetesClient; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.List; import java.util.Map; + +import io.fabric8.kubernetes.api.builder.Function; +import io.fabric8.kubernetes.client.KubernetesClient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.cloud.bootstrap.config.PropertySourceLocator; import org.springframework.cloud.kubernetes.config.ConfigMapConfigProperties.NormalizedSource; import org.springframework.core.annotation.Order; @@ -42,12 +37,25 @@ import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; +import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationName; +import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationNamespace; +import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.KEY_VALUE_TO_PROPERTIES; +import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.PROPERTIES_TO_MAP; +import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.yamlParserGenerator; + +/** + * A {@link PropertySourceLocator} that uses config maps. + * + * @author Ioannis Canellos + */ @Order(0) public class ConfigMapPropertySourceLocator implements PropertySourceLocator { - private static final Log LOG = LogFactory.getLog(ConfigMapPropertySourceLocator.class); + private static final Log LOG = LogFactory + .getLog(ConfigMapPropertySourceLocator.class); private final KubernetesClient client; + private final ConfigMapConfigProperties properties; public ConfigMapPropertySourceLocator(KubernetesClient client, @@ -61,11 +69,11 @@ public PropertySource locate(Environment environment) { if (environment instanceof ConfigurableEnvironment) { ConfigurableEnvironment env = (ConfigurableEnvironment) environment; - List sources = properties + List sources = this.properties .determineSources(); CompositePropertySource composite = new CompositePropertySource( "composite-configmap"); - if (properties.isEnableApi()) { + if (this.properties.isEnableApi()) { sources.forEach(s -> composite.addFirstPropertySource( getMapPropertySourceForSingleConfigMap(env, s))); } @@ -80,71 +88,63 @@ public PropertySource locate(Environment environment) { private MapPropertySource getMapPropertySourceForSingleConfigMap( ConfigurableEnvironment environment, NormalizedSource normalizedSource) { - String configurationTarget = properties.getConfigurationTarget(); - return new ConfigMapPropertySource(client, + String configurationTarget = this.properties.getConfigurationTarget(); + return new ConfigMapPropertySource(this.client, getApplicationName(environment, normalizedSource.getName(), configurationTarget), - getApplicationNamespace(client, normalizedSource.getNamespace(), + getApplicationNamespace(this.client, normalizedSource.getNamespace(), configurationTarget), environment.getActiveProfiles()); } private void addPropertySourcesFromPaths(Environment environment, - CompositePropertySource composite) { - properties - .getPaths() - .stream() - .map(Paths::get) - .peek(p -> { - if(!Files.exists(p)) { - LOG.warn("Configured input path: " + p + " will be ignored because it does not exist on the file system"); - } - }) - .filter(Files::exists) - .peek(p -> { - if(!Files.isRegularFile(p)) { - LOG.warn("Configured input path: " + p + " will be ignored because it is not a regular file"); + CompositePropertySource composite) { + this.properties.getPaths().stream().map(Paths::get).peek(p -> { + if (!Files.exists(p)) { + LOG.warn("Configured input path: " + p + + " will be ignored because it does not exist on the file system"); + } + }).filter(Files::exists).peek(p -> { + if (!Files.isRegularFile(p)) { + LOG.warn("Configured input path: " + p + + " will be ignored because it is not a regular file"); + } + }).filter(Files::isRegularFile).forEach(p -> { + try { + String content = new String(Files.readAllBytes(p)).trim(); + String filename = p.getFileName().toString().toLowerCase(); + if (filename.endsWith(".properties")) { + addPropertySourceIfNeeded( + c -> PROPERTIES_TO_MAP + .apply(KEY_VALUE_TO_PROPERTIES.apply(c)), + content, filename, composite); } - }) - .filter(Files::isRegularFile) - .forEach(p -> { - try { - String content = new String(Files.readAllBytes(p)).trim(); - String filename = p.getFileName().toString().toLowerCase(); - if(filename.endsWith(".properties")) { - addPropertySourceIfNeeded( - c -> PROPERTIES_TO_MAP.apply(KEY_VALUE_TO_PROPERTIES.apply(c)), - content, - filename, - composite - ); - } - else if(filename.endsWith(".yml") || filename.endsWith(".yaml")) { - addPropertySourceIfNeeded( - c -> PROPERTIES_TO_MAP.apply( - yamlParserGenerator(environment.getActiveProfiles()).apply(c) - ), - content, - filename, - composite - ); - } - } catch (IOException e) { - LOG.warn("Error reading input file", e); + else if (filename.endsWith(".yml") || filename.endsWith(".yaml")) { + addPropertySourceIfNeeded(c -> PROPERTIES_TO_MAP + .apply(yamlParserGenerator(environment.getActiveProfiles()) + .apply(c)), + content, filename, composite); } - }); + } + catch (IOException e) { + LOG.warn("Error reading input file", e); + } + }); } - private void addPropertySourceIfNeeded(Function> contentToMapFunction, - String content, String name, CompositePropertySource composite) { + private void addPropertySourceIfNeeded( + Function> contentToMapFunction, String content, + String name, CompositePropertySource composite) { Map map = new HashMap<>(); map.putAll(contentToMapFunction.apply(content)); - if(map.isEmpty()) { - LOG.warn("Property source: " + name + "will be ignored because no properties could be found"); + if (map.isEmpty()) { + LOG.warn("Property source: " + name + + "will be ignored because no properties could be found"); } else { composite.addFirstPropertySource(new MapPropertySource(name, map)); } } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigUtils.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigUtils.java index cfb15ef98f..c239b90eca 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigUtils.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigUtils.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config; @@ -27,10 +26,19 @@ import static org.springframework.cloud.kubernetes.config.Constants.FALLBACK_APPLICATION_NAME; import static org.springframework.cloud.kubernetes.config.Constants.SPRING_APPLICATION_NAME; -public class ConfigUtils { +/** + * Utility class that works with configuration properties. + * + * @author Ioannis Canellos + */ +public final class ConfigUtils { private static final Log LOG = LogFactory.getLog(ConfigUtils.class); + private ConfigUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + public static String getApplicationName( Environment env, String configName, String configurationTarget) { String name = configName; diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/Constants.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/Constants.java index fe4cd2b4f9..680b80b081 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/Constants.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/Constants.java @@ -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. @@ -12,15 +12,17 @@ * 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.kubernetes.config; final class Constants { + static final String SPRING_APPLICATION_NAME = "spring.application.name"; static final String FALLBACK_APPLICATION_NAME = "application"; static final String PROPERTY_SOURCE_NAME_SEPARATOR = "."; private Constants() { } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/KubernetesPropertySource.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/KubernetesPropertySource.java index 8ee235a9d9..ac902b10e6 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/KubernetesPropertySource.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/KubernetesPropertySource.java @@ -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. @@ -12,15 +12,10 @@ * 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.kubernetes.config; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.core.env.MapPropertySource; - import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -28,10 +23,18 @@ import java.util.List; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.core.env.MapPropertySource; + /** * Secrets and ConfigMaps shared features. + * + * @author Stefan Larsson */ public class KubernetesPropertySource extends MapPropertySource { + private static final Log LOG = LogFactory.getLog(KubernetesPropertySource.class); @SuppressWarnings("unchecked") @@ -39,31 +42,30 @@ protected KubernetesPropertySource(String name, Map source) { super(name, source); } - protected static void putPathConfig(Map result, List paths) { - paths - .stream() - .map(Paths::get) - .filter(Files::exists) - .forEach(p -> putAll(p, result)); + protected static void putPathConfig(Map result, + List paths) { + paths.stream().map(Paths::get).filter(Files::exists) + .forEach(p -> putAll(p, result)); } private static void putAll(Path path, Map result) { try { - Files.walk(path) - .filter(Files::isRegularFile) - .forEach(p -> readFile(p, result)); - } catch (IOException e) { + Files.walk(path).filter(Files::isRegularFile) + .forEach(p -> readFile(p, result)); + } + catch (IOException e) { LOG.warn("Error walking properties files", e); } } private static void readFile(Path path, Map result) { try { - result.put( - path.getFileName().toString(), - new String(Files.readAllBytes(path)).trim()); - } catch (IOException e) { + result.put(path.getFileName().toString(), + new String(Files.readAllBytes(path)).trim()); + } + catch (IOException e) { LOG.warn("Error reading properties file", e); } } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java index ed8ecfffba..4fb79e216e 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java @@ -1,9 +1,20 @@ -package org.springframework.cloud.kubernetes.config; +/* + * 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 java.util.Arrays.asList; -import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.ABSTAIN; -import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.FOUND; -import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.NOT_FOUND; +package org.springframework.cloud.kubernetes.config; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -11,35 +22,41 @@ import java.util.Properties; import java.util.function.Function; import java.util.stream.Collectors; + import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; import org.springframework.core.io.ByteArrayResource; -public class PropertySourceUtils { - - static final Function KEY_VALUE_TO_PROPERTIES = - s -> { - Properties properties = new Properties(); - try { - properties.load(new ByteArrayInputStream(s.getBytes())); - return properties; - } - catch (IOException e) { - throw new IllegalArgumentException(); +import static java.util.Arrays.asList; +import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.ABSTAIN; +import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.FOUND; +import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.NOT_FOUND; + +/** + * Utility class to work with property sources. + * + * @author Georgios Andrianakis + */ +public final class PropertySourceUtils { + + static final Function KEY_VALUE_TO_PROPERTIES = s -> { + Properties properties = new Properties(); + try { + properties.load(new ByteArrayInputStream(s.getBytes())); + return properties; + } + catch (IOException e) { + throw new IllegalArgumentException(); } }; + static final Function> PROPERTIES_TO_MAP = p -> p + .entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()), + e -> String.valueOf(e.getValue()))); + + private PropertySourceUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } - static final Function> PROPERTIES_TO_MAP = - p -> p.entrySet() - .stream() - .collect( - Collectors.toMap( - e -> String.valueOf(e.getKey()), - e -> String.valueOf(e.getValue()) - ) - ); - - static Function yamlParserGenerator( - final String[] profiles) { + static Function yamlParserGenerator(final String[] profiles) { return s -> { YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean(); yamlFactory.setDocumentMatchers(properties -> { @@ -55,4 +72,5 @@ static Function yamlParserGenerator( return yamlFactory.getObject(); }; } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsConfigProperties.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsConfigProperties.java index 0655b5515b..f5c5bfc437 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsConfigProperties.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsConfigProperties.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config; import java.util.HashMap; @@ -23,41 +23,49 @@ import org.springframework.boot.context.properties.ConfigurationProperties; +/** + * Properties for configuring Kubernetes secrets. + * + * @author l burgazzoli + */ @ConfigurationProperties("spring.cloud.kubernetes.secrets") public class SecretsConfigProperties extends AbstractConfigProperties { private static final String TARGET = "Secret"; private boolean enableApi = false; + private Map labels = new HashMap<>(); + private List paths = new LinkedList<>(); public boolean isEnableApi() { - return enableApi; + return this.enableApi; } public void setEnableApi(boolean enableApi) { this.enableApi = enableApi; } + public Map getLabels() { + return this.labels; + } + public void setLabels(Map labels) { this.labels = labels; } - public Map getLabels() { - return labels; + public List getPaths() { + return this.paths; } public void setPaths(List paths) { this.paths = paths; } - public List getPaths() { - return paths; - } - @Override public String getConfigurationTarget() { return TARGET; } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySource.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySource.java index 8686ed4ac4..f8f75a624d 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySource.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySource.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config; import java.util.Base64; @@ -31,33 +31,40 @@ import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationName; import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationNamespace; +/** + * Kubernetes property source for secrets. + * + * @author l burgazzoli + */ public class SecretsPropertySource extends KubernetesPropertySource { + private static final Log LOG = LogFactory.getLog(SecretsPropertySource.class); private static final String PREFIX = "secrets"; public SecretsPropertySource(KubernetesClient client, Environment env, - SecretsConfigProperties config) { + SecretsConfigProperties config) { super(getSourceName(client, env, config), getSourceData(client, env, config)); } private static String getSourceName(KubernetesClient client, Environment env, - SecretsConfigProperties config) { + SecretsConfigProperties config) { return new StringBuilder().append(PREFIX) - .append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR).append( - getApplicationName(env, config.getName(), - config.getConfigurationTarget())) - .append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR).append( - getApplicationNamespace(client, config.getNamespace(), - config.getConfigurationTarget())).toString(); + .append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR) + .append(getApplicationName(env, config.getName(), + config.getConfigurationTarget())) + .append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR) + .append(getApplicationNamespace(client, config.getNamespace(), + config.getConfigurationTarget())) + .toString(); } private static Map getSourceData(KubernetesClient client, - Environment env, SecretsConfigProperties config) { + Environment env, SecretsConfigProperties config) { String name = getApplicationName(env, config.getName(), - config.getConfigurationTarget()); + config.getConfigurationTarget()); String namespace = getApplicationNamespace(client, config.getNamespace(), - config.getConfigurationTarget()); + config.getConfigurationTarget()); Map result = new HashMap<>(); if (config.isEnableApi()) { @@ -76,20 +83,19 @@ private static Map getSourceData(KubernetesClient client, if (!config.getLabels().isEmpty()) { if (StringUtils.isEmpty(namespace)) { client.secrets().withLabels(config.getLabels()).list().getItems() - .forEach(s -> putAll(s, result)); + .forEach(s -> putAll(s, result)); } else { client.secrets().inNamespace(namespace) - .withLabels(config.getLabels()).list().getItems() - .forEach(s -> putAll(s, result)); + .withLabels(config.getLabels()).list().getItems() + .forEach(s -> putAll(s, result)); } } } catch (Exception e) { - LOG.warn( - "Can't read secret with name: [" + name + "] or labels [" + config - .getLabels() + "] in namespace:[" + namespace + "] (cause: " + e - .getMessage() + "). Ignoring"); + LOG.warn("Can't read secret with name: [" + name + "] or labels [" + + config.getLabels() + "] in namespace:[" + namespace + + "] (cause: " + e.getMessage() + "). Ignoring"); } } @@ -99,17 +105,19 @@ private static Map getSourceData(KubernetesClient client, return result; } - @Override public String toString() { - return getClass().getSimpleName() + " {name='" + this.name + "'}"; - } - // ***************************** // Helpers // ***************************** private static void putAll(Secret secret, Map result) { if (secret != null && secret.getData() != null) { - secret.getData().forEach((k, v) -> result - .put(k, new String(Base64.getDecoder().decode(v)).trim())); + secret.getData().forEach((k, v) -> result.put(k, + new String(Base64.getDecoder().decode(v)).trim())); } } + + @Override + public String toString() { + return getClass().getSimpleName() + " {name='" + this.name + "'}"; + } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceLocator.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceLocator.java index fec0020ef0..236ceb11a8 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceLocator.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceLocator.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config; @@ -25,9 +24,16 @@ import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; +/** + * Kubernetes {@link PropertySourceLocator} for secrets. + * + * @author l burgazzoli + */ @Order(1) public class SecretsPropertySourceLocator implements PropertySourceLocator { + private final KubernetesClient client; + private final SecretsConfigProperties properties; public SecretsPropertySourceLocator(KubernetesClient client, @@ -39,6 +45,8 @@ public SecretsPropertySourceLocator(KubernetesClient client, @Override public MapPropertySource locate(Environment environment) { return environment instanceof ConfigurableEnvironment - ? new SecretsPropertySource(client, environment, properties) : null; + ? new SecretsPropertySource(this.client, environment, this.properties) + : null; } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java index 5cfe6de789..884a313bb7 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config.reload; import io.fabric8.kubernetes.client.KubernetesClient; @@ -41,6 +41,8 @@ /** * Definition of beans needed for the automatic reload of configuration. + * + * @author Nicolla Ferraro */ @Configuration @ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true) @@ -54,7 +56,7 @@ public class ConfigReloadAutoConfiguration { /** * Configuration reload must be enabled explicitly. */ - @ConditionalOnProperty(value = "spring.cloud.kubernetes.reload.enabled") + @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") @ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class }) @EnableScheduling @EnableAsync @@ -73,7 +75,9 @@ protected static class ConfigReloadAutoConfigurationBeans { private SecretsPropertySourceLocator secretsPropertySourceLocator; /** - * Provides a bean that listen to configuration changes and fire a reload. + * @param properties config reload properties + * @param strategy configuration update strategy + * @return a bean that listen to configuration changes and fire a reload. */ @Bean @ConditionalOnMissingBean @@ -81,20 +85,26 @@ public ConfigurationChangeDetector propertyChangeWatcher( ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy) { switch (properties.getMode()) { case POLLING: - return new PollingConfigurationChangeDetector(environment, properties, - kubernetesClient, strategy, configMapPropertySourceLocator, - secretsPropertySourceLocator); + return new PollingConfigurationChangeDetector(this.environment, + properties, this.kubernetesClient, strategy, + this.configMapPropertySourceLocator, + this.secretsPropertySourceLocator); case EVENT: - return new EventBasedConfigurationChangeDetector(environment, properties, - kubernetesClient, strategy, configMapPropertySourceLocator, - secretsPropertySourceLocator); + return new EventBasedConfigurationChangeDetector(this.environment, + properties, this.kubernetesClient, strategy, + this.configMapPropertySourceLocator, + this.secretsPropertySourceLocator); } throw new IllegalStateException( "Unsupported configuration reload mode: " + properties.getMode()); } /** - * Provides the action to execute when the configuration changes. + * @param properties config reload properties + * @param ctx application context + * @param restarter restart endpoint + * @param refresher context refresher + * @return provides the action to execute when the configuration changes. */ @Bean @ConditionalOnMissingBean diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadProperties.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadProperties.java index cc0c0fbefa..07eec60ca1 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadProperties.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadProperties.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config.reload; import java.time.Duration; @@ -22,6 +22,8 @@ /** * General configuration for the configuration reload. + * + * @author Nicola Ferraro */ @ConfigurationProperties(prefix = "spring.cloud.kubernetes.reload") public class ConfigReloadProperties { @@ -60,7 +62,7 @@ public ConfigReloadProperties() { } public boolean isEnabled() { - return enabled; + return this.enabled; } public void setEnabled(boolean enabled) { @@ -68,7 +70,7 @@ public void setEnabled(boolean enabled) { } public boolean isMonitoringConfigMaps() { - return monitoringConfigMaps; + return this.monitoringConfigMaps; } public void setMonitoringConfigMaps(boolean monitoringConfigMaps) { @@ -76,7 +78,7 @@ public void setMonitoringConfigMaps(boolean monitoringConfigMaps) { } public boolean isMonitoringSecrets() { - return monitoringSecrets; + return this.monitoringSecrets; } public void setMonitoringSecrets(boolean monitoringSecrets) { @@ -84,7 +86,7 @@ public void setMonitoringSecrets(boolean monitoringSecrets) { } public ReloadStrategy getStrategy() { - return strategy; + return this.strategy; } public void setStrategy(ReloadStrategy strategy) { @@ -92,22 +94,26 @@ public void setStrategy(ReloadStrategy strategy) { } public ReloadDetectionMode getMode() { - return mode; + return this.mode; } - public void setPeriod(Duration period) { - this.period = period; + public void setMode(ReloadDetectionMode mode) { + this.mode = mode; } public Duration getPeriod() { - return period; + return this.period; } - public void setMode(ReloadDetectionMode mode) { - this.mode = mode; + public void setPeriod(Duration period) { + this.period = period; } + /** + * Reload strategies. + */ public enum ReloadStrategy { + /** * Fire a refresh of beans annotated with @ConfigurationProperties * or @RefreshScope. @@ -126,9 +132,14 @@ public enum ReloadStrategy { * configured to restart the pod. */ SHUTDOWN + } + /** + * Reload detection modes. + */ public enum ReloadDetectionMode { + /** * Enables a polling task that retrieves periodically all external properties and * fire a reload when they change. @@ -140,6 +151,7 @@ public enum ReloadDetectionMode { * or secrets change. */ EVENT + } } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java index b03085c02b..6b64406030 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config.reload; import java.util.ArrayList; @@ -38,6 +38,8 @@ /** * This is the superclass of all beans that can listen to changes in the configuration and * fire a reload. + * + * @author Nicola Ferraro */ public abstract class ConfigurationChangeDetector { @@ -64,22 +66,27 @@ public ConfigurationChangeDetector(ConfigurableEnvironment environment, public void shutdown() { // Ensure the kubernetes client is cleaned up from spare threads when shutting // down - kubernetesClient.close(); + this.kubernetesClient.close(); } public void reloadProperties() { - log.info("Reloading using strategy: " + strategy.getName()); - strategy.reload(); + this.log.info("Reloading using strategy: " + this.strategy.getName()); + this.strategy.reload(); } /** * Determines if two property sources are different. + * @param mp1 map property sources 1 + * @param mp2 map property sources 2 + * @return {@code true} if source has changed */ protected boolean changed(MapPropertySource mp1, MapPropertySource mp2) { - if (mp1 == mp2) + if (mp1 == mp2) { return false; - if (mp1 == null && mp2 != null || mp1 != null && mp2 == null) + } + if (mp1 == null && mp2 != null || mp1 != null && mp2 == null) { return true; + } Map s1 = mp1.getSource(); Map s2 = mp2.getSource(); @@ -91,8 +98,9 @@ protected boolean changed(List l1, List l2) { if (l1.size() != l2.size()) { - log.debug("The current number of Confimap PropertySources does not match " - + "the ones loaded from the Kubernetes - No reload will take place"); + this.log.debug( + "The current number of Confimap PropertySources does not match " + + "the ones loaded from the Kubernetes - No reload will take place"); return false; } @@ -107,6 +115,9 @@ protected boolean changed(List l1, /** * Finds one registered property source of the given type, logging a warning if * multiple property sources of that type are available. + * @param property source type + * @param sourceClass class for which property sources will be searched for + * @return matched property source */ protected > S findPropertySource(Class sourceClass) { List sources = findPropertySources(sourceClass); @@ -114,20 +125,22 @@ protected > S findPropertySource(Class sourceClas return null; } if (sources.size() > 1) { - log.warn("Found more than one property source of type " + sourceClass); + this.log.warn("Found more than one property source of type " + sourceClass); } return sources.get(0); } /** - * Finds all registered property sources of the given type. + * @param property source type + * @param sourceClass class for which property sources will be found + * @return finds all registered property sources of the given type */ protected > List findPropertySources( Class sourceClass) { List managedSources = new LinkedList<>(); LinkedList> sources = toLinkedList( - environment.getPropertySources()); + this.environment.getPropertySources()); while (!sources.isEmpty()) { PropertySource source = sources.pop(); if (source instanceof CompositePropertySource) { @@ -152,7 +165,11 @@ private LinkedList toLinkedList(Iterable it) { /** * Returns a list of MapPropertySource that correspond to the current state of the - * system This only handles the PropertySource objects that are returned + * system. This only handles the PropertySource objects that are returned. + * @param propertySourceLocator Spring's property source locator + * @param environment Spring environment + * @return a list of MapPropertySource that correspond to the current state of the + * system */ protected List locateMapPropertySources( PropertySourceLocator propertySourceLocator, Environment environment) { @@ -168,7 +185,7 @@ else if (propertySource instanceof CompositePropertySource) { .map(p -> (MapPropertySource) p).collect(Collectors.toList())); } else { - log.debug("Found property source that cannot be handled: " + this.log.debug("Found property source that cannot be handled: " + propertySource.getClass()); } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationUpdateStrategy.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationUpdateStrategy.java index 7862f59b40..03ce9ae115 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationUpdateStrategy.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationUpdateStrategy.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config.reload; import java.util.Objects; @@ -21,6 +21,8 @@ /** * This is the superclass of all named strategies that can be fired when the configuration * changes. + * + * @author Nicola Ferraro */ public class ConfigurationUpdateStrategy { @@ -36,7 +38,7 @@ public ConfigurationUpdateStrategy(String name, Runnable reloadProcedure) { } public String getName() { - return name; + return this.name; } public void reload() { @@ -46,8 +48,9 @@ public void reload() { @Override public String toString() { final StringBuilder sb = new StringBuilder("ConfigurationUpdateStrategy{"); - sb.append("name='").append(name).append('\''); + sb.append("name='").append(this.name).append('\''); sb.append('}'); return sb.toString(); } + } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java index ca90103c76..2d4a236016 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config.reload; import java.util.HashMap; @@ -39,6 +39,8 @@ /** * A change detector that subscribes to changes in secrets and configmaps and fire a * reload when something changes. + * + * @author Nicola Ferraro */ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDetector { @@ -64,11 +66,11 @@ public EventBasedConfigurationChangeDetector(AbstractEnvironment environment, public void watch() { boolean activated = false; - if (properties.isMonitoringConfigMaps()) { + if (this.properties.isMonitoringConfigMaps()) { try { String name = "config-maps-watch"; - watches.put(name, - kubernetesClient.configMaps().watch(new Watcher() { + this.watches.put(name, this.kubernetesClient.configMaps() + .watch(new Watcher() { @Override public void eventReceived(Action action, ConfigMap configMap) { @@ -80,41 +82,43 @@ public void onClose(KubernetesClientException e) { } })); activated = true; - log.info("Added new Kubernetes watch: " + name); + this.log.info("Added new Kubernetes watch: " + name); } catch (Exception e) { - log.error( + this.log.error( "Error while establishing a connection to watch config maps: configuration may remain stale", e); } } - if (properties.isMonitoringSecrets()) { + if (this.properties.isMonitoringSecrets()) { try { activated = false; String name = "secrets-watch"; - watches.put(name, kubernetesClient.secrets().watch(new Watcher() { - @Override - public void eventReceived(Action action, Secret secret) { - onEvent(secret); - } - - @Override - public void onClose(KubernetesClientException e) { - } - })); + this.watches.put(name, + this.kubernetesClient.secrets().watch(new Watcher() { + @Override + public void eventReceived(Action action, Secret secret) { + onEvent(secret); + } + + @Override + public void onClose(KubernetesClientException e) { + } + })); activated = true; - log.info("Added new Kubernetes watch: " + name); + this.log.info("Added new Kubernetes watch: " + name); } catch (Exception e) { - log.error( + this.log.error( "Error while establishing a connection to watch secrets: configuration may remain stale", e); } } if (activated) { - log.info("Kubernetes event-based configuration change detector activated"); + this.log.info( + "Kubernetes event-based configuration change detector activated"); } } @@ -123,12 +127,12 @@ public void unwatch() { if (this.watches != null) { for (Map.Entry entry : this.watches.entrySet()) { try { - log.debug("Closing the watch " + entry.getKey()); + this.log.debug("Closing the watch " + entry.getKey()); entry.getValue().close(); } catch (Exception e) { - log.error("Error while closing the watch connection", e); + this.log.error("Error while closing the watch connection", e); } } } @@ -136,10 +140,11 @@ public void unwatch() { private void onEvent(ConfigMap configMap) { boolean changed = changed( - locateMapPropertySources(configMapPropertySourceLocator, environment), + locateMapPropertySources(this.configMapPropertySourceLocator, + this.environment), findPropertySources(ConfigMapPropertySource.class)); if (changed) { - log.info("Detected change in config maps"); + this.log.info("Detected change in config maps"); reloadProperties(); } } @@ -148,10 +153,10 @@ private void onEvent(Secret secret) { MapPropertySource currentSecretSource = findPropertySource( SecretsPropertySource.class); if (currentSecretSource != null) { - MapPropertySource newSecretSource = secretsPropertySourceLocator - .locate(environment); + MapPropertySource newSecretSource = this.secretsPropertySourceLocator + .locate(this.environment); if (changed(currentSecretSource, newSecretSource)) { - log.info("Detected change in secrets"); + this.log.info("Detected change in secrets"); reloadProperties(); } } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/PollingConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/PollingConfigurationChangeDetector.java index 08812ee87e..99afc9efcb 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/PollingConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/PollingConfigurationChangeDetector.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.config.reload; import java.util.List; @@ -35,6 +35,8 @@ /** * A change detector that periodically retrieves secrets and configmaps and fire a reload * when something changes. + * + * @author Nicola Ferraro */ public class PollingConfigurationChangeDetector extends ConfigurationChangeDetector { @@ -57,32 +59,32 @@ public PollingConfigurationChangeDetector(AbstractEnvironment environment, @PostConstruct public void init() { - log.info("Kubernetes polling configuration change detector activated"); + this.log.info("Kubernetes polling configuration change detector activated"); } @Scheduled(initialDelayString = "${spring.cloud.kubernetes.reload.period:15000}", fixedDelayString = "${spring.cloud.kubernetes.reload.period:15000}") public void executeCycle() { boolean changedConfigMap = false; - if (properties.isMonitoringConfigMaps()) { + if (this.properties.isMonitoringConfigMaps()) { List currentConfigMapSources = findPropertySources( ConfigMapPropertySource.class); if (!currentConfigMapSources.isEmpty()) { changedConfigMap = changed( - locateMapPropertySources(configMapPropertySourceLocator, - environment), + locateMapPropertySources(this.configMapPropertySourceLocator, + this.environment), currentConfigMapSources); } } boolean changedSecrets = false; - if (properties.isMonitoringSecrets()) { + if (this.properties.isMonitoringSecrets()) { MapPropertySource currentSecretSource = findPropertySource( SecretsPropertySource.class); if (currentSecretSource != null) { - MapPropertySource newSecretSource = secretsPropertySourceLocator - .locate(environment); + MapPropertySource newSecretSource = this.secretsPropertySourceLocator + .locate(this.environment); changedSecrets = changed(currentSecretSource, newSecretSource); } } diff --git a/spring-cloud-kubernetes-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-kubernetes-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 7440879071..03045e2a88 100644 --- a/spring-cloud-kubernetes-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-kubernetes-config/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,15 +1,17 @@ -{"properties": [ - { - "name": "spring.cloud.kubernetes.config.enabled", - "type": "java.lang.Boolean", - "description": "Enable the ConfigMap property source locator.", - "defaultValue": true - }, - { - "name": "spring.cloud.kubernetes.secrets.enabled", - "type": "java.lang.Boolean", - "description": "Enable the Secrets property source locator.", - "defaultValue": true - } -]} +{ + "properties": [ + { + "name": "spring.cloud.kubernetes.config.enabled", + "type": "java.lang.Boolean", + "description": "Enable the ConfigMap property source locator.", + "defaultValue": true + }, + { + "name": "spring.cloud.kubernetes.secrets.enabled", + "type": "java.lang.Boolean", + "description": "Enable the Secrets property source locator.", + "defaultValue": true + } + ] +} diff --git a/spring-cloud-kubernetes-config/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-config/src/main/resources/META-INF/spring.factories index 142d79998d..90e6af77b4 100644 --- a/spring-cloud-kubernetes-config/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-kubernetes-config/src/main/resources/META-INF/spring.factories @@ -1,5 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.kubernetes.config.reload.ConfigReloadAutoConfiguration - org.springframework.cloud.bootstrap.BootstrapConfiguration=\ org.springframework.cloud.kubernetes.config.BootstrapConfiguration diff --git a/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy b/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy index 3991be7305..1777635454 100644 --- a/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy +++ b/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy @@ -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. @@ -12,27 +12,27 @@ * 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.kubernetes.config -import io.fabric8.kubernetes.api.model.SecretBuilder +import groovy.util.logging.Slf4j import io.fabric8.kubernetes.api.model.ConfigMapBuilder +import io.fabric8.kubernetes.api.model.SecretBuilder import io.fabric8.kubernetes.client.Config import io.fabric8.kubernetes.client.KubernetesClient import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer +import spock.lang.Specification + import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.test.context.SpringBootTest import org.springframework.core.env.Environment import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification -import groovy.util.logging.Slf4j @Slf4j -@ContextConfiguration(classes=[TestApplication.class]) -@SpringBootTest(properties=[ +@ContextConfiguration(classes = [TestApplication.class]) +@SpringBootTest(properties = [ "spring.application.name=testapp", "spring.cloud.kubernetes.client.namespace=testns", "spring.cloud.kubernetes.client.trustCerts=true", @@ -42,84 +42,87 @@ import groovy.util.logging.Slf4j @EnableConfigurationProperties class CoreTest extends Specification { - private static KubernetesMockServer mockServer = new KubernetesMockServer() - private static KubernetesClient mockClient - - @Autowired - Environment environment - - @Autowired(required = false) - Config config - - @Autowired(required = false) - KubernetesClient client - - def setupSpec() { - mockServer.init() - mockClient = mockServer.createClient() - - mockServer.expect().get() - .withPath("/api/v1/namespaces/testns/configmaps/testapp") - .andReturn( - 200, - new ConfigMapBuilder() - .withData([ - 'spring.kubernetes.test.value': 'value1']) - .build()) - .always() - mockServer.expect().get() - .withPath("/api/v1/namespaces/testns/secrets/testapp") - .andReturn( - 200, - new SecretBuilder() - .withData([ - 'amq.pwd': 'MWYyZDFlMmU2N2Rm', - 'amq.usr': 'YWRtaW4K' - ]) - .build()) - .always() - - //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()) - System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true") - System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false") - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false") - } - - def cleanupSpec() { - mockServer.destroy(); - } - - def "Kubernetes client config bean should be present"() { - expect: - config != null - } - - def "Kubernetes client config bean should be configurable via system properties"() { - expect: - config.getMasterUrl().equals(mockClient.getConfiguration().getMasterUrl()) - config.getNamespace().equals("testns") - config.trustCerts - } - - def "Kubernetes client bean should be present"() { - expect: - client != null - } - - def "Kubernetes client should be configured from system properties"() { - expect: - client.getConfiguration().getMasterUrl().equals(mockClient.getConfiguration().getMasterUrl()) - } - - def "properties should be read from config map"() { - expect: - environment.getProperty("spring.kubernetes.test.value").equals("value1") - } - - def "properties should be read from secrets"() { - expect: - environment.getProperty("amq.pwd").equals("1f2d1e2e67df") - environment.getProperty("amq.usr").equals('admin'); - } + private static KubernetesMockServer mockServer = new KubernetesMockServer() + private static KubernetesClient mockClient + + @Autowired + Environment environment + + @Autowired(required = false) + Config config + + @Autowired(required = false) + KubernetesClient client + + def setupSpec() { + mockServer.init() + mockClient = mockServer.createClient() + + mockServer.expect().get() + .withPath("/api/v1/namespaces/testns/configmaps/testapp") + .andReturn( + 200, + new ConfigMapBuilder() + .withData([ + 'spring.kubernetes.test.value': 'value1']) + .build()) + .always() + mockServer.expect().get() + .withPath("/api/v1/namespaces/testns/secrets/testapp") + .andReturn( + 200, + new SecretBuilder() + .withData([ + 'amq.pwd': 'MWYyZDFlMmU2N2Rm', + 'amq.usr': 'YWRtaW4K' + ]) + .build()) + .always() + + //Configure the kubernetes master url to point to the mock server + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient. + getConfiguration().getMasterUrl()) + System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true") + System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false") + System. + setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false") + } + + def cleanupSpec() { + mockServer.destroy(); + } + + def "Kubernetes client config bean should be present"() { + expect: + config != null + } + + def "Kubernetes client config bean should be configurable via system properties"() { + expect: + config.getMasterUrl().equals(mockClient.getConfiguration().getMasterUrl()) + config.getNamespace().equals("testns") + config.trustCerts + } + + def "Kubernetes client bean should be present"() { + expect: + client != null + } + + def "Kubernetes client should be configured from system properties"() { + expect: + client.getConfiguration().getMasterUrl(). + equals(mockClient.getConfiguration().getMasterUrl()) + } + + def "properties should be read from config map"() { + expect: + environment.getProperty("spring.kubernetes.test.value").equals("value1") + } + + def "properties should be read from secrets"() { + expect: + environment.getProperty("amq.pwd").equals("1f2d1e2e67df") + environment.getProperty("amq.usr").equals('admin'); + } } diff --git a/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/TestApplication.groovy b/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/TestApplication.groovy index b4e9685538..6f3e7a1974 100644 --- a/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/TestApplication.groovy +++ b/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/TestApplication.groovy @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config @@ -23,7 +22,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication @SpringBootApplication class TestApplication { - def main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } + def main(String[] args) { + SpringApplication.run(TestApplication.class, args); + } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapTestUtil.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapTestUtil.java index d2199076a7..08fce06e3c 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapTestUtil.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapTestUtil.java @@ -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. @@ -12,28 +12,27 @@ * 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.kubernetes.config; -import io.fabric8.kubernetes.client.utils.IOHelpers; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; +import io.fabric8.kubernetes.client.utils.IOHelpers; + final class ConfigMapTestUtil { private ConfigMapTestUtil() { } - static String readResourceFile(String file) { String resource; try { resource = IOHelpers.readFully( - ConfigMapTestUtil.class.getClassLoader().getResourceAsStream(file)); + ConfigMapTestUtil.class.getClassLoader().getResourceAsStream(file)); } catch (IOException e) { resource = ""; @@ -44,4 +43,5 @@ static String readResourceFile(String file) { static void createFileWithContent(String file, String content) throws IOException { Files.write(Paths.get(file), content.getBytes(), StandardOpenOption.CREATE); } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsFromFilePathsSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsFromFilePathsSpringBootTest.java index 6f58608503..7a7a26ae0c 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsFromFilePathsSpringBootTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsFromFilePathsSpringBootTest.java @@ -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. @@ -12,56 +12,65 @@ * 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.kubernetes.config; -import static org.assertj.core.util.Lists.newArrayList; -import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.createFileWithContent; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.kubernetes.config.example.App; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; +import static org.assertj.core.util.Lists.newArrayList; +import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.createFileWithContent; + @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class , properties = { - "spring.application.name=configmap-path-example", - "spring.cloud.kubernetes.config.enableApi=false", - "spring.cloud.kubernetes.config.paths=" - + ConfigMapsFromFilePathsSpringBootTest.FIRST_FILE_NAME_FULL_PATH + "," - + ConfigMapsFromFilePathsSpringBootTest.SECOND_FILE_NAME_FULL_PATH -}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = { + "spring.application.name=configmap-path-example", + "spring.cloud.kubernetes.config.enableApi=false", + "spring.cloud.kubernetes.config.paths=" + + ConfigMapsFromFilePathsSpringBootTest.FIRST_FILE_NAME_FULL_PATH + "," + + ConfigMapsFromFilePathsSpringBootTest.SECOND_FILE_NAME_FULL_PATH }) public class ConfigMapsFromFilePathsSpringBootTest { protected static final String FILES_ROOT_PATH = "/tmp/scktests"; + protected static final String FIRST_FILE_NAME = "application.properties"; + protected static final String SECOND_FILE_NAME = "extra.properties"; + protected static final String UNUSED_FILE_NAME = "unused.properties"; - protected static final String FIRST_FILE_NAME_FULL_PATH = FILES_ROOT_PATH + "/" + FIRST_FILE_NAME; - protected static final String SECOND_FILE_NAME_FULL_PATH = FILES_ROOT_PATH + "/" + SECOND_FILE_NAME; - protected static final String UNUSED_FILE_NAME_FULL_PATH = FILES_ROOT_PATH + "/" + UNUSED_FILE_NAME; + + protected static final String FIRST_FILE_NAME_FULL_PATH = FILES_ROOT_PATH + "/" + + FIRST_FILE_NAME; + + protected static final String SECOND_FILE_NAME_FULL_PATH = FILES_ROOT_PATH + "/" + + SECOND_FILE_NAME; + + protected static final String UNUSED_FILE_NAME_FULL_PATH = FILES_ROOT_PATH + "/" + + UNUSED_FILE_NAME; @ClassRule public static KubernetesServer server = new KubernetesServer(); private static KubernetesClient mockClient; - @Autowired - private WebTestClient webClient; + @Autowired + private WebTestClient webClient; @BeforeClass public static void setUpBeforeClass() throws IOException { @@ -77,41 +86,41 @@ public static void setUpBeforeClass() throws IOException { System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); Files.createDirectories(Paths.get(FILES_ROOT_PATH)); - createFileWithContent(FIRST_FILE_NAME_FULL_PATH, "bean.greeting=Hello from path!"); + createFileWithContent(FIRST_FILE_NAME_FULL_PATH, + "bean.greeting=Hello from path!"); createFileWithContent(SECOND_FILE_NAME_FULL_PATH, "bean.farewell=Bye from path!"); - createFileWithContent(UNUSED_FILE_NAME_FULL_PATH, "bean.morning=Morning from path!"); + createFileWithContent(UNUSED_FILE_NAME_FULL_PATH, + "bean.morning=Morning from path!"); } @AfterClass public static void teardownAfterClass() { - newArrayList( - FIRST_FILE_NAME_FULL_PATH, - SECOND_FILE_NAME_FULL_PATH, - SECOND_FILE_NAME_FULL_PATH, - FILES_ROOT_PATH - ).forEach(fn -> { - try { - Files.delete(Paths.get(fn)); - } catch (IOException ignored) {} - }); + newArrayList(FIRST_FILE_NAME_FULL_PATH, SECOND_FILE_NAME_FULL_PATH, + SECOND_FILE_NAME_FULL_PATH, FILES_ROOT_PATH).forEach(fn -> { + try { + Files.delete(Paths.get(fn)); + } + catch (IOException ignored) { + } + }); } @Test public void greetingInputShouldReturnPropertyFromFirstFile() { - this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Hello from path!"); + this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() + .expectBody().jsonPath("content").isEqualTo("Hello from path!"); } @Test public void farewellInputShouldReturnPropertyFromSecondFile() { - this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Bye from path!"); + this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk() + .expectBody().jsonPath("content").isEqualTo("Bye from path!"); } @Test public void morningInputShouldReturnDefaultValue() { - this.webClient.get().uri("/api/morning").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Good morning, World!"); + this.webClient.get().uri("/api/morning").exchange().expectStatus().isOk() + .expectBody().jsonPath("content").isEqualTo("Good morning, World!"); } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsMixedSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsMixedSpringBootTest.java index 2d33f13fd5..b14af0e6a4 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsMixedSpringBootTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsMixedSpringBootTest.java @@ -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. @@ -12,44 +12,46 @@ * 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.kubernetes.config; -import static org.assertj.core.util.Lists.newArrayList; -import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashMap; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.kubernetes.config.example.App; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; +import static org.assertj.core.util.Lists.newArrayList; +import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile; + @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class , properties = { - "spring.application.name=" + ConfigMapsMixedSpringBootTest.APPLICATION_NAME, - "spring.cloud.kubernetes.config.enableApi=true", - "spring.cloud.kubernetes.config.paths=" - + ConfigMapsMixedSpringBootTest.FILE_NAME_FULL_PATH -}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = { + "spring.application.name=" + ConfigMapsMixedSpringBootTest.APPLICATION_NAME, + "spring.cloud.kubernetes.config.enableApi=true", + "spring.cloud.kubernetes.config.paths=" + + ConfigMapsMixedSpringBootTest.FILE_NAME_FULL_PATH }) public class ConfigMapsMixedSpringBootTest { protected static final String FILES_ROOT_PATH = "/tmp/scktests"; + protected static final String FILE_NAME = "application-path.yaml"; + protected static final String FILE_NAME_FULL_PATH = FILES_ROOT_PATH + "/" + FILE_NAME; protected static final String APPLICATION_NAME = "configmap-mixed-example"; @@ -59,8 +61,8 @@ public class ConfigMapsMixedSpringBootTest { private static KubernetesClient mockClient; - @Autowired - private WebTestClient webClient; + @Autowired + private WebTestClient webClient; @BeforeClass public static void setUpBeforeClass() throws IOException { @@ -76,44 +78,47 @@ public static void setUpBeforeClass() throws IOException { System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); Files.createDirectories(Paths.get(FILES_ROOT_PATH)); - ConfigMapTestUtil.createFileWithContent(FILE_NAME_FULL_PATH, readResourceFile("application-path.yaml")); + ConfigMapTestUtil.createFileWithContent(FILE_NAME_FULL_PATH, + readResourceFile("application-path.yaml")); HashMap data = new HashMap<>(); data.put("bean.morning", "Buenos Dias ConfigMap, %s"); server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME) - .andReturn(200, new ConfigMapBuilder().withNewMetadata() - .withName(APPLICATION_NAME).endMetadata().addToData(data).build()) - .always(); + .andReturn(200, new ConfigMapBuilder().withNewMetadata() + .withName(APPLICATION_NAME).endMetadata().addToData(data).build()) + .always(); } @AfterClass public static void teardownAfterClass() { - newArrayList( - FILE_NAME_FULL_PATH, - FILES_ROOT_PATH - ).forEach(fn -> { + newArrayList(FILE_NAME_FULL_PATH, FILES_ROOT_PATH).forEach(fn -> { try { Files.delete(Paths.get(fn)); - } catch (IOException ignored) {} + } + catch (IOException ignored) { + } }); } @Test public void greetingInputShouldReturnPropertyFromFile() { - this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Hello ConfigMap, World from path"); + this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() + .expectBody().jsonPath("content") + .isEqualTo("Hello ConfigMap, World from path"); } @Test public void farewellInputShouldReturnPropertyFromFile() { - this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Bye ConfigMap, World from path"); + this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk() + .expectBody().jsonPath("content") + .isEqualTo("Bye ConfigMap, World from path"); } @Test public void morningInputShouldReturnPropertyFromApi() { - this.webClient.get().uri("/api/morning").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Buenos Dias ConfigMap, World"); + this.webClient.get().uri("/api/morning").exchange().expectStatus().isOk() + .expectBody().jsonPath("content") + .isEqualTo("Buenos Dias ConfigMap, World"); } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java index d46c9b9ddc..eef9c24fc4 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java @@ -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. @@ -12,21 +12,22 @@ * 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.kubernetes.config; +import java.util.HashMap; + import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.util.HashMap; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; @@ -34,7 +35,7 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Charles Moulliard @@ -46,6 +47,8 @@ @AutoConfigureWebTestClient public class ConfigMapsSpringBootTest { + private static final String APPLICATION_NAME = "configmap-example"; + @ClassRule public static KubernetesServer server = new KubernetesServer(); @@ -54,8 +57,6 @@ public class ConfigMapsSpringBootTest { @Autowired(required = false) private Config config; - private static final String APPLICATION_NAME = "configmap-example"; - @Autowired private WebTestClient webClient; @@ -82,8 +83,9 @@ public static void setUpBeforeClass() { @Test public void testConfig() { - assertEquals(config.getMasterUrl(), mockClient.getConfiguration().getMasterUrl()); - assertEquals(config.getNamespace(), mockClient.getNamespace()); + assertThat(mockClient.getConfiguration().getMasterUrl()) + .isEqualTo(this.config.getMasterUrl()); + assertThat(mockClient.getNamespace()).isEqualTo(this.config.getNamespace()); } @Test @@ -91,13 +93,13 @@ public void testConfigMap() { ConfigMap configmap = mockClient.configMaps().inNamespace("test") .withName(APPLICATION_NAME).get(); HashMap keys = (HashMap) configmap.getData(); - assertEquals(keys.get("bean.greeting"), "Hello ConfigMap, %s!"); + assertThat("Hello ConfigMap, %s!").isEqualTo(keys.get("bean.greeting")); } @Test public void testGreetingEndpoint() { this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Hello ConfigMap, World!"); + .expectBody().jsonPath("content").isEqualTo("Hello ConfigMap, World!"); } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java index 634c37380e..c9ddfd4a7e 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java @@ -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. @@ -12,25 +12,23 @@ * 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.kubernetes.config; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile; +import java.util.Map; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.ConfigMapList; import io.fabric8.kubernetes.api.model.ConfigMapListBuilder; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.util.Map; import org.junit.Rule; import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile; + /** * @author Charles Moulliard */ @@ -41,40 +39,40 @@ public class ConfigMapsTest { @Test public void testConfigMapList() { - server.expect().withPath("/api/v1/namespaces/ns1/configmaps") + this.server.expect().withPath("/api/v1/namespaces/ns1/configmaps") .andReturn(200, new ConfigMapListBuilder().build()).once(); - KubernetesClient client = server.getClient(); + KubernetesClient client = this.server.getClient(); ConfigMapList configMapList = client.configMaps().inNamespace("ns1").list(); - assertNotNull(configMapList); - assertEquals(0, configMapList.getItems().size()); + assertThat(configMapList).isNotNull(); + assertThat(configMapList.getItems().size()).isEqualTo(0); } @Test public void testConfigMapGet() { - server.expect().withPath("/api/v1/namespaces/ns2/configmaps") + this.server.expect().withPath("/api/v1/namespaces/ns2/configmaps") .andReturn(200, new ConfigMapBuilder().withNewMetadata() .withName("reload-example").endMetadata() .addToData("KEY", "123").build()) .once(); - KubernetesClient client = server.getClient(); + KubernetesClient client = this.server.getClient(); ConfigMapList configMapList = client.configMaps().inNamespace("ns2").list(); - assertNotNull(configMapList); - assertEquals(1, configMapList.getAdditionalProperties().size()); + assertThat(configMapList).isNotNull(); + assertThat(configMapList.getAdditionalProperties().size()).isEqualTo(1); @SuppressWarnings("unchecked") Map data = (Map) configMapList .getAdditionalProperties().get("data"); - assertEquals("123", data.get("KEY")); + assertThat(data.get("KEY")).isEqualTo("123"); } @Test public void testConfigMapFromSingleApplicationProperties() { String configMapName = "app-properties-test"; String namespace = "app-props"; - server.expect() + this.server.expect() .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)) .andReturn(200, new ConfigMapBuilder().withNewMetadata() @@ -85,18 +83,18 @@ public void testConfigMapFromSingleApplicationProperties() { .once(); ConfigMapPropertySource cmps = new ConfigMapPropertySource( - server.getClient().inNamespace(namespace), configMapName); + this.server.getClient().inNamespace(namespace), configMapName); - assertEquals("a", cmps.getProperty("dummy.property.string1")); - assertEquals("1", cmps.getProperty("dummy.property.int1")); - assertEquals("true", cmps.getProperty("dummy.property.bool1")); + assertThat(cmps.getProperty("dummy.property.string1")).isEqualTo("a"); + assertThat(cmps.getProperty("dummy.property.int1")).isEqualTo("1"); + assertThat(cmps.getProperty("dummy.property.bool1")).isEqualTo("true"); } @Test public void testConfigMapFromSingleApplicationYaml() { String configMapName = "app-yaml-test"; String namespace = "app-props"; - server.expect() + this.server.expect() .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)) .andReturn(200, @@ -108,18 +106,18 @@ public void testConfigMapFromSingleApplicationYaml() { .once(); ConfigMapPropertySource cmps = new ConfigMapPropertySource( - server.getClient().inNamespace(namespace), configMapName); + this.server.getClient().inNamespace(namespace), configMapName); - assertEquals("a", cmps.getProperty("dummy.property.string2")); - assertEquals("1", cmps.getProperty("dummy.property.int2")); - assertEquals("true", cmps.getProperty("dummy.property.bool2")); + assertThat(cmps.getProperty("dummy.property.string2")).isEqualTo("a"); + assertThat(cmps.getProperty("dummy.property.int2")).isEqualTo("1"); + assertThat(cmps.getProperty("dummy.property.bool2")).isEqualTo("true"); } @Test public void testConfigMapFromSingleNonStandardFileName() { String configMapName = "single-non-standard-test"; String namespace = "app-props"; - server.expect() + this.server.expect() .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)) .andReturn(200, new ConfigMapBuilder().withNewMetadata() @@ -128,18 +126,18 @@ public void testConfigMapFromSingleNonStandardFileName() { .once(); ConfigMapPropertySource cmps = new ConfigMapPropertySource( - server.getClient().inNamespace(namespace), configMapName); + this.server.getClient().inNamespace(namespace), configMapName); - assertEquals("a", cmps.getProperty("dummy.property.string3")); - assertEquals("1", cmps.getProperty("dummy.property.int3")); - assertEquals("true", cmps.getProperty("dummy.property.bool3")); + assertThat(cmps.getProperty("dummy.property.string3")).isEqualTo("a"); + assertThat(cmps.getProperty("dummy.property.int3")).isEqualTo("1"); + assertThat(cmps.getProperty("dummy.property.bool3")).isEqualTo("true"); } @Test public void testConfigMapFromSingleInvalidPropertiesContent() { String configMapName = "single-unparseable-properties-test"; String namespace = "app-props"; - server.expect() + this.server.expect() .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)) .andReturn(200, @@ -148,7 +146,7 @@ public void testConfigMapFromSingleInvalidPropertiesContent() { .addToData("application.properties", "somevalue").build()) .once(); - new ConfigMapPropertySource(server.getClient().inNamespace(namespace), + new ConfigMapPropertySource(this.server.getClient().inNamespace(namespace), configMapName); // no exception is thrown for unparseable content @@ -158,7 +156,7 @@ public void testConfigMapFromSingleInvalidPropertiesContent() { public void testConfigMapFromSingleInvalidYamlContent() { String configMapName = "single-unparseable-yaml-test"; String namespace = "app-props"; - server.expect() + this.server.expect() .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)) .andReturn(200, @@ -167,7 +165,7 @@ public void testConfigMapFromSingleInvalidYamlContent() { .build()) .once(); - new ConfigMapPropertySource(server.getClient().inNamespace(namespace), + new ConfigMapPropertySource(this.server.getClient().inNamespace(namespace), configMapName); // no exception is thrown for unparseable content @@ -177,7 +175,7 @@ public void testConfigMapFromSingleInvalidYamlContent() { public void testConfigMapFromMultipleApplicationProperties() { String configMapName = "app-multiple-properties-test"; String namespace = "app-props"; - server.expect() + this.server.expect() .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)) .andReturn(200, @@ -191,17 +189,17 @@ public void testConfigMapFromMultipleApplicationProperties() { .once(); ConfigMapPropertySource cmps = new ConfigMapPropertySource( - server.getClient().inNamespace(namespace), configMapName); + this.server.getClient().inNamespace(namespace), configMapName); // application.properties should be read correctly - assertEquals("a", cmps.getProperty("dummy.property.string1")); - assertEquals("1", cmps.getProperty("dummy.property.int1")); - assertEquals("true", cmps.getProperty("dummy.property.bool1")); + assertThat(cmps.getProperty("dummy.property.string1")).isEqualTo("a"); + assertThat(cmps.getProperty("dummy.property.int1")).isEqualTo("1"); + assertThat(cmps.getProperty("dummy.property.bool1")).isEqualTo("true"); // the adhoc.properties file should not be parsed - assertNull(cmps.getProperty("dummy.property.bool2")); - assertNull(cmps.getProperty("dummy.property.bool2")); - assertNull(cmps.getProperty("dummy.property.bool2")); + assertThat(cmps.getProperty("dummy.property.bool2")).isNull(); + assertThat(cmps.getProperty("dummy.property.bool2")).isNull(); + assertThat(cmps.getProperty("dummy.property.bool2")).isNull(); } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesNoActiveProfileSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesNoActiveProfileSpringBootTest.java index dbae4f36ab..eaafe72e8d 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesNoActiveProfileSpringBootTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesNoActiveProfileSpringBootTest.java @@ -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. @@ -12,20 +12,21 @@ * 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.kubernetes.config; +import java.util.HashMap; + import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.util.HashMap; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; @@ -45,13 +46,13 @@ @AutoConfigureWebTestClient public class ConfigMapsWithProfilesNoActiveProfileSpringBootTest { + private static final String APPLICATION_NAME = "configmap-with-profile-no-active-profiles-example"; + @ClassRule public static KubernetesServer server = new KubernetesServer(); private static KubernetesClient mockClient; - private static final String APPLICATION_NAME = "configmap-with-profile-no-active-profiles-example"; - @Autowired private WebTestClient webClient; @@ -79,14 +80,15 @@ public static void setUpBeforeClass() { @Test public void testGreetingEndpoint() { this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Hello ConfigMap default, World!"); + .expectBody().jsonPath("content") + .isEqualTo("Hello ConfigMap default, World!"); } @Test public void testFarewellEndpoint() { this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk() - .expectBody().jsonPath("content") - .isEqualTo("Goodbye ConfigMap default, World!"); + .expectBody().jsonPath("content") + .isEqualTo("Goodbye ConfigMap default, World!"); } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesSpringBootTest.java index eef254a8f9..9ba19f0e7a 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesSpringBootTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithProfilesSpringBootTest.java @@ -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. @@ -12,20 +12,21 @@ * 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.kubernetes.config; +import java.util.HashMap; + import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.util.HashMap; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; @@ -47,6 +48,8 @@ @AutoConfigureWebTestClient public class ConfigMapsWithProfilesSpringBootTest { + private static final String APPLICATION_NAME = "configmap-with-profile-example"; + @ClassRule public static KubernetesServer server = new KubernetesServer(); @@ -55,8 +58,6 @@ public class ConfigMapsWithProfilesSpringBootTest { @Autowired(required = false) Config config; - private static final String APPLICATION_NAME = "configmap-with-profile-example"; - @Autowired private WebTestClient webClient; @@ -84,14 +85,15 @@ public static void setUpBeforeClass() { @Test public void testGreetingEndpoint() { this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() - .expectBody().jsonPath("content") - .isEqualTo("Hello ConfigMap dev, World!"); + .expectBody().jsonPath("content") + .isEqualTo("Hello ConfigMap dev, World!"); } @Test public void testFarewellEndpoint() { this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk() - .expectBody().jsonPath("content") - .isEqualTo("Goodbye ConfigMap default, World!"); + .expectBody().jsonPath("content") + .isEqualTo("Goodbye ConfigMap default, World!"); } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithoutProfilesSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithoutProfilesSpringBootTest.java index d4265174eb..420b6a3183 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithoutProfilesSpringBootTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsWithoutProfilesSpringBootTest.java @@ -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. @@ -12,20 +12,21 @@ * 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.kubernetes.config; +import java.util.HashMap; + import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.util.HashMap; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; @@ -37,22 +38,20 @@ import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - classes = App.class, - properties = { "spring.application.name=configmap-without-profile-example", - "spring.cloud.kubernetes.reload.enabled=false"} -) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = { + "spring.application.name=configmap-without-profile-example", + "spring.cloud.kubernetes.reload.enabled=false" }) @ActiveProfiles("development") @AutoConfigureWebTestClient public class ConfigMapsWithoutProfilesSpringBootTest { + private static final String APPLICATION_NAME = "configmap-without-profile-example"; + @ClassRule public static KubernetesServer server = new KubernetesServer(); private static KubernetesClient mockClient; - private static final String APPLICATION_NAME = "configmap-without-profile-example"; - @Autowired private WebTestClient webClient; @@ -60,32 +59,34 @@ public class ConfigMapsWithoutProfilesSpringBootTest { public static void setUpBeforeClass() { mockClient = server.getClient(); - //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()); + // Configure the kubernetes master url to point to the mock server + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + mockClient.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); - HashMap data = new HashMap<>(); - data.put("application.yml", readResourceFile("application-without-profiles.yaml")); - server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME).andReturn(200, new ConfigMapBuilder() - .withNewMetadata().withName(APPLICATION_NAME).endMetadata() - .addToData(data) - .build()) - .always(); + HashMap data = new HashMap<>(); + data.put("application.yml", + readResourceFile("application-without-profiles.yaml")); + server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME) + .andReturn(200, new ConfigMapBuilder().withNewMetadata() + .withName(APPLICATION_NAME).endMetadata().addToData(data).build()) + .always(); } @Test public void testGreetingEndpoint() { this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk() - .expectBody().jsonPath("content").isEqualTo("Hello ConfigMap, World!"); + .expectBody().jsonPath("content").isEqualTo("Hello ConfigMap, World!"); } @Test public void testFarewellEndpoint() { this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk() - .expectBody().jsonPath("content") - .isEqualTo("Goodbye ConfigMap, World!"); + .expectBody().jsonPath("content").isEqualTo("Goodbye ConfigMap, World!"); } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/HealthIndicatorTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/HealthIndicatorTest.java index b4e2fb6b65..0cc0b746aa 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/HealthIndicatorTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/HealthIndicatorTest.java @@ -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.kubernetes.config; import io.fabric8.kubernetes.client.Config; @@ -19,10 +35,8 @@ import static org.hamcrest.Matchers.containsString; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, - properties = { - "management.endpoint.health.show-details=always" - }) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = { + "management.endpoint.health.show-details=always" }) public class HealthIndicatorTest { @ClassRule @@ -40,23 +54,21 @@ public class HealthIndicatorTest { public static void setUpBeforeClass() { mockClient = server.getClient(); - //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()); + // Configure the kubernetes master url to point to the mock server + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + mockClient.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @Test public void healthEndpointShouldContainKubernetes() { - webClient.get() - .uri("http://localhost:{port}/actuator/health", port) - .accept(MediaType.APPLICATION_JSON) - .exchange() - .expectStatus().isOk() - .expectBody(String.class).value(containsString("kubernetes")); + this.webClient.get().uri("http://localhost:{port}/actuator/health", this.port) + .accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk() + .expectBody(String.class).value(containsString("kubernetes")); } - } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/KubernetesConfigConfigurationTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/KubernetesConfigConfigurationTest.java index c5e8131f8e..239b90968b 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/KubernetesConfigConfigurationTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/KubernetesConfigConfigurationTest.java @@ -1,16 +1,32 @@ +/* + * 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.kubernetes.config; import io.fabric8.kubernetes.client.KubernetesClient; import org.junit.After; import org.junit.Test; + import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; /** @@ -27,38 +43,36 @@ public void close() { } } - @Test public void kubernetesWhenKubernetesDisabled() throws Exception { setup("spring.cloud.kubernetes.enabled=false"); - assertFalse(context.containsBean("configMapPropertySourceLocator")); - assertFalse(context.containsBean("secretsPropertySourceLocator")); + assertThat(this.context.containsBean("configMapPropertySourceLocator")).isFalse(); + assertThat(this.context.containsBean("secretsPropertySourceLocator")).isFalse(); } @Test public void kubernetesWhenKubernetesConfigDisabled() throws Exception { setup("spring.cloud.kubernetes.config.enabled=false", - "spring.cloud.kubernetes.secrets.enabled=false"); - assertFalse(context.containsBean("configMapPropertySourceLocator")); - assertFalse(context.containsBean("secretsPropertySourceLocator")); + "spring.cloud.kubernetes.secrets.enabled=false"); + assertThat(this.context.containsBean("configMapPropertySourceLocator")).isFalse(); + assertThat(this.context.containsBean("secretsPropertySourceLocator")).isFalse(); } @Test public void kubernetesDefaultEnabled() throws Exception { setup("spring.cloud.kubernetes.enabled=true"); - assertTrue(context.containsBean("configMapPropertySourceLocator")); - assertTrue(context.containsBean("secretsPropertySourceLocator")); + assertThat(this.context.containsBean("configMapPropertySourceLocator")).isTrue(); + assertThat(this.context.containsBean("secretsPropertySourceLocator")).isTrue(); } private void setup(String... env) { this.context = new SpringApplicationBuilder( - PropertyPlaceholderAutoConfiguration.class, - KubernetesClientTestConfiguration.class, - BootstrapConfiguration.class).web(org.springframework.boot.WebApplicationType.NONE) - .properties(env).run(); + PropertyPlaceholderAutoConfiguration.class, + KubernetesClientTestConfiguration.class, BootstrapConfiguration.class) + .web(org.springframework.boot.WebApplicationType.NONE) + .properties(env).run(); } - @Configuration static class KubernetesClientTestConfiguration { @@ -67,6 +81,6 @@ KubernetesClient kubernetesClient() { return mock(KubernetesClient.class); } - } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MissingActuatorTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MissingActuatorTest.java index 814151e812..dd4e7aed2a 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MissingActuatorTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MissingActuatorTest.java @@ -1,10 +1,25 @@ -package org.springframework.cloud.kubernetes.config; +/* + * 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.assertj.core.api.Assertions.assertThat; +package org.springframework.cloud.kubernetes.config; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -14,30 +29,35 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; +import static org.assertj.core.api.Assertions.assertThat; + // inspired by spring-cloud-commons: RefreshAutoConfigurationMoreClassPathTests @RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({"spring-boot-actuator-autoconfigure-*.jar", "spring-boot-starter-actuator-*.jar"}) +@ClassPathExclusions({ "spring-boot-actuator-autoconfigure-*.jar", + "spring-boot-starter-actuator-*.jar" }) public class MissingActuatorTest { @Rule public OutputCapture outputCapture = new OutputCapture(); + private static ConfigurableApplicationContext getApplicationContext( + Class configuration, String... properties) { + return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE) + .properties(properties).run(); + } + @Test public void unknownClassProtected() { - try (ConfigurableApplicationContext context = getApplicationContext( - Config.class, "debug=true")) { + try (ConfigurableApplicationContext context = getApplicationContext(Config.class, + "debug=true")) { String output = this.outputCapture.toString(); - assertThat(output).doesNotContain("Failed to introspect annotations on [class org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration") - .doesNotContain("TypeNotPresentExceptionProxy"); + assertThat(output).doesNotContain("Failed to introspect annotations on" + + " [class org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration") + .doesNotContain("TypeNotPresentExceptionProxy"); } } - private static ConfigurableApplicationContext getApplicationContext( - Class configuration, String... properties) { - return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE).properties(properties).run(); - } - @Configuration @EnableAutoConfiguration static class Config { diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MultipleConfigMapsSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MultipleConfigMapsSpringBootTest.java index dba81c72b8..2d78ee9c54 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MultipleConfigMapsSpringBootTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/MultipleConfigMapsSpringBootTest.java @@ -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. @@ -12,21 +12,22 @@ * 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.kubernetes.config; +import java.util.HashMap; +import java.util.Map; + import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import java.util.HashMap; -import java.util.Map; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; @@ -38,8 +39,8 @@ * @author Charles Moulliard */ @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ExampleApp.class, - properties = {"spring.cloud.bootstrap.name=multiplecms"}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ExampleApp.class, properties = { + "spring.cloud.bootstrap.name=multiplecms" }) @AutoConfigureWebTestClient public class MultipleConfigMapsSpringBootTest { @@ -55,59 +56,51 @@ public class MultipleConfigMapsSpringBootTest { public static void setUpBeforeClass() { mockClient = server.getClient(); - //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()); + // Configure the kubernetes master url to point to the mock server + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + mockClient.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); - createConfigmap( - server, - "s1", - "defnamespace", - new HashMap() {{ - put("bean.common-message","c1"); + createConfigmap(server, "s1", "defnamespace", new HashMap() { + { + put("bean.common-message", "c1"); put("bean.message1", "m1"); - }}); - - createConfigmap( - server, - "defname", - "s2", - new HashMap() {{ - put("bean.common-message","c2"); + } + }); + + createConfigmap(server, "defname", "s2", new HashMap() { + { + put("bean.common-message", "c2"); put("bean.message2", "m2"); - }}); - - createConfigmap( - server, - "othername", - "othernamespace", - new HashMap() {{ - put("bean.common-message","c3"); - put("bean.message3", "m3"); - }}); + } + }); + + createConfigmap(server, "othername", "othernamespace", + new HashMap() { + { + put("bean.common-message", "c3"); + put("bean.message3", "m3"); + } + }); } private static void createConfigmap(KubernetesServer server, String configMapName, - String namespace, Map data) { - - server - .expect() - .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)) - .andReturn( - 200, - new ConfigMapBuilder() - .withNewMetadata().withName(configMapName).endMetadata() - .addToData(data) - .build() - ) - .always(); + String namespace, Map data) { + + server.expect() + .withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, + configMapName)) + .andReturn(200, new ConfigMapBuilder().withNewMetadata() + .withName(configMapName).endMetadata().addToData(data).build()) + .always(); } - //the last confimap defined in 'multiplecms.yml' has the highest priority, so - //the common property defined in all configmaps is taken from the last one defined + // the last confimap defined in 'multiplecms.yml' has the highest priority, so + // the common property defined in all configmaps is taken from the last one defined @Test public void testCommonMessage() { assertResponse("/common", "c3"); @@ -129,9 +122,8 @@ public void testMessage3() { } private void assertResponse(String path, String expectedMessage) { - this.webClient.get().uri(path).exchange().expectStatus().isOk() - .expectBody().jsonPath("message") - .isEqualTo(expectedMessage); + this.webClient.get().uri(path).exchange().expectStatus().isOk().expectBody() + .jsonPath("message").isEqualTo(expectedMessage); } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceTest.java index 99c064b725..1f56436fea 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/SecretsPropertySourceTest.java @@ -1,5 +1,23 @@ +/* + * 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.kubernetes.config; +import java.util.Base64; + import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.api.model.SecretBuilder; import io.fabric8.kubernetes.client.Config; @@ -9,6 +27,7 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.kubernetes.config.example.App; @@ -16,43 +35,53 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; -import java.util.Base64; - import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; -@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class) @TestPropertySource("classpath:/application-secrets.properties") public class SecretsPropertySourceTest { +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class) +@TestPropertySource("classpath:/application-secrets.properties") +public class SecretsPropertySourceTest { private static final String NAMESPACE = "test"; + private static final String SECRET_VALUE = "secretValue"; - @ClassRule public static KubernetesServer server = new KubernetesServer(false, true); + @ClassRule + public static KubernetesServer server = new KubernetesServer(false, true); - @Autowired private SecretsPropertySourceLocator propertySourceLocator; - @Autowired private Environment environment; + @Autowired + private SecretsPropertySourceLocator propertySourceLocator; - @BeforeClass public static void setUpBeforeClass() { + @Autowired + private Environment environment; + + @BeforeClass + public static void setUpBeforeClass() { KubernetesClient mockClient = server.getClient(); // Configure the kubernetes master url to point to the mock server System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, - mockClient.getConfiguration().getMasterUrl()); + mockClient.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, - "false"); + "false"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, NAMESPACE); Secret secret = new SecretBuilder().withNewMetadata() - .withLabels(singletonMap("foo", "bar")).endMetadata() - .addToData("secretName", Base64.getEncoder().encodeToString(SECRET_VALUE.getBytes())) - .build(); + .withLabels(singletonMap("foo", "bar")).endMetadata() + .addToData("secretName", + Base64.getEncoder().encodeToString(SECRET_VALUE.getBytes())) + .build(); mockClient.secrets().inNamespace(NAMESPACE).create(secret); } - @Test public void toStringShouldNotExposeSecretValues() { - String actual = propertySourceLocator.locate(environment).toString(); + @Test + public void toStringShouldNotExposeSecretValues() { + String actual = this.propertySourceLocator.locate(this.environment).toString(); assertThat(actual).doesNotContain(SECRET_VALUE); } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/App.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/App.java index 287fbad847..fdb7d9a15f 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/App.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/App.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config.example; @@ -25,7 +24,9 @@ */ @SpringBootApplication public class App { + public static void main(String[] args) { SpringApplication.run(App.class, args); } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingController.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingController.java index 35d07f83c2..95eb88be9e 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingController.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingController.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config.example; @@ -36,17 +35,21 @@ public GreetingController(GreetingProperties properties) { } @RequestMapping("/api/greeting") - public ResponseMessage greeting(@RequestParam(value="name", defaultValue="World") String name) { - return new ResponseMessage(String.format(properties.getGreeting(), name)); + public ResponseMessage greeting( + @RequestParam(value = "name", defaultValue = "World") String name) { + return new ResponseMessage(String.format(this.properties.getGreeting(), name)); } @RequestMapping("/api/farewell") - public ResponseMessage farewell(@RequestParam(value="name", defaultValue="World") String name) { - return new ResponseMessage(String.format(properties.getFarewell(), name)); + public ResponseMessage farewell( + @RequestParam(value = "name", defaultValue = "World") String name) { + return new ResponseMessage(String.format(this.properties.getFarewell(), name)); } @RequestMapping("/api/morning") - public ResponseMessage morning(@RequestParam(value="name", defaultValue="World") String name) { - return new ResponseMessage(String.format(properties.getMorning(), name)); + public ResponseMessage morning( + @RequestParam(value = "name", defaultValue = "World") String name) { + return new ResponseMessage(String.format(this.properties.getMorning(), name)); } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingProperties.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingProperties.java index f8716df8a1..737700a3bb 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingProperties.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/GreetingProperties.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config.example; @@ -25,11 +24,13 @@ public class GreetingProperties { private String greeting = "Hello, %s!"; + private String farewell = "Goodbye, %s!"; + private String morning = "Good morning, %s!"; public String getGreeting() { - return greeting; + return this.greeting; } public void setGreeting(String greeting) { @@ -37,7 +38,7 @@ public void setGreeting(String greeting) { } public String getFarewell() { - return farewell; + return this.farewell; } public void setFarewell(String farewell) { @@ -45,10 +46,11 @@ public void setFarewell(String farewell) { } public String getMorning() { - return morning; + return this.morning; } public void setMorning(String morning) { this.morning = morning; } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/ResponseMessage.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/ResponseMessage.java index 31ce305fff..e404565997 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/ResponseMessage.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example/ResponseMessage.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config.example; @@ -33,6 +32,7 @@ public ResponseMessage(String content) { } public String getContent() { - return content; + return this.content; } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleApp.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleApp.java index c61fd757e8..1a595cd2ac 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleApp.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleApp.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config.example2; @@ -28,7 +27,8 @@ public class ExampleApp { public static void main(String[] args) { - SpringApplication.run(org.springframework.cloud.kubernetes.config.example.App.class, args); + SpringApplication + .run(org.springframework.cloud.kubernetes.config.example.App.class, args); } @RestController @@ -42,27 +42,28 @@ public Controller(ExampleAppProps exampleAppProps) { @GetMapping("/common") public Response commonMessage() { - return new Response(exampleAppProps.getCommonMessage()); + return new Response(this.exampleAppProps.getCommonMessage()); } @GetMapping("/m1") public Response message1() { - return new Response(exampleAppProps.getMessage1()); + return new Response(this.exampleAppProps.getMessage1()); } @GetMapping("/m2") public Response message2() { - return new Response(exampleAppProps.getMessage2()); + return new Response(this.exampleAppProps.getMessage2()); } @GetMapping("/m3") public Response message3() { - return new Response(exampleAppProps.getMessage3()); + return new Response(this.exampleAppProps.getMessage3()); } + } - + public static class Response { - + private final String message; public Response(String message) { @@ -70,8 +71,9 @@ public Response(String message) { } public String getMessage() { - return message; + return this.message; } + } } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleAppProps.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleAppProps.java index 482d719f2d..4c4fa9f27f 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleAppProps.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/example2/ExampleAppProps.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.config.example2; @@ -23,12 +22,15 @@ public class ExampleAppProps { private String commonMessage; + private String message1; + private String message2; + private String message3; public String getCommonMessage() { - return commonMessage; + return this.commonMessage; } public void setCommonMessage(String commonMessage) { @@ -36,7 +38,7 @@ public void setCommonMessage(String commonMessage) { } public String getMessage1() { - return message1; + return this.message1; } public void setMessage1(String message1) { @@ -44,7 +46,7 @@ public void setMessage1(String message1) { } public String getMessage2() { - return message2; + return this.message2; } public void setMessage2(String message2) { @@ -52,10 +54,11 @@ public void setMessage2(String message2) { } public String getMessage3() { - return message3; + return this.message3; } public void setMessage3(String message3) { this.message3 = message3; } + } diff --git a/spring-cloud-kubernetes-config/src/test/resources/application.properties b/spring-cloud-kubernetes-config/src/test/resources/application.properties index 09cecf84f4..473327168b 100644 --- a/spring-cloud-kubernetes-config/src/test/resources/application.properties +++ b/spring-cloud-kubernetes-config/src/test/resources/application.properties @@ -1,3 +1,3 @@ dummy.property.string1=a dummy.property.int1=1 -dummy.property.bool1=true \ No newline at end of file +dummy.property.bool1=true diff --git a/spring-cloud-kubernetes-config/src/test/resources/application.yaml b/spring-cloud-kubernetes-config/src/test/resources/application.yaml index 5a7a342c20..37fcceb68e 100644 --- a/spring-cloud-kubernetes-config/src/test/resources/application.yaml +++ b/spring-cloud-kubernetes-config/src/test/resources/application.yaml @@ -2,4 +2,4 @@ dummy: property: string2: "a" int2: 1 - bool2: true \ No newline at end of file + bool2: true diff --git a/spring-cloud-kubernetes-config/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-config/src/test/resources/logback-test.xml index 75d20a0a6f..5d1ac6d06a 100644 --- a/spring-cloud-kubernetes-config/src/test/resources/logback-test.xml +++ b/spring-cloud-kubernetes-config/src/test/resources/logback-test.xml @@ -1,6 +1,7 @@ - - - + + + diff --git a/spring-cloud-kubernetes-config/src/test/resources/multiplecms.yml b/spring-cloud-kubernetes-config/src/test/resources/multiplecms.yml index bf938dd641..1978a64761 100644 --- a/spring-cloud-kubernetes-config/src/test/resources/multiplecms.yml +++ b/spring-cloud-kubernetes-config/src/test/resources/multiplecms.yml @@ -10,7 +10,7 @@ spring: name: defname namespace: defnamespace sources: - - name: s1 - - namespace: s2 - - name: othername - namespace: othernamespace + - name: s1 + - namespace: s2 + - name: othername + namespace: othernamespace diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml index f1363d221f..c0b8b36dc9 100644 --- a/spring-cloud-kubernetes-core/pom.xml +++ b/spring-cloud-kubernetes-core/pom.xml @@ -16,8 +16,8 @@ ~ --> - org.springframework.cloud diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java index 807c0336e3..01877b9b6c 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java @@ -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. @@ -12,20 +12,19 @@ * 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.kubernetes; +import java.time.Duration; + import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ConfigBuilder; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; - -import java.time.Duration; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -34,6 +33,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +/** + * Auto configuration for Kubernetes. + * + * @author Ioannis Canellos + */ @Configuration @ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true) @EnableConfigurationProperties(KubernetesClientProperties.class) @@ -41,6 +45,33 @@ public class KubernetesAutoConfiguration { private static final Log LOG = LogFactory.getLog(KubernetesAutoConfiguration.class); + private static D or(D dis, D dat) { + if (dis != null) { + return dis; + } + else { + return dat; + } + } + + private static Integer orDurationInt(Duration dis, Integer dat) { + if (dis != null) { + return (int) dis.toMillis(); + } + else { + return dat; + } + } + + private static Long orDurationLong(Duration dis, Long dat) { + if (dis != null) { + return dis.toMillis(); + } + else { + return dat; + } + } + @Bean @ConditionalOnMissingBean(Config.class) public Config kubernetesClientConfig( @@ -83,27 +114,29 @@ public Config kubernetesClientConfig( .withConnectionTimeout( orDurationInt(kubernetesClientProperties.getConnectionTimeout(), base.getConnectionTimeout())) - .withRequestTimeout(orDurationInt(kubernetesClientProperties.getRequestTimeout(), - base.getRequestTimeout())) - .withRollingTimeout(orDurationLong(kubernetesClientProperties.getRollingTimeout(), - base.getRollingTimeout())) + .withRequestTimeout( + orDurationInt(kubernetesClientProperties.getRequestTimeout(), + base.getRequestTimeout())) + .withRollingTimeout( + orDurationLong(kubernetesClientProperties.getRollingTimeout(), + base.getRollingTimeout())) .withTrustCerts(or(kubernetesClientProperties.isTrustCerts(), base.isTrustCerts())) .withHttpProxy(or(kubernetesClientProperties.getHttpProxy(), - base.getHttpProxy())) + base.getHttpProxy())) .withHttpsProxy(or(kubernetesClientProperties.getHttpsProxy(), - base.getHttpsProxy())) + base.getHttpsProxy())) .withProxyUsername(or(kubernetesClientProperties.getProxyUsername(), - base.getProxyUsername())) + base.getProxyUsername())) .withPassword(or(kubernetesClientProperties.getProxyPassword(), - base.getProxyPassword())) - .withNoProxy(or(kubernetesClientProperties.getNoProxy(), - base.getNoProxy())) + base.getProxyPassword())) + .withNoProxy( + or(kubernetesClientProperties.getNoProxy(), base.getNoProxy())) .build(); if (properties.getNamespace() == null || properties.getNamespace().isEmpty()) { - LOG.warn( - "No namespace has been detected. Please specify KUBERNETES_NAMESPACE env var, or use a later kubernetes version (1.3 or later)"); + LOG.warn("No namespace has been detected. Please specify " + + "KUBERNETES_NAMESPACE env var, or use a later kubernetes version (1.3 or later)"); } return properties; } @@ -123,41 +156,17 @@ public StandardPodUtils kubernetesPodUtils(KubernetesClient client) { @Configuration @ConditionalOnClass(HealthIndicator.class) protected static class KubernetesActuatorConfiguration { + @Bean public KubernetesHealthIndicator kubernetesHealthIndicator(PodUtils podUtils) { return new KubernetesHealthIndicator(podUtils); } - + @Bean public KubernetesInfoContributor kubernetesInfoContributor(PodUtils podUtils) { return new KubernetesInfoContributor(podUtils); } - } - private static D or(D dis, D dat) { - if (dis != null) { - return dis; - } - else { - return dat; - } - } - - private static Integer orDurationInt(Duration dis, Integer dat) { - if (dis != null) { - return (int)dis.toMillis(); - } - else { - return dat; - } - } - - private static Long orDurationLong(Duration dis, Long dat) { - if (dis != null) { - return dis.toMillis(); - } - else { - return dat; - } } + } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesClientProperties.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesClientProperties.java index 2d828778aa..94d68b23eb 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesClientProperties.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesClientProperties.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes; @@ -21,37 +20,66 @@ import org.springframework.boot.context.properties.ConfigurationProperties; +/** + * Kubernetes client properties. + * + * @author Ioannis Canellos + */ @ConfigurationProperties("spring.cloud.kubernetes.client") public class KubernetesClientProperties { private Boolean trustCerts; + private String masterUrl; + private String apiVersion; + private String namespace; + private String caCertFile; + private String caCertData; + private String clientCertFile; + private String clientCertData; + private String clientKeyFile; + private String clientKeyData; + private String clientKeyAlgo; + private String clientKeyPassphrase; + private String username; + private String password; + private Duration watchReconnectInterval; + private Duration watchReconnectLimit; + private Duration connectionTimeout; + private Duration requestTimeout; + private Duration rollingTimeout; + private Duration loggingInterval; + private String httpProxy; + private String httpsProxy; + private String proxyUsername; + private String proxyPassword; + private String[] noProxy; public String getClientCertData() { - return clientCertData; + return this.clientCertData; } public void setClientCertData(String clientCertData) { @@ -59,15 +87,11 @@ public void setClientCertData(String clientCertData) { } public Boolean isTrustCerts() { - return trustCerts; - } - - public void setTrustCerts(Boolean trustCerts) { - this.trustCerts = trustCerts; + return this.trustCerts; } public String getMasterUrl() { - return masterUrl; + return this.masterUrl; } public void setMasterUrl(String masterUrl) { @@ -75,7 +99,7 @@ public void setMasterUrl(String masterUrl) { } public String getApiVersion() { - return apiVersion; + return this.apiVersion; } public void setApiVersion(String apiVersion) { @@ -83,7 +107,7 @@ public void setApiVersion(String apiVersion) { } public String getNamespace() { - return namespace; + return this.namespace; } public void setNamespace(String namespace) { @@ -91,7 +115,7 @@ public void setNamespace(String namespace) { } public String getCaCertFile() { - return caCertFile; + return this.caCertFile; } public void setCaCertFile(String caCertFile) { @@ -99,7 +123,7 @@ public void setCaCertFile(String caCertFile) { } public String getCaCertData() { - return caCertData; + return this.caCertData; } public void setCaCertData(String caCertData) { @@ -107,7 +131,7 @@ public void setCaCertData(String caCertData) { } public String getClientCertFile() { - return clientCertFile; + return this.clientCertFile; } public void setClientCertFile(String clientCertFile) { @@ -115,7 +139,7 @@ public void setClientCertFile(String clientCertFile) { } public String getClientKeyFile() { - return clientKeyFile; + return this.clientKeyFile; } public void setClientKeyFile(String clientKeyFile) { @@ -123,7 +147,7 @@ public void setClientKeyFile(String clientKeyFile) { } public String getClientKeyData() { - return clientKeyData; + return this.clientKeyData; } public void setClientKeyData(String clientKeyData) { @@ -131,7 +155,7 @@ public void setClientKeyData(String clientKeyData) { } public String getClientKeyAlgo() { - return clientKeyAlgo; + return this.clientKeyAlgo; } public void setClientKeyAlgo(String clientKeyAlgo) { @@ -139,7 +163,7 @@ public void setClientKeyAlgo(String clientKeyAlgo) { } public String getClientKeyPassphrase() { - return clientKeyPassphrase; + return this.clientKeyPassphrase; } public void setClientKeyPassphrase(String clientKeyPassphrase) { @@ -147,7 +171,7 @@ public void setClientKeyPassphrase(String clientKeyPassphrase) { } public String getUsername() { - return username; + return this.username; } public void setUsername(String username) { @@ -155,7 +179,7 @@ public void setUsername(String username) { } public String getPassword() { - return password; + return this.password; } public void setPassword(String password) { @@ -163,7 +187,7 @@ public void setPassword(String password) { } public Duration getWatchReconnectInterval() { - return watchReconnectInterval; + return this.watchReconnectInterval; } public void setWatchReconnectInterval(Duration watchReconnectInterval) { @@ -171,7 +195,7 @@ public void setWatchReconnectInterval(Duration watchReconnectInterval) { } public Duration getWatchReconnectLimit() { - return watchReconnectLimit; + return this.watchReconnectLimit; } public void setWatchReconnectLimit(Duration watchReconnectLimit) { @@ -179,7 +203,7 @@ public void setWatchReconnectLimit(Duration watchReconnectLimit) { } public Duration getConnectionTimeout() { - return connectionTimeout; + return this.connectionTimeout; } public void setConnectionTimeout(Duration connectionTimeout) { @@ -187,7 +211,7 @@ public void setConnectionTimeout(Duration connectionTimeout) { } public Duration getRequestTimeout() { - return requestTimeout; + return this.requestTimeout; } public void setRequestTimeout(Duration requestTimeout) { @@ -195,7 +219,7 @@ public void setRequestTimeout(Duration requestTimeout) { } public Duration getRollingTimeout() { - return rollingTimeout; + return this.rollingTimeout; } public void setRollingTimeout(Duration rollingTimeout) { @@ -203,7 +227,7 @@ public void setRollingTimeout(Duration rollingTimeout) { } public Duration getLoggingInterval() { - return loggingInterval; + return this.loggingInterval; } public void setLoggingInterval(Duration loggingInterval) { @@ -211,11 +235,15 @@ public void setLoggingInterval(Duration loggingInterval) { } public Boolean getTrustCerts() { - return trustCerts; + return this.trustCerts; + } + + public void setTrustCerts(Boolean trustCerts) { + this.trustCerts = trustCerts; } public String getHttpProxy() { - return httpProxy; + return this.httpProxy; } public void setHttpProxy(String httpProxy) { @@ -223,7 +251,7 @@ public void setHttpProxy(String httpProxy) { } public String getHttpsProxy() { - return httpsProxy; + return this.httpsProxy; } public void setHttpsProxy(String httpsProxy) { @@ -231,7 +259,7 @@ public void setHttpsProxy(String httpsProxy) { } public String getProxyUsername() { - return proxyUsername; + return this.proxyUsername; } public void setProxyUsername(String proxyUsername) { @@ -239,7 +267,7 @@ public void setProxyUsername(String proxyUsername) { } public String getProxyPassword() { - return proxyPassword; + return this.proxyPassword; } public void setProxyPassword(String proxyPassword) { @@ -247,10 +275,11 @@ public void setProxyPassword(String proxyPassword) { } public String[] getNoProxy() { - return noProxy; + return this.noProxy; } public void setNoProxy(String[] noProxy) { this.noProxy = noProxy; } + } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java index 513e7f2467..57552ce70d 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesHealthIndicator.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes; @@ -22,6 +21,11 @@ import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; +/** + * Kubernetes implementation of {@link AbstractHealthIndicator}. + * + * @author Ioannis Canellos + */ public class KubernetesHealthIndicator extends AbstractHealthIndicator { private PodUtils utils; @@ -33,7 +37,7 @@ public KubernetesHealthIndicator(PodUtils utils) { @Override protected void doHealthCheck(Health.Builder builder) throws Exception { try { - Pod current = utils.currentPod().get(); + Pod current = this.utils.currentPod().get(); if (current != null) { builder.up().withDetail("inside", true) .withDetail("namespace", current.getMetadata().getNamespace()) @@ -52,4 +56,5 @@ protected void doHealthCheck(Health.Builder builder) throws Exception { builder.down(e); } } + } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java index a8d8025166..c9ebf80f9f 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesInfoContributor.java @@ -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. @@ -12,25 +12,29 @@ * 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.kubernetes; -import io.fabric8.kubernetes.api.model.Pod; - import java.util.HashMap; import java.util.Map; +import io.fabric8.kubernetes.api.model.Pod; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.actuate.info.Info.Builder; import org.springframework.boot.actuate.info.InfoContributor; +/** + * Kubernetes implementation of {@link InfoContributor}. + * + * @author Mark Anderson + */ public class KubernetesInfoContributor implements InfoContributor { private static final Log LOG = LogFactory.getLog(KubernetesInfoContributor.class); - + private PodUtils utils; public KubernetesInfoContributor(PodUtils utils) { @@ -40,7 +44,7 @@ public KubernetesInfoContributor(PodUtils utils) { @Override public void contribute(Builder builder) { try { - Pod current = utils.currentPod().get(); + Pod current = this.utils.currentPod().get(); Map details = new HashMap<>(); if (current != null) { details.put("inside", true); @@ -60,4 +64,5 @@ public void contribute(Builder builder) { LOG.warn("Failed to get pod details", e); } } + } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/LazilyInstantiate.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/LazilyInstantiate.java index 74129c1980..7bf61cb000 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/LazilyInstantiate.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/LazilyInstantiate.java @@ -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. @@ -12,34 +12,41 @@ * 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.kubernetes; import java.util.function.Supplier; -public class LazilyInstantiate implements Supplier { +/** + * Lazy instantiation utility class. + * + * @param return type + * @author Ioannis Canellos + */ +public final class LazilyInstantiate implements Supplier { - public static LazilyInstantiate using(Supplier supplier) { - return new LazilyInstantiate(supplier); - } + private final Supplier supplier; - public synchronized T get() { - return current.get(); - } + private Supplier current; private LazilyInstantiate(Supplier supplier) { this.supplier = supplier; this.current = () -> swapper(); } - private final Supplier supplier; - private Supplier current; + public static LazilyInstantiate using(Supplier supplier) { + return new LazilyInstantiate(supplier); + } + + public synchronized T get() { + return this.current.get(); + } private T swapper() { - T obj = supplier.get(); - current = () -> obj; + T obj = this.supplier.get(); + this.current = () -> obj; return obj; } + } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/PodUtils.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/PodUtils.java index 86b792c2d0..470c0d69b5 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/PodUtils.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/PodUtils.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes; @@ -21,6 +20,11 @@ import io.fabric8.kubernetes.api.model.Pod; +/** + * Utility interface to retrieve {@link Pod} related information. + * + * @author Ioannis Canellos + */ public interface PodUtils { /** @@ -33,4 +37,5 @@ public interface PodUtils { * @return true if called from within Kubernetes, false otherwise. */ Boolean isInsideKubernetes(); + } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/StandardPodUtils.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/StandardPodUtils.java index e3fcbab264..28a48471ce 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/StandardPodUtils.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/StandardPodUtils.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes; @@ -26,13 +25,24 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +/** + * Utility class to work with pods. + * + * @author Ioannis Canellos + */ public class StandardPodUtils implements PodUtils { - private static final Log LOG = LogFactory.getLog(StandardPodUtils.class); + /** + * Hostname environment variable name. + */ public static final String HOSTNAME = "HOSTNAME"; + private static final Log LOG = LogFactory.getLog(StandardPodUtils.class); + private final KubernetesClient client; + private final String hostName; + private Supplier current; public StandardPodUtils(KubernetesClient client) { @@ -48,7 +58,7 @@ public StandardPodUtils(KubernetesClient client) { @Override public Supplier currentPod() { - return current; + return this.current; } @Override @@ -59,22 +69,23 @@ public Boolean isInsideKubernetes() { private synchronized Pod internalGetPod() { try { if (isServiceAccountFound() && isHostNameEnvVarPresent()) { - return client.pods().withName(hostName).get(); + return this.client.pods().withName(this.hostName).get(); } else { return null; } } catch (Throwable t) { - LOG.warn("Failed to get pod with name:[" + hostName - + "]. You should look into this if things aren't working as you expect. Are you missing serviceaccount permissions?", + LOG.warn("Failed to get pod with name:[" + this.hostName + + "]. You should look into this if things aren't" + + " working as you expect. Are you missing serviceaccount permissions?", t); return null; } } private boolean isHostNameEnvVarPresent() { - return hostName != null && !hostName.isEmpty(); + return this.hostName != null && !this.hostName.isEmpty(); } private boolean isServiceAccountFound() { @@ -82,4 +93,5 @@ private boolean isServiceAccountFound() { && Paths.get(Config.KUBERNETES_SERVICE_ACCOUNT_CA_CRT_PATH).toFile() .exists(); } + } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesApplicationContextInitializer.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesApplicationContextInitializer.java index 72f60c0ca1..ca448c4baf 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesApplicationContextInitializer.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesApplicationContextInitializer.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.profile; @@ -27,6 +26,11 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.Ordered; +/** + * Kubernetes specific application context initializer. + * + * @author Ioannis Canellos + */ public class KubernetesApplicationContextInitializer implements ApplicationContextInitializer, Ordered { @@ -54,7 +58,8 @@ public int getOrder() { @Override public void initialize(ConfigurableApplicationContext applicationContext) { - listenerSupplier.get().addKubernetesProfile(applicationContext.getEnvironment()); + this.listenerSupplier.get() + .addKubernetesProfile(applicationContext.getEnvironment()); } } diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListener.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListener.java index a369b40bad..d033686797 100644 --- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListener.java +++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListener.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.profile; @@ -27,6 +26,11 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; +/** + * Adds Kubernetes profiles. + * + * @author Ioannis Canellos + */ public class KubernetesProfileApplicationListener implements ApplicationListener, Ordered { @@ -34,8 +38,11 @@ public class KubernetesProfileApplicationListener .getLog(KubernetesProfileApplicationListener.class); private static final String KUBERNETES_PROFILE = "kubernetes"; + private static final int OFFSET = 1; + private static final int ORDER = Ordered.HIGHEST_PRECEDENCE + OFFSET; + private final PodUtils utils; public KubernetesProfileApplicationListener(PodUtils utils) { @@ -49,7 +56,7 @@ public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { } void addKubernetesProfile(ConfigurableEnvironment environment) { - if (utils.isInsideKubernetes()) { + if (this.utils.isInsideKubernetes()) { if (hasKubernetesProfile(environment)) { if (LOG.isDebugEnabled()) { LOG.debug("'kubernetes' already in list of active profiles"); @@ -83,4 +90,5 @@ private boolean hasKubernetesProfile(Environment environment) { public int getOrder() { return ORDER; } + } diff --git a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/HealthIndicatorTest.java b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/HealthIndicatorTest.java index f320f4200e..3c08fa446c 100644 --- a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/HealthIndicatorTest.java +++ b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/HealthIndicatorTest.java @@ -1,7 +1,20 @@ -package org.springframework.cloud.kubernetes; +/* + * 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 io.restassured.RestAssured.given; -import static org.hamcrest.core.StringContains.containsString; +package org.springframework.cloud.kubernetes; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; @@ -11,16 +24,18 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.kubernetes.example.App; import org.springframework.test.context.junit4.SpringRunner; +import static io.restassured.RestAssured.given; +import static org.hamcrest.core.StringContains.containsString; + @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, - properties = { - "management.endpoint.health.show-details=always" - }) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = { + "management.endpoint.health.show-details=always" }) public class HealthIndicatorTest { @ClassRule @@ -31,29 +46,26 @@ public class HealthIndicatorTest { @Value("${local.server.port}") private int port; - @BeforeClass public static void setUpBeforeClass() { mockClient = server.getClient(); - //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()); + // Configure the kubernetes master url to point to the mock server + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + mockClient.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @Test public void healthEndpointShouldContainKubernetes() { - RestAssured.baseURI = String.format("http://localhost:%d/actuator/health", port); - given() - .contentType("application/json") - .get() - .then() - .statusCode(200) - .body(containsString("kubernetes")); + RestAssured.baseURI = String.format("http://localhost:%d/actuator/health", + this.port); + given().contentType("application/json").get().then().statusCode(200) + .body(containsString("kubernetes")); } - } diff --git a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/InfoContributorTest.java b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/InfoContributorTest.java index 7b816c5d7f..278dc19b3f 100644 --- a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/InfoContributorTest.java +++ b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/InfoContributorTest.java @@ -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. @@ -12,14 +12,10 @@ * 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.kubernetes; -import static io.restassured.RestAssured.given; -import static org.hamcrest.core.StringContains.containsString; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.server.mock.KubernetesServer; @@ -28,11 +24,15 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.kubernetes.example.App; import org.springframework.test.context.junit4.SpringRunner; +import static io.restassured.RestAssured.given; +import static org.hamcrest.core.StringContains.containsString; + @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class) public class InfoContributorTest { @@ -45,29 +45,26 @@ public class InfoContributorTest { @Value("${local.server.port}") private int port; - @BeforeClass public static void setUpBeforeClass() { mockClient = server.getClient(); - //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()); + // Configure the kubernetes master url to point to the mock server + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + mockClient.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @Test public void infoEndpointShouldContainKubernetes() { - RestAssured.baseURI = String.format("http://localhost:%d/actuator/info", port); - given() - .contentType("application/json") - .get() - .then() - .statusCode(200) - .body(containsString("kubernetes")); + RestAssured.baseURI = String.format("http://localhost:%d/actuator/info", + this.port); + given().contentType("application/json").get().then().statusCode(200) + .body(containsString("kubernetes")); } - } diff --git a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/LazilyInstantiateTest.java b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/LazilyInstantiateTest.java index 225e1631ec..7e0f796bb2 100644 --- a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/LazilyInstantiateTest.java +++ b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/LazilyInstantiateTest.java @@ -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. @@ -12,15 +12,10 @@ * 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.kubernetes; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - import java.util.function.Supplier; import org.junit.Before; @@ -29,6 +24,10 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + @RunWith(MockitoJUnitRunner.class) public class LazilyInstantiateTest { @@ -40,30 +39,32 @@ public class LazilyInstantiateTest { @Before public void setUp() throws Exception { // common setup - when(mockSupplier.get()).thenReturn(SINGLETON) + when(this.mockSupplier.get()).thenReturn(SINGLETON) .thenThrow(new RuntimeException("Supplier was called more than once!")); } @Test public void supplierNotCalledInLazyInstantiateFactoryMethod() { - LazilyInstantiate.using(mockSupplier); + LazilyInstantiate.using(this.mockSupplier); // verify - verifyZeroInteractions(mockSupplier); + verifyZeroInteractions(this.mockSupplier); } @Test public void factoryReturnsSingletonFromSupplier() { - LazilyInstantiate lazyStringFactory = LazilyInstantiate.using(mockSupplier); + LazilyInstantiate lazyStringFactory = LazilyInstantiate + .using(this.mockSupplier); String singletonString = lazyStringFactory.get(); // verify - assertEquals(SINGLETON, singletonString); + assertThat(singletonString).isEqualTo(SINGLETON); } @Test public void factoryOnlyCallsSupplierOnce() { - LazilyInstantiate lazyStringFactory = LazilyInstantiate.using(mockSupplier); + LazilyInstantiate lazyStringFactory = LazilyInstantiate + .using(this.mockSupplier); lazyStringFactory.get(); // mock will throw exception if it is called more than once diff --git a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/StandardPodUtilsTest.java b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/StandardPodUtilsTest.java index 3e0f85c83e..59b102e96e 100644 --- a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/StandardPodUtilsTest.java +++ b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/StandardPodUtilsTest.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes; import org.junit.Test; diff --git a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/example/App.java b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/example/App.java index f741704ea2..491982317c 100644 --- a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/example/App.java +++ b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/example/App.java @@ -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.kubernetes.example; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListenerTest.java b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListenerTest.java index ef7d113889..1ae77b074d 100644 --- a/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListenerTest.java +++ b/spring-cloud-kubernetes-core/src/test/java/org/springframework/cloud/kubernetes/profile/KubernetesProfileApplicationListenerTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.profile; @@ -22,6 +21,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.cloud.kubernetes.PodUtils; import org.springframework.core.env.ConfigurableEnvironment; @@ -48,23 +48,23 @@ public class KubernetesProfileApplicationListenerTest { @Before public void before() { - when(mockEnvironment.getActiveProfiles()).thenReturn(ACTIVE_PROFILES); - when(mockEvent.getEnvironment()).thenReturn(mockEnvironment); - listener = new KubernetesProfileApplicationListener(mockPodUtils); + when(this.mockEnvironment.getActiveProfiles()).thenReturn(ACTIVE_PROFILES); + when(this.mockEvent.getEnvironment()).thenReturn(this.mockEnvironment); + this.listener = new KubernetesProfileApplicationListener(this.mockPodUtils); } @Test public void shouldEnableKubernetesProfile() { - when(mockPodUtils.isInsideKubernetes()).thenReturn(true); - listener.onApplicationEvent(mockEvent); - verify(mockEnvironment).addActiveProfile("kubernetes"); + when(this.mockPodUtils.isInsideKubernetes()).thenReturn(true); + this.listener.onApplicationEvent(this.mockEvent); + verify(this.mockEnvironment).addActiveProfile("kubernetes"); } @Test public void shouldNotEnableKubernetesProfile() { - when(mockPodUtils.isInsideKubernetes()).thenReturn(false); - listener.onApplicationEvent(mockEvent); - verify(mockEnvironment, times(0)).addActiveProfile("kubernetes"); + when(this.mockPodUtils.isInsideKubernetes()).thenReturn(false); + this.listener.onApplicationEvent(this.mockEvent); + verify(this.mockEnvironment, times(0)).addActiveProfile("kubernetes"); } } diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 8c859ebb2e..f3cd894311 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -16,7 +16,8 @@ ~ --> - 4.0.0 diff --git a/spring-cloud-kubernetes-discovery/pom.xml b/spring-cloud-kubernetes-discovery/pom.xml index fdee6dc206..3e57a9c896 100644 --- a/spring-cloud-kubernetes-discovery/pom.xml +++ b/spring-cloud-kubernetes-discovery/pom.xml @@ -16,8 +16,8 @@ ~ --> - org.springframework.cloud diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolver.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolver.java index 016b5fbd3e..b8b75e14c6 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolver.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolver.java @@ -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. @@ -12,69 +12,76 @@ * 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.kubernetes.discovery; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + /** * TODO break up into delegates if the implementation get's more complicated *

- * Returns true if one of the following conditions apply: + * Returns true if one of the following conditions apply. *

- * spring.cloud.kubernetes.discovery.secured has been set to true - * the service contains a label or an annotation named 'secured' that is truthy - * the port is one of the known ports used for secure communication + * spring.cloud.kubernetes.discovery.secured has been set to true the service contains a + * label or an annotation named 'secured' that is truthy the port is one of the known + * ports used for secure communication */ class DefaultIsServicePortSecureResolver { - private static final Log log = LogFactory.getLog(DefaultIsServicePortSecureResolver.class); - + private static final Log log = LogFactory + .getLog(DefaultIsServicePortSecureResolver.class); - private static final Set TRUTHY_STRINGS = new HashSet() {{ - add("true"); - add("on"); - add("yes"); - add("1"); - }}; + private static final Set TRUTHY_STRINGS = new HashSet() { + { + add("true"); + add("on"); + add("yes"); + add("1"); + } + }; private final KubernetesDiscoveryProperties properties; - public DefaultIsServicePortSecureResolver(KubernetesDiscoveryProperties properties) { + DefaultIsServicePortSecureResolver(KubernetesDiscoveryProperties properties) { this.properties = properties; } boolean resolve(Input input) { - final String securedLabelValue = input.getServiceLabels().getOrDefault("secured", "false"); + final String securedLabelValue = input.getServiceLabels().getOrDefault("secured", + "false"); if (TRUTHY_STRINGS.contains(securedLabelValue)) { if (log.isDebugEnabled()) { - log.debug("Considering service with name: " + input.getServiceName() + " and port " + input.getPort() - + " is secure since the service contains a true value for the 'secured' label"); + log.debug("Considering service with name: " + input.getServiceName() + + " and port " + input.getPort() + + " is secure since the service contains a true value for the 'secured' label"); } return true; } - final String securedAnnotationValue = input.getServiceAnnotations().getOrDefault("secured", "false"); + final String securedAnnotationValue = input.getServiceAnnotations() + .getOrDefault("secured", "false"); if (TRUTHY_STRINGS.contains(securedAnnotationValue)) { if (log.isDebugEnabled()) { - log.debug("Considering service with name: " + input.getServiceName() + " and port " + input.getPort() - + " is secure since the service contains a true value for the 'secured' annotation"); + log.debug("Considering service with name: " + input.getServiceName() + + " and port " + input.getPort() + + " is secure since the service contains a true value for the 'secured' annotation"); } return true; } - if (input.getPort() != null && properties.getKnownSecurePorts().contains(input.getPort())) { + if (input.getPort() != null + && this.properties.getKnownSecurePorts().contains(input.getPort())) { if (log.isDebugEnabled()) { - log.debug("Considering service with name: " + input.getServiceName() + " and port " + input.getPort() - + " is secure due to the port being a known https port"); + log.debug("Considering service with name: " + input.getServiceName() + + " and port " + input.getPort() + + " is secure due to the port being a known https port"); } return true; } @@ -83,38 +90,45 @@ boolean resolve(Input input) { } static class Input { + private final Integer port; + private final String serviceName; + private final Map serviceLabels; + private final Map serviceAnnotations; - //used only for testing + // used only for testing Input(Integer port, String serviceName) { this(port, serviceName, null, null); } - Input(Integer port, String serviceName, - Map serviceLabels, Map serviceAnnotations) { + Input(Integer port, String serviceName, Map serviceLabels, + Map serviceAnnotations) { this.port = port; this.serviceName = serviceName; this.serviceLabels = serviceLabels == null ? new HashMap<>() : serviceLabels; - this.serviceAnnotations = serviceAnnotations == null ? new HashMap<>() : serviceAnnotations; + this.serviceAnnotations = serviceAnnotations == null ? new HashMap<>() + : serviceAnnotations; } public String getServiceName() { - return serviceName; + return this.serviceName; } public Map getServiceLabels() { - return serviceLabels; + return this.serviceLabels; } public Map getServiceAnnotations() { - return serviceAnnotations; + return this.serviceAnnotations; } public Integer getPort() { - return port; + return this.port; } + } + } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java index b415a037dd..f532f190f8 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java @@ -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. @@ -12,11 +12,16 @@ * 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.kubernetes.discovery; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + import io.fabric8.kubernetes.api.model.EndpointAddress; import io.fabric8.kubernetes.api.model.EndpointSubset; import io.fabric8.kubernetes.api.model.Endpoints; @@ -24,29 +29,25 @@ import io.fabric8.kubernetes.client.KubernetesClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.cloud.client.discovery.event.HeartbeatEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.scheduling.annotation.Scheduled; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; - - /** * @author Oleg Vyukov */ public class KubernetesCatalogWatch implements ApplicationEventPublisherAware { - private static final Logger logger = LoggerFactory.getLogger(KubernetesCatalogWatch.class); + private static final Logger logger = LoggerFactory + .getLogger(KubernetesCatalogWatch.class); private final KubernetesClient kubernetesClient; + private final AtomicReference> catalogEndpointsState = new AtomicReference<>(); - private ApplicationEventPublisher publisher; + private ApplicationEventPublisher publisher; public KubernetesCatalogWatch(KubernetesClient kubernetesClient) { this.kubernetesClient = kubernetesClient; @@ -60,33 +61,32 @@ public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { @Scheduled(fixedDelayString = "${spring.cloud.kubernetes.discovery.catalogServicesWatchDelay:30000}") public void catalogServicesWatch() { try { - List previousState = catalogEndpointsState.get(); - - //not all pods participate in the service discovery. only those that have endpoints. - List endpoints = kubernetesClient.endpoints().list().getItems(); - List endpointsPodNames = - endpoints.stream() - .map(Endpoints::getSubsets) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .map(EndpointSubset::getAddresses) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .map(EndpointAddress::getTargetRef) - .filter(Objects::nonNull) - .map(ObjectReference::getName) // pod name unique in namespace + List previousState = this.catalogEndpointsState.get(); + + // not all pods participate in the service discovery. only those that have + // endpoints. + List endpoints = this.kubernetesClient.endpoints().list() + .getItems(); + List endpointsPodNames = endpoints.stream().map(Endpoints::getSubsets) + .filter(Objects::nonNull).flatMap(Collection::stream) + .map(EndpointSubset::getAddresses).filter(Objects::nonNull) + .flatMap(Collection::stream).map(EndpointAddress::getTargetRef) + .filter(Objects::nonNull).map(ObjectReference::getName) // pod name + // unique in + // namespace .sorted(String::compareTo).collect(Collectors.toList()); - catalogEndpointsState.set(endpointsPodNames); + this.catalogEndpointsState.set(endpointsPodNames); if (!endpointsPodNames.equals(previousState)) { - logger.trace("Received endpoints update from kubernetesClient: {}", endpointsPodNames); - publisher.publishEvent(new HeartbeatEvent(this, endpointsPodNames)); + logger.trace("Received endpoints update from kubernetesClient: {}", + endpointsPodNames); + this.publisher.publishEvent(new HeartbeatEvent(this, endpointsPodNames)); } - } catch (Exception e) { + } + catch (Exception e) { logger.error("Error watching Kubernetes Services", e); } } - } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesClientServicesFunction.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesClientServicesFunction.java index daa6b836f9..94c7778006 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesClientServicesFunction.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesClientServicesFunction.java @@ -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. @@ -12,10 +12,12 @@ * 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.kubernetes.discovery; +import java.util.function.Function; + import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceList; import io.fabric8.kubernetes.client.KubernetesClient; @@ -23,23 +25,25 @@ import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.FilterWatchListDeletable; -import java.util.function.Function; - /** - * A regular java.util.function that is used to hide the complexity of the KubernetesClient interfaces + * A regular java.util.function that is used to hide the complexity of the + * KubernetesClient interfaces. * * It's meant to be used to abstract things like: * - * client.services() - * client.services().withLabel("key", "value") + * client.services() client.services().withLabel("key", "value") * client.services().withoutLabel("key") * - * The result of the application of the function can then be used for example to list the services like so: + * The result of the application of the function can then be used for example to list the + * services like so: * * function.apply(client).list() * * See KubernetesDiscoveryClientAutoConfiguration.servicesFunction + * + * @author Georgios Andrianakis */ public interface KubernetesClientServicesFunction extends - Function>> { + Function>> { + } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java index fec843f51a..b85f9798b9 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java @@ -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. @@ -12,10 +12,17 @@ * 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.kubernetes.discovery; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + import io.fabric8.kubernetes.api.model.EndpointAddress; import io.fabric8.kubernetes.api.model.EndpointPort; import io.fabric8.kubernetes.api.model.EndpointSubset; @@ -24,6 +31,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.expression.Expression; @@ -32,42 +40,42 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; -import java.util.stream.Collectors; - import static java.util.stream.Collectors.toMap; +/** + * Kubeneretes implementation of {@link DiscoveryClient}. + * + * @author Ioannis Canellos + */ public class KubernetesDiscoveryClient implements DiscoveryClient { private static final Log log = LogFactory.getLog(KubernetesDiscoveryClient.class); - private KubernetesClient client; private final KubernetesDiscoveryProperties properties; + private final DefaultIsServicePortSecureResolver isServicePortSecureResolver; private final KubernetesClientServicesFunction kubernetesClientServicesFunction; + private final SpelExpressionParser parser = new SpelExpressionParser(); + private final SimpleEvaluationContext evalCtxt = SimpleEvaluationContext - .forReadOnlyDataBinding() - .withInstanceMethods() - .build(); + .forReadOnlyDataBinding().withInstanceMethods().build(); + + private KubernetesClient client; public KubernetesDiscoveryClient(KubernetesClient client, - KubernetesDiscoveryProperties kubernetesDiscoveryProperties, - KubernetesClientServicesFunction kubernetesClientServicesFunction) { + KubernetesDiscoveryProperties kubernetesDiscoveryProperties, + KubernetesClientServicesFunction kubernetesClientServicesFunction) { this(client, kubernetesDiscoveryProperties, kubernetesClientServicesFunction, - new DefaultIsServicePortSecureResolver(kubernetesDiscoveryProperties)); + new DefaultIsServicePortSecureResolver(kubernetesDiscoveryProperties)); } KubernetesDiscoveryClient(KubernetesClient client, - KubernetesDiscoveryProperties kubernetesDiscoveryProperties, - KubernetesClientServicesFunction kubernetesClientServicesFunction, - DefaultIsServicePortSecureResolver isServicePortSecureResolver) { + KubernetesDiscoveryProperties kubernetesDiscoveryProperties, + KubernetesClientServicesFunction kubernetesClientServicesFunction, + DefaultIsServicePortSecureResolver isServicePortSecureResolver) { this.client = client; this.properties = kubernetesDiscoveryProperties; @@ -76,7 +84,7 @@ public KubernetesDiscoveryClient(KubernetesClient client, } public KubernetesClient getClient() { - return client; + return this.client; } public void setClient(KubernetesClient client) { @@ -93,62 +101,64 @@ public List getInstances(String serviceId) { Assert.notNull(serviceId, "[Assertion failed] - the object argument must be null"); - Endpoints endpoints = client.endpoints().withName(serviceId).get(); + Endpoints endpoints = this.client.endpoints().withName(serviceId).get(); List subsets = getSubsetsFromEndpoints(endpoints); List instances = new ArrayList<>(); if (!subsets.isEmpty()) { - final Service service = client.services().withName(serviceId).get(); + final Service service = this.client.services().withName(serviceId).get(); final Map serviceMetadata = new HashMap<>(); - KubernetesDiscoveryProperties.Metadata metadataProps = properties.getMetadata(); - if(metadataProps.isAddLabels()) { + KubernetesDiscoveryProperties.Metadata metadataProps = this.properties + .getMetadata(); + if (metadataProps.isAddLabels()) { Map labelMetadata = getMapWithPrefixedKeys( - service.getMetadata().getLabels(), metadataProps.getLabelsPrefix()); + service.getMetadata().getLabels(), + metadataProps.getLabelsPrefix()); if (log.isDebugEnabled()) { - log.debug("Adding label metadata: "+labelMetadata); + log.debug("Adding label metadata: " + labelMetadata); } serviceMetadata.putAll(labelMetadata); } - if(metadataProps.isAddAnnotations()) { + if (metadataProps.isAddAnnotations()) { Map annotationMetadata = getMapWithPrefixedKeys( - service.getMetadata().getAnnotations(), metadataProps.getAnnotationsPrefix()); + service.getMetadata().getAnnotations(), + metadataProps.getAnnotationsPrefix()); if (log.isDebugEnabled()) { - log.debug("Adding annotation metadata: "+annotationMetadata); + log.debug("Adding annotation metadata: " + annotationMetadata); } serviceMetadata.putAll(annotationMetadata); } for (EndpointSubset s : subsets) { - // Extend the service metadata map with per-endpoint port information (if requested) + // Extend the service metadata map with per-endpoint port information (if + // requested) Map endpointMetadata = new HashMap<>(serviceMetadata); - if(metadataProps.isAddPorts()) { + if (metadataProps.isAddPorts()) { Map ports = s.getPorts().stream() - .filter(port -> !StringUtils.isEmpty(port.getName())) - .collect(toMap(EndpointPort::getName, port -> Integer.toString(port.getPort()))); - Map portMetadata = getMapWithPrefixedKeys(ports, metadataProps.getPortsPrefix()); + .filter(port -> !StringUtils.isEmpty(port.getName())) + .collect(toMap(EndpointPort::getName, + port -> Integer.toString(port.getPort()))); + Map portMetadata = getMapWithPrefixedKeys(ports, + metadataProps.getPortsPrefix()); if (log.isDebugEnabled()) { - log.debug("Adding port metadata: "+portMetadata); + log.debug("Adding port metadata: " + portMetadata); } endpointMetadata.putAll(portMetadata); } List addresses = s.getAddresses(); for (EndpointAddress endpointAddress : addresses) { - final EndpointPort endpointPort = - s.getPorts().stream().findFirst().orElseThrow(IllegalStateException::new); + final EndpointPort endpointPort = s.getPorts().stream().findFirst() + .orElseThrow(IllegalStateException::new); instances.add(new KubernetesServiceInstance(serviceId, - endpointAddress, - endpointPort, - endpointMetadata, - isServicePortSecureResolver.resolve( - new DefaultIsServicePortSecureResolver.Input( + endpointAddress, endpointPort, endpointMetadata, + this.isServicePortSecureResolver + .resolve(new DefaultIsServicePortSecureResolver.Input( endpointPort.getPort(), service.getMetadata().getName(), service.getMetadata().getLabels(), - service.getMetadata().getAnnotations() - ) - ))); + service.getMetadata().getAnnotations())))); } } } @@ -170,7 +180,8 @@ private List getSubsetsFromEndpoints(Endpoints endpoints) { // returns a new map that contain all the entries of the original map // but with the keys prefixed // if the prefix is null or empty, the map itself is returned (unchanged of course) - private Map getMapWithPrefixedKeys(Map map, String prefix) { + private Map getMapWithPrefixedKeys(Map map, + String prefix) { if (map == null) { return new HashMap<>(); } @@ -188,14 +199,16 @@ private Map getMapWithPrefixedKeys(Map map, Stri @Override public List getServices() { - String spelExpression = properties.getFilter(); + String spelExpression = this.properties.getFilter(); Predicate filteredServices; if (spelExpression == null || spelExpression.isEmpty()) { filteredServices = (Service instance) -> true; - } else { - Expression filterExpr = parser.parseExpression(spelExpression); + } + else { + Expression filterExpr = this.parser.parseExpression(spelExpression); filteredServices = (Service instance) -> { - Boolean include = filterExpr.getValue(evalCtxt, instance, Boolean.class); + Boolean include = filterExpr.getValue(this.evalCtxt, instance, + Boolean.class); if (include == null) { return false; } @@ -206,11 +219,8 @@ public List getServices() { } public List getServices(Predicate filter) { - return kubernetesClientServicesFunction.apply(client).list() - .getItems() - .stream() - .filter(filter) - .map(s -> s.getMetadata().getName()) + return this.kubernetesClientServicesFunction.apply(this.client).list().getItems() + .stream().filter(filter).map(s -> s.getMetadata().getName()) .collect(Collectors.toList()); } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java index ac8d7bf354..a647b62dce 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java @@ -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. @@ -12,12 +12,12 @@ * 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.kubernetes.discovery; import io.fabric8.kubernetes.client.KubernetesClient; + import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -28,21 +28,28 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +/** + * Auto configuration for discovery clients. + * + * @author Mauricio Salatino + */ @Configuration -@ConditionalOnProperty(name="spring.cloud.kubernetes.enabled", matchIfMissing = true) +@ConditionalOnProperty(name = "spring.cloud.kubernetes.enabled", matchIfMissing = true) @AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, - CommonsClientAutoConfiguration.class, }) + CommonsClientAutoConfiguration.class }) public class KubernetesDiscoveryClientAutoConfiguration { @Bean @ConditionalOnMissingBean - public DefaultIsServicePortSecureResolver isServicePortSecureResolver(KubernetesDiscoveryProperties properties) { + public DefaultIsServicePortSecureResolver isServicePortSecureResolver( + KubernetesDiscoveryProperties properties) { return new DefaultIsServicePortSecureResolver(properties); } @Bean - public KubernetesClientServicesFunction servicesFunction(KubernetesDiscoveryProperties properties) { - if (properties.getServiceLabels().isEmpty()) { + public KubernetesClientServicesFunction servicesFunction( + KubernetesDiscoveryProperties properties) { + if (properties.getServiceLabels().isEmpty()) { return KubernetesClient::services; } @@ -51,12 +58,13 @@ public KubernetesClientServicesFunction servicesFunction(KubernetesDiscoveryProp @Bean @ConditionalOnMissingBean - @ConditionalOnProperty(name = "spring.cloud.kubernetes.discovery.enabled",matchIfMissing = true) + @ConditionalOnProperty(name = "spring.cloud.kubernetes.discovery.enabled", matchIfMissing = true) public KubernetesDiscoveryClient kubernetesDiscoveryClient(KubernetesClient client, - KubernetesDiscoveryProperties properties, - KubernetesClientServicesFunction kubernetesClientServicesFunction, - DefaultIsServicePortSecureResolver isServicePortSecureResolver) { - return new KubernetesDiscoveryClient(client, properties, kubernetesClientServicesFunction, isServicePortSecureResolver); + KubernetesDiscoveryProperties properties, + KubernetesClientServicesFunction kubernetesClientServicesFunction, + DefaultIsServicePortSecureResolver isServicePortSecureResolver) { + return new KubernetesDiscoveryClient(client, properties, + kubernetesClientServicesFunction, isServicePortSecureResolver); } @Bean @@ -66,7 +74,7 @@ public KubernetesServiceRegistry getServiceRegistry() { @Bean public KubernetesRegistration getRegistration(KubernetesClient client, - KubernetesDiscoveryProperties properties) { + KubernetesDiscoveryProperties properties) { return new KubernetesRegistration(client, properties); } @@ -81,4 +89,5 @@ public KubernetesDiscoveryProperties getKubernetesDiscoveryProperties() { public KubernetesCatalogWatch kubernetesCatalogWatch(KubernetesClient client) { return new KubernetesCatalogWatch(client); } + } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfiguration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfiguration.java index 7207adb529..b7b4041267 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfiguration.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfiguration.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.discovery; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -21,8 +21,15 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +/** + * Bootstrap config for Kubernetes discovery config client. + * + * @author Zhanwei Wang + */ @Configuration -@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled") -@Import({KubernetesAutoConfiguration.class, - KubernetesDiscoveryClientAutoConfiguration.class, }) -public class KubernetesDiscoveryClientConfigClientBootstrapConfiguration {} +@ConditionalOnProperty("spring.cloud.config.discovery.enabled") +@Import({ KubernetesAutoConfiguration.class, + KubernetesDiscoveryClientAutoConfiguration.class }) +public class KubernetesDiscoveryClientConfigClientBootstrapConfiguration { + +} diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java index 961b385ade..06ff845dc4 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java @@ -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. @@ -12,20 +12,24 @@ * 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.kubernetes.discovery; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.style.ToStringCreator; - import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.style.ToStringCreator; + +/** + * Kubernetes discovery properties. + * + * @author Ioannis Canellos + */ @ConfigurationProperties("spring.cloud.kubernetes.discovery") public class KubernetesDiscoveryProperties { @@ -36,23 +40,30 @@ public class KubernetesDiscoveryProperties { @Value("${spring.application.name:unknown}") private String serviceName = "unknown"; - /** SpEL expression to filter services AFTER they have been retrieved from the Kubernetes API server. */ + /** + * SpEL expression to filter services AFTER they have been retrieved from the + * Kubernetes API server. + */ private String filter; + /** Set the port numbers that are considered secure and use HTTPS. */ + private Set knownSecurePorts = new HashSet() { + { + add(443); + add(8443); + } + }; - /** Set the port numbers that are considered secure and use HTTPS */ - private Set knownSecurePorts = new HashSet() {{ - add(443); - add(8443); - }}; - - /** If set, then only the services matching these labels will be fetched from the Kubernetes API server */ + /** + * If set, then only the services matching these labels will be fetched from the + * Kubernetes API server. + */ private Map serviceLabels = new HashMap<>(); private Metadata metadata = new Metadata(); public boolean isEnabled() { - return enabled; + return this.enabled; } public void setEnabled(boolean enabled) { @@ -60,7 +71,7 @@ public void setEnabled(boolean enabled) { } public String getServiceName() { - return serviceName; + return this.serviceName; } public void setServiceName(String serviceName) { @@ -68,15 +79,15 @@ public void setServiceName(String serviceName) { } public String getFilter() { - return filter; + return this.filter; } - public void setFilter(String filter){ + public void setFilter(String filter) { this.filter = filter; } public Set getKnownSecurePorts() { - return knownSecurePorts; + return this.knownSecurePorts; } public void setKnownSecurePorts(Set knownSecurePorts) { @@ -84,7 +95,7 @@ public void setKnownSecurePorts(Set knownSecurePorts) { } public Map getServiceLabels() { - return serviceLabels; + return this.serviceLabels; } public void setServiceLabels(Map serviceLabels) { @@ -92,7 +103,7 @@ public void setServiceLabels(Map serviceLabels) { } public Metadata getMetadata() { - return metadata; + return this.metadata; } public void setMetadata(Metadata metadata) { @@ -101,37 +112,56 @@ public void setMetadata(Metadata metadata) { @Override public String toString() { - return new ToStringCreator(this) - .append("enabled", enabled) - .append("serviceName", serviceName) - .append("filter", filter) - .append("knownSecurePorts", knownSecurePorts) - .append("serviceLabels", serviceLabels) - .append("metadata", metadata) - .toString(); + return new ToStringCreator(this).append("enabled", this.enabled) + .append("serviceName", this.serviceName).append("filter", this.filter) + .append("knownSecurePorts", this.knownSecurePorts) + .append("serviceLabels", this.serviceLabels) + .append("metadata", this.metadata).toString(); } + /** + * Metadata properties. + */ public class Metadata { - /** When set, the Kubernetes labels of the services will be included as metadata of the returned ServiceInstance. */ + + /** + * When set, the Kubernetes labels of the services will be included as metadata of + * the returned ServiceInstance. + */ private boolean addLabels = true; - /** When addLabels is set, then this will be used as a prefix to the key names in the metadata map. */ + /** + * When addLabels is set, then this will be used as a prefix to the key names in + * the metadata map. + */ private String labelsPrefix; - /** When set, the Kubernetes annotations of the services will be included as metadata of the returned ServiceInstance. */ + /** + * When set, the Kubernetes annotations of the services will be included as + * metadata of the returned ServiceInstance. + */ private boolean addAnnotations = true; - /** When addAnnotations is set, then this will be used as a prefix to the key names in the metadata map. */ + /** + * When addAnnotations is set, then this will be used as a prefix to the key names + * in the metadata map. + */ private String annotationsPrefix; - /** When set, any named Kubernetes service ports will be included as metadata of the returned ServiceInstance. */ + /** + * When set, any named Kubernetes service ports will be included as metadata of + * the returned ServiceInstance. + */ private boolean addPorts = true; - /** When addPorts is set, then this will be used as a prefix to the key names in the metadata map. */ + /** + * When addPorts is set, then this will be used as a prefix to the key names in + * the metadata map. + */ private String portsPrefix = "port."; public boolean isAddLabels() { - return addLabels; + return this.addLabels; } public void setAddLabels(boolean addLabels) { @@ -139,7 +169,7 @@ public void setAddLabels(boolean addLabels) { } public String getLabelsPrefix() { - return labelsPrefix; + return this.labelsPrefix; } public void setLabelsPrefix(String labelsPrefix) { @@ -147,7 +177,7 @@ public void setLabelsPrefix(String labelsPrefix) { } public boolean isAddAnnotations() { - return addAnnotations; + return this.addAnnotations; } public void setAddAnnotations(boolean addAnnotations) { @@ -155,7 +185,7 @@ public void setAddAnnotations(boolean addAnnotations) { } public String getAnnotationsPrefix() { - return annotationsPrefix; + return this.annotationsPrefix; } public void setAnnotationsPrefix(String annotationsPrefix) { @@ -163,7 +193,7 @@ public void setAnnotationsPrefix(String annotationsPrefix) { } public boolean isAddPorts() { - return addPorts; + return this.addPorts; } public void setAddPorts(boolean addPorts) { @@ -171,7 +201,7 @@ public void setAddPorts(boolean addPorts) { } public String getPortsPrefix() { - return portsPrefix; + return this.portsPrefix; } public void setPortsPrefix(String portsPrefix) { @@ -180,14 +210,14 @@ public void setPortsPrefix(String portsPrefix) { @Override public String toString() { - return new ToStringCreator(this) - .append("addLabels", addLabels) - .append("labelsPrefix", labelsPrefix) - .append("addAnnotations", addAnnotations) - .append("annotationsPrefix", annotationsPrefix) - .append("addPorts", addPorts) - .append("portsPrefix", portsPrefix) - .toString(); + return new ToStringCreator(this).append("addLabels", this.addLabels) + .append("labelsPrefix", this.labelsPrefix) + .append("addAnnotations", this.addAnnotations) + .append("annotationsPrefix", this.annotationsPrefix) + .append("addPorts", this.addPorts) + .append("portsPrefix", this.portsPrefix).toString(); } + } + } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java index b90b8a2298..27187c41ae 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.discovery; @@ -23,25 +22,34 @@ import io.fabric8.kubernetes.api.model.EndpointAddress; import io.fabric8.kubernetes.api.model.EndpointPort; + import org.springframework.cloud.client.ServiceInstance; +/** + * Kubernetes {@link ServiceInstance}. + * + * @author Ioannis Canellos + */ public class KubernetesServiceInstance implements ServiceInstance { private static final String HTTP_PREFIX = "http://"; + private static final String HTTPS_PREFIX = "https://"; + private static final String COLN = ":"; private final String serviceId; + private final EndpointAddress endpointAddress; + private final EndpointPort endpointPort; + private final Boolean secure; + private final Map metadata; - public KubernetesServiceInstance(String serviceId, - EndpointAddress endpointAddress, - EndpointPort endpointPort, - Map metadata, - Boolean secure) { + public KubernetesServiceInstance(String serviceId, EndpointAddress endpointAddress, + EndpointPort endpointPort, Map metadata, Boolean secure) { this.serviceId = serviceId; this.endpointAddress = endpointAddress; this.endpointPort = endpointPort; @@ -51,22 +59,22 @@ public KubernetesServiceInstance(String serviceId, @Override public String getServiceId() { - return serviceId; + return this.serviceId; } @Override public String getHost() { - return endpointAddress.getIp(); + return this.endpointAddress.getIp(); } @Override public int getPort() { - return endpointPort.getPort(); + return this.endpointPort.getPort(); } @Override public boolean isSecure() { - return secure; + return this.secure; } @Override @@ -75,19 +83,22 @@ public URI getUri() { if (isSecure()) { sb.append(HTTPS_PREFIX); - } else { + } + else { sb.append(HTTP_PREFIX); } sb.append(getHost()).append(COLN).append(getPort()); try { return new URI(sb.toString()); - } catch (URISyntaxException e) { + } + catch (URISyntaxException e) { throw new RuntimeException(e); } } public Map getMetadata() { - return metadata; + return this.metadata; } + } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesAutoServiceRegistration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesAutoServiceRegistration.java index 3c9f5fff37..512a00ff85 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesAutoServiceRegistration.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesAutoServiceRegistration.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.registry; @@ -22,6 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent; import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistration; @@ -31,11 +31,16 @@ import org.springframework.context.event.EventListener; import org.springframework.core.Ordered; -public class KubernetesAutoServiceRegistration implements AutoServiceRegistration, - SmartLifecycle, - Ordered { +/** + * Auto service registration for Kubernetes. + * + * @author Mauricio Salatino + */ +public class KubernetesAutoServiceRegistration + implements AutoServiceRegistration, SmartLifecycle, Ordered { - private static final Log log = LogFactory.getLog(KubernetesAutoServiceRegistration.class); + private static final Log log = LogFactory + .getLog(KubernetesAutoServiceRegistration.class); private AtomicBoolean running = new AtomicBoolean(false); @@ -50,8 +55,8 @@ public class KubernetesAutoServiceRegistration implements AutoServiceRegistratio private KubernetesRegistration registration; public KubernetesAutoServiceRegistration(ApplicationContext context, - KubernetesServiceRegistry serviceRegistry, - KubernetesRegistration registration) { + KubernetesServiceRegistry serviceRegistry, + KubernetesRegistration registration) { this.context = context; this.serviceRegistry = serviceRegistry; this.registration = registration; @@ -73,8 +78,7 @@ public void start() { this.serviceRegistry.register(this.registration); this.context.publishEvent( - new InstanceRegisteredEvent<>(this, - this.registration.getProperties())); + new InstanceRegisteredEvent<>(this, this.registration.getProperties())); this.running.set(true); } @@ -105,16 +109,16 @@ public void onApplicationEvent(ServletWebServerInitializedEvent event) { int localPort = event.getWebServer().getPort(); if (this.port.get() == 0) { log.info("Updating port to " + localPort); - this.port.compareAndSet(0, - localPort); + this.port.compareAndSet(0, localPort); start(); } } @EventListener(ContextClosedEvent.class) public void onApplicationEvent(ContextClosedEvent event) { - if (event.getApplicationContext() == context) { + if (event.getApplicationContext() == this.context) { stop(); } } + } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesRegistration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesRegistration.java index b1eb2b95a9..543b7a85ed 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesRegistration.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesRegistration.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.registry; @@ -25,18 +24,25 @@ import java.util.concurrent.atomic.AtomicBoolean; import io.fabric8.kubernetes.client.KubernetesClient; + import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; +/** + * Kubernetes implementation of a {@link Registration}. + * + * @author Mauricio Salatino + */ public class KubernetesRegistration implements Registration, Closeable { - private final KubernetesClient client; + private KubernetesDiscoveryProperties properties; + private AtomicBoolean running = new AtomicBoolean(false); public KubernetesRegistration(KubernetesClient client, - KubernetesDiscoveryProperties properties) { + KubernetesDiscoveryProperties properties) { this.client = client; this.properties = properties; } @@ -48,12 +54,12 @@ public void close() throws IOException { @Override public String getServiceId() { - return properties.getServiceName(); + return this.properties.getServiceName(); } @Override public String getHost() { - return client.getMasterUrl().getHost(); + return this.client.getMasterUrl().getHost(); } @Override @@ -69,15 +75,16 @@ public boolean isSecure() { @Override public URI getUri() { try { - return client.getMasterUrl().toURI(); - } catch (URISyntaxException e) { + return this.client.getMasterUrl().toURI(); + } + catch (URISyntaxException e) { e.printStackTrace(); } return null; } public KubernetesDiscoveryProperties getProperties() { - return properties; + return this.properties; } @Override @@ -87,10 +94,8 @@ public Map getMetadata() { @Override public String toString() { - return "KubernetesRegistration{" + - "client=" + client + - ", properties=" + properties + - ", running=" + running + - '}'; + return "KubernetesRegistration{" + "client=" + this.client + ", properties=" + + this.properties + ", running=" + this.running + '}'; } + } diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesServiceRegistry.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesServiceRegistry.java index 82813d5a48..2ecb500498 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesServiceRegistry.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesServiceRegistry.java @@ -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. @@ -12,16 +12,22 @@ * 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.kubernetes.registry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -public class KubernetesServiceRegistry implements ServiceRegistry { +/** + * Kubernetes {@link ServiceRegistry}. + * + * @author Mauricio Salatino + */ +public class KubernetesServiceRegistry + implements ServiceRegistry { private static final Log log = LogFactory.getLog(KubernetesServiceRegistry.class); @@ -44,15 +50,15 @@ public void close() { } @Override - public void setStatus(KubernetesRegistration registration, - String status) { + public void setStatus(KubernetesRegistration registration, String status) { log.info("Set Status for : " + registration + " Status: " + status); } @Override public T getStatus(KubernetesRegistration registration) { - log.info("Get Status for : " + registration ); + log.info("Get Status for : " + registration); return null; } + } diff --git a/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories index 3061cdd61e..354998d98c 100644 --- a/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories @@ -1,5 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration - org.springframework.cloud.bootstrap.BootstrapConfiguration=\ org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientConfigClientBootstrapConfiguration diff --git a/spring-cloud-kubernetes-discovery/src/test/groovy/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.groovy b/spring-cloud-kubernetes-discovery/src/test/groovy/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.groovy index b0d566ef07..b5b2afe711 100644 --- a/spring-cloud-kubernetes-discovery/src/test/groovy/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.groovy +++ b/spring-cloud-kubernetes-discovery/src/test/groovy/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.groovy @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.discovery @@ -23,9 +22,10 @@ import io.fabric8.kubernetes.api.model.ServiceListBuilder import io.fabric8.kubernetes.client.Config import io.fabric8.kubernetes.client.KubernetesClient import io.fabric8.kubernetes.server.mock.KubernetesMockServer +import spock.lang.Specification + import org.springframework.cloud.client.ServiceInstance import org.springframework.cloud.client.discovery.DiscoveryClient -import spock.lang.Specification import static org.assertj.core.api.Assertions.assertThat @@ -40,10 +40,12 @@ class KubernetesDiscoveryClientTest extends Specification { mockClient = mockServer.createClient() //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()) + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient. + getConfiguration().getMasterUrl()) System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true") System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false") - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false") + System. + setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false") } def cleanupSpec() { @@ -52,156 +54,186 @@ class KubernetesDiscoveryClientTest extends Specification { def "getInstances should be able to handle endpoints single address"() { given: - mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint").andReturn(200, new EndpointsBuilder() - .withNewMetadata() + mockServer.expect().get(). + withPath("/api/v1/namespaces/test/endpoints/endpoint"). + andReturn(200, new EndpointsBuilder() + .withNewMetadata() .withName("endpoint") - .endMetadata() - .addNewSubset() + .endMetadata() + .addNewSubset() .addNewAddress() - .withIp("ip1") + .withIp("ip1") .endAddress() - .addNewPort("http",80,"TCP") - .endSubset() - .build()).once() + .addNewPort("http", 80, "TCP") + .endSubset() + .build()).once() and: - mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint").andReturn(200, new ServiceBuilder() - .withNewMetadata() - .withName("endpoint") - .withLabels(new HashMap() {{ - put("l", "v") - }}) - .endMetadata() - .build()).once() + mockServer.expect().get(). + withPath("/api/v1/namespaces/test/services/endpoint"). + andReturn(200, new ServiceBuilder() + .withNewMetadata() + .withName("endpoint") + .withLabels(new HashMap() { + { + put("l", "v") + } + }) + .endMetadata() + .build()).once() final properties = new KubernetesDiscoveryProperties() DiscoveryClient discoveryClient = new KubernetesDiscoveryClient( - mockClient, properties, {client -> client.services()}, new DefaultIsServicePortSecureResolver(properties)) + mockClient, properties, { client -> + client.services() + }, new DefaultIsServicePortSecureResolver(properties)) when: - List instances = discoveryClient.getInstances("endpoint") + List instances = discoveryClient.getInstances("endpoint") then: - instances != null - instances.size() == 1 - instances.find({s -> s.host == "ip1" && !s.secure}) + instances != null + instances.size() == 1 + instances.find({ s -> s.host == "ip1" && !s.secure }) } - def "getInstances should be able to handle endpoints multiple addresses"() { given: - mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint").andReturn(200, new EndpointsBuilder() - .withNewMetadata() + mockServer.expect().get(). + withPath("/api/v1/namespaces/test/endpoints/endpoint"). + andReturn(200, new EndpointsBuilder() + .withNewMetadata() .withName("endpoint") - .endMetadata() - .addNewSubset() + .endMetadata() + .addNewSubset() .addNewAddress() - .withIp("ip1") + .withIp("ip1") .endAddress() .addNewAddress() - .withIp("ip2") + .withIp("ip2") .endAddress() - .addNewPort("https",443,"TCP") - .endSubset() - .build()).once() + .addNewPort("https", 443, "TCP") + .endSubset() + .build()).once() and: - mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint").andReturn(200, new ServiceBuilder() - .withNewMetadata() - .withName("endpoint") - .withLabels(new HashMap() {{ - put("l", "v") - }}) - .endMetadata() - .build()).once() + mockServer.expect().get(). + withPath("/api/v1/namespaces/test/services/endpoint"). + andReturn(200, new ServiceBuilder() + .withNewMetadata() + .withName("endpoint") + .withLabels(new HashMap() { + { + put("l", "v") + } + }) + .endMetadata() + .build()).once() final properties = new KubernetesDiscoveryProperties() DiscoveryClient discoveryClient = new KubernetesDiscoveryClient( - mockClient, properties, {client -> client.services()}, new DefaultIsServicePortSecureResolver(properties)) + mockClient, properties, { client -> + client.services() + }, new DefaultIsServicePortSecureResolver(properties)) when: - List instances = discoveryClient.getInstances("endpoint") + List instances = discoveryClient.getInstances("endpoint") then: - instances != null - instances.size() == 2 - instances.find({s -> s.host == "ip1" && s.secure}) - instances.find({s -> s.host == "ip2" && s.secure}) + instances != null + instances.size() == 2 + instances.find({ s -> s.host == "ip1" && s.secure }) + instances.find({ s -> s.host == "ip2" && s.secure }) } def "getServices should return all services when no labels are applied to the client"() { given: - mockServer.expect().get().withPath("/api/v1/namespaces/test/services").andReturn(200, new ServiceListBuilder() - .addNewItem() - .withNewMetadata() - .withName("s1") - .withLabels(new HashMap() {{ - put("label", "value") - }}) - .endMetadata() - .endItem() - .addNewItem() - .withNewMetadata() - .withName("s2") - .withLabels(new HashMap() {{ - put("label", "value") - put("label2", "value2") - }}) - .endMetadata() - .endItem() - .addNewItem() - .withNewMetadata() - .withName("s3") - .endMetadata() - .endItem() - .build()).once() + mockServer.expect().get().withPath("/api/v1/namespaces/test/services"). + andReturn(200, new ServiceListBuilder() + .addNewItem() + .withNewMetadata() + .withName("s1") + .withLabels(new HashMap() { + { + put("label", "value") + } + }) + .endMetadata() + .endItem() + .addNewItem() + .withNewMetadata() + .withName("s2") + .withLabels(new HashMap() { + { + put("label", "value") + put("label2", "value2") + } + }) + .endMetadata() + .endItem() + .addNewItem() + .withNewMetadata() + .withName("s3") + .endMetadata() + .endItem() + .build()).once() and: - DiscoveryClient discoveryClient = new KubernetesDiscoveryClient( - mockClient, new KubernetesDiscoveryProperties(), {client -> client.services()}) + DiscoveryClient discoveryClient = new KubernetesDiscoveryClient( + mockClient, new KubernetesDiscoveryProperties(), { client -> + client.services() + }) when: - List instances = discoveryClient.getServices() + List instances = discoveryClient.getServices() then: - assertThat(instances).containsOnly("s1", "s2", "s3") + assertThat(instances).containsOnly("s1", "s2", "s3") } def "getServices should return only matching services when labels are applied to the client"() { given: - // this is the URL that is created by the KubernetesClient when a a label named 'label' - // with a value of 'value' is specified - mockServer.expect().get().withPath("/api/v1/namespaces/test/services?labelSelector=label%3Dvalue").andReturn(200, new ServiceListBuilder() - .addNewItem() - .withNewMetadata() - .withName("s1") - .withLabels(new HashMap() {{ - put("label", "value") - }}) - .endMetadata() - .endItem() - .addNewItem() - .withNewMetadata() - .withName("s2") - .withLabels(new HashMap() {{ - put("label", "value") - put("label2", "value2") - }}) - .endMetadata() - .endItem() - .build()).once() + // this is the URL that is created by the KubernetesClient when a a label named 'label' + // with a value of 'value' is specified + mockServer.expect().get(). + withPath("/api/v1/namespaces/test/services?labelSelector=label%3Dvalue"). + andReturn(200, new ServiceListBuilder() + .addNewItem() + .withNewMetadata() + .withName("s1") + .withLabels(new HashMap() { + { + put("label", "value") + } + }) + .endMetadata() + .endItem() + .addNewItem() + .withNewMetadata() + .withName("s2") + .withLabels(new HashMap() { + { + put("label", "value") + put("label2", "value2") + } + }) + .endMetadata() + .endItem() + .build()).once() and: - DiscoveryClient discoveryClient = new KubernetesDiscoveryClient( - mockClient, - new KubernetesDiscoveryProperties(), {client -> client.services().withLabels(["label": "value"])}) + DiscoveryClient discoveryClient = new KubernetesDiscoveryClient( + mockClient, + new KubernetesDiscoveryProperties(), { client -> + client.services().withLabels(["label": "value"]) + }) when: - List instances = discoveryClient.getServices() + List instances = discoveryClient.getServices() then: - assertThat(instances).containsOnly("s1", "s2") + assertThat(instances).containsOnly("s1", "s2") } } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolverTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolverTest.java index bcb4b4d589..1adb5938b8 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolverTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/DefaultIsServicePortSecureResolverTest.java @@ -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. @@ -12,70 +12,74 @@ * 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.kubernetes.discovery; -import org.junit.Test; - import java.util.HashMap; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class DefaultIsServicePortSecureResolverTest { +import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +public class DefaultIsServicePortSecureResolverTest { @Test public void testPortNumbersOnly() { final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); properties.getKnownSecurePorts().add(12345); - final DefaultIsServicePortSecureResolver sut = new DefaultIsServicePortSecureResolver(properties); + final DefaultIsServicePortSecureResolver sut = new DefaultIsServicePortSecureResolver( + properties); - assertFalse(sut.resolve(new DefaultIsServicePortSecureResolver.Input(null, "dummy"))); - assertFalse(sut.resolve(new DefaultIsServicePortSecureResolver.Input(8080, "dummy"))); - assertFalse(sut.resolve(new DefaultIsServicePortSecureResolver.Input(1234, "dummy"))); + assertThat( + sut.resolve(new DefaultIsServicePortSecureResolver.Input(null, "dummy"))) + .isFalse(); + assertThat( + sut.resolve(new DefaultIsServicePortSecureResolver.Input(8080, "dummy"))) + .isFalse(); + assertThat( + sut.resolve(new DefaultIsServicePortSecureResolver.Input(1234, "dummy"))) + .isFalse(); - assertTrue(sut.resolve(new DefaultIsServicePortSecureResolver.Input(443, "dummy"))); - assertTrue(sut.resolve(new DefaultIsServicePortSecureResolver.Input(8443, "dummy"))); - assertTrue(sut.resolve(new DefaultIsServicePortSecureResolver.Input(12345, "dummy"))); + assertThat( + sut.resolve(new DefaultIsServicePortSecureResolver.Input(443, "dummy"))) + .isTrue(); + assertThat( + sut.resolve(new DefaultIsServicePortSecureResolver.Input(8443, "dummy"))) + .isTrue(); + assertThat( + sut.resolve(new DefaultIsServicePortSecureResolver.Input(12345, "dummy"))) + .isTrue(); } @Test public void testLabelsAndAnnotations() { - final DefaultIsServicePortSecureResolver sut - = new DefaultIsServicePortSecureResolver(new KubernetesDiscoveryProperties()); + final DefaultIsServicePortSecureResolver sut = new DefaultIsServicePortSecureResolver( + new KubernetesDiscoveryProperties()); - assertTrue(sut.resolve(new DefaultIsServicePortSecureResolver.Input( - 8080, - "dummy", - new HashMap() {{ - put("secured", "true"); - put("other", "value"); - }}, - new HashMap<>())) - ); - assertTrue(sut.resolve(new DefaultIsServicePortSecureResolver.Input( - 1234, - "dummy", - new HashMap() {{ - put("other", "value"); - put("secured", "1"); - }}, - new HashMap<>())) - ); - assertTrue(sut.resolve(new DefaultIsServicePortSecureResolver.Input( - 4321, - "dummy", - new HashMap<>(), - new HashMap() {{ - put("other1", "value1"); - put("secured", "yes"); - put("other2", "value2"); - }})) - ); + assertThat(sut.resolve(new DefaultIsServicePortSecureResolver.Input(8080, "dummy", + new HashMap() { + { + put("secured", "true"); + put("other", "value"); + } + }, new HashMap<>()))).isTrue(); + assertThat(sut.resolve(new DefaultIsServicePortSecureResolver.Input(1234, "dummy", + new HashMap() { + { + put("other", "value"); + put("secured", "1"); + } + }, new HashMap<>()))).isTrue(); + assertThat(sut.resolve(new DefaultIsServicePortSecureResolver.Input(4321, "dummy", + new HashMap<>(), new HashMap() { + { + put("other1", "value1"); + put("secured", "yes"); + put("other2", "value2"); + } + }))).isTrue(); } + } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchConfigurationTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchConfigurationTest.java index 719d0cbc79..04374a862d 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchConfigurationTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchConfigurationTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.discovery; @@ -20,6 +19,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import org.junit.After; import org.junit.Test; + import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -27,7 +27,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import static org.junit.Assert.*; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; /** @@ -47,31 +47,29 @@ public void close() { @Test public void kubernetesCatalogWatchDisabled() throws Exception { setup("spring.cloud.kubernetes.discovery.catalog-services-watch.enabled=false"); - assertFalse(context.containsBean("kubernetesCatalogWatch")); + assertThat(this.context.containsBean("kubernetesCatalogWatch")).isFalse(); } @Test public void kubernetesCatalogWatchWhenKubernetesDisabled() throws Exception { setup("spring.cloud.kubernetes.enabled=false"); - assertFalse(context.containsBean("kubernetesCatalogWatch")); + assertThat(this.context.containsBean("kubernetesCatalogWatch")).isFalse(); } - @Test public void kubernetesCatalogWatchDefaultEnabled() throws Exception { setup(); - assertTrue(context.containsBean("kubernetesCatalogWatch")); + assertThat(this.context.containsBean("kubernetesCatalogWatch")).isTrue(); } private void setup(String... env) { this.context = new SpringApplicationBuilder( - PropertyPlaceholderAutoConfiguration.class, - KubernetesClientTestConfiguration.class, - KubernetesDiscoveryClientAutoConfiguration.class).web(WebApplicationType.NONE) - .properties(env).run(); + PropertyPlaceholderAutoConfiguration.class, + KubernetesClientTestConfiguration.class, + KubernetesDiscoveryClientAutoConfiguration.class) + .web(WebApplicationType.NONE).properties(env).run(); } - @Configuration static class KubernetesClientTestConfiguration { @@ -80,6 +78,6 @@ KubernetesClient kubernetesClient() { return mock(KubernetesClient.class); } - } + } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java index 4ab34de940..f2fb86dc1a 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java @@ -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. @@ -12,12 +12,21 @@ * 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.kubernetes.discovery; -import io.fabric8.kubernetes.api.model.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import io.fabric8.kubernetes.api.model.DoneableEndpoints; +import io.fabric8.kubernetes.api.model.EndpointAddress; +import io.fabric8.kubernetes.api.model.EndpointSubset; +import io.fabric8.kubernetes.api.model.Endpoints; +import io.fabric8.kubernetes.api.model.EndpointsList; +import io.fabric8.kubernetes.api.model.ObjectReference; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; @@ -29,19 +38,15 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.cloud.client.discovery.event.HeartbeatEvent; import org.springframework.context.ApplicationEventPublisher; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - import static java.util.Arrays.stream; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * @author Oleg Vyukov @@ -66,52 +71,57 @@ public class KubernetesCatalogWatchTest { @Before public void setUp() throws Exception { - underTest.setApplicationEventPublisher(applicationEventPublisher); + this.underTest.setApplicationEventPublisher(this.applicationEventPublisher); } @Test public void testRandomOrderChangePods() throws Exception { - when(endpointsOperation.list()) - .thenReturn(createSingleEndpointEndpointListByPodName("api-pod", "other-pod")) - .thenReturn(createSingleEndpointEndpointListByPodName("other-pod", "api-pod")); - when(kubernetesClient.endpoints()).thenReturn(endpointsOperation); - - underTest.catalogServicesWatch(); + when(this.endpointsOperation.list()) + .thenReturn( + createSingleEndpointEndpointListByPodName("api-pod", "other-pod")) + .thenReturn(createSingleEndpointEndpointListByPodName("other-pod", + "api-pod")); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); // second execution on shuffleServices - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); - verify(applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); } @Test public void testRandomOrderChangeServices() throws Exception { - when(endpointsOperation.list()) - .thenReturn(createEndpointsListByServiceName("api-service", "other-service")) - .thenReturn(createEndpointsListByServiceName("other-service", "api-service")); - when(kubernetesClient.endpoints()).thenReturn(endpointsOperation); - - underTest.catalogServicesWatch(); + when(this.endpointsOperation.list()) + .thenReturn( + createEndpointsListByServiceName("api-service", "other-service")) + .thenReturn( + createEndpointsListByServiceName("other-service", "api-service")); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); // second execution on shuffleServices - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); - verify(applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); } @Test public void testEventBody() throws Exception { - when(endpointsOperation.list()) - .thenReturn(createSingleEndpointEndpointListByPodName("api-pod", "other-pod")); - when(kubernetesClient.endpoints()).thenReturn(endpointsOperation); + when(this.endpointsOperation.list()).thenReturn( + createSingleEndpointEndpointListByPodName("api-pod", "other-pod")); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); - verify(applicationEventPublisher).publishEvent(heartbeatEventArgumentCaptor.capture()); + verify(this.applicationEventPublisher) + .publishEvent(this.heartbeatEventArgumentCaptor.capture()); - HeartbeatEvent event = heartbeatEventArgumentCaptor.getValue(); - assertThat(event.getValue(), instanceOf(List.class)); + HeartbeatEvent event = this.heartbeatEventArgumentCaptor.getValue(); + assertThat(event.getValue()).isInstanceOf(List.class); List expectedPodsList = Arrays.asList("api-pod", "other-pod"); - assertEquals(expectedPodsList, event.getValue()); + assertThat(event.getValue()).isEqualTo(expectedPodsList); } @Test @@ -119,14 +129,14 @@ public void testEndpointsWithoutSubsets() { EndpointsList endpoints = createSingleEndpointEndpointListWithoutSubsets(); - when(endpointsOperation.list()).thenReturn(endpoints); - when(kubernetesClient.endpoints()).thenReturn(endpointsOperation); + when(this.endpointsOperation.list()).thenReturn(endpoints); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); // second execution on shuffleServices - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); - verify(applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); } @Test @@ -135,37 +145,37 @@ public void testEndpointsWithoutAddresses() { EndpointsList endpoints = createSingleEndpointEndpointListByPodName("api-pod"); endpoints.getItems().get(0).getSubsets().get(0).setAddresses(null); - when(endpointsOperation.list()).thenReturn(endpoints); - when(kubernetesClient.endpoints()).thenReturn(endpointsOperation); + when(this.endpointsOperation.list()).thenReturn(endpoints); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); // second execution on shuffleServices - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); - verify(applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); } @Test public void testEndpointsWithoutTargetRefs() { EndpointsList endpoints = createSingleEndpointEndpointListByPodName("api-pod"); - endpoints.getItems().get(0).getSubsets().get(0).getAddresses().get(0).setTargetRef(null); + endpoints.getItems().get(0).getSubsets().get(0).getAddresses().get(0) + .setTargetRef(null); - when(endpointsOperation.list()).thenReturn(endpoints); - when(kubernetesClient.endpoints()).thenReturn(endpointsOperation); + when(this.endpointsOperation.list()).thenReturn(endpoints); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); // second execution on shuffleServices - underTest.catalogServicesWatch(); + this.underTest.catalogServicesWatch(); - verify(applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); } - private EndpointsList createEndpointsListByServiceName(String... serviceNames) { List endpoints = stream(serviceNames) - .map(s -> createEndpointsByPodName(s + "-singlePodUniqueId")) - .collect(Collectors.toList()); + .map(s -> createEndpointsByPodName(s + "-singlePodUniqueId")) + .collect(Collectors.toList()); EndpointsList endpointsList = new EndpointsList(); endpointsList.setItems(endpoints); @@ -189,14 +199,12 @@ private EndpointsList createSingleEndpointEndpointListByPodName(String... podNam return endpointsList; } - private Endpoints createEndpointsByPodName(String podName) { Endpoints endpoints = new Endpoints(); endpoints.setSubsets(createSubsetsByPodName(podName)); return endpoints; } - private List createSubsetsByPodName(String... names) { EndpointSubset endpointSubset = new EndpointSubset(); endpointSubset.setAddresses(createEndpointAddressByPodNames(names)); @@ -213,5 +221,4 @@ private List createEndpointAddressByPodNames(String[] names) { }).collect(Collectors.toList()); } - } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationPropertiesTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationPropertiesTests.java index e26117293f..4c0de92732 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationPropertiesTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationPropertiesTests.java @@ -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.kubernetes.discovery; import io.fabric8.kubernetes.client.KubernetesClient; @@ -29,35 +45,35 @@ public void close() { @Test public void kubernetesDiscoveryDisabled() throws Exception { - setup("spring.cloud.kubernetes.discovery.enabled=false","spring.cloud.kubernetes.discovery.catalog-services-watch.enabled=false"); - assertThat(context.getBeanNamesForType(KubernetesDiscoveryClient.class)) - .isEmpty(); + setup("spring.cloud.kubernetes.discovery.enabled=false", + "spring.cloud.kubernetes.discovery.catalog-services-watch.enabled=false"); + assertThat(this.context.getBeanNamesForType(KubernetesDiscoveryClient.class)) + .isEmpty(); } @Test public void kubernetesDiscoveryWhenKubernetesDisabled() throws Exception { setup("spring.cloud.kubernetes.enabled=false"); - assertThat(context.getBeanNamesForType(KubernetesDiscoveryClient.class)) - .isEmpty(); + assertThat(this.context.getBeanNamesForType(KubernetesDiscoveryClient.class)) + .isEmpty(); } - @Test public void kubernetesDiscoveryDefaultEnabled() throws Exception { setup("spring.cloud.kubernetes.enabled=true"); - assertThat(context.getBeanNamesForType(KubernetesDiscoveryClient.class)) - .hasSize(1); + assertThat(this.context.getBeanNamesForType(KubernetesDiscoveryClient.class)) + .hasSize(1); } private void setup(String... env) { this.context = new SpringApplicationBuilder( - PropertyPlaceholderAutoConfiguration.class, - KubernetesClientTestConfiguration.class, - KubernetesDiscoveryClientAutoConfiguration.class).web(org.springframework.boot.WebApplicationType.NONE) - .properties(env).run(); + PropertyPlaceholderAutoConfiguration.class, + KubernetesClientTestConfiguration.class, + KubernetesDiscoveryClientAutoConfiguration.class) + .web(org.springframework.boot.WebApplicationType.NONE) + .properties(env).run(); } - @Configuration static class KubernetesClientTestConfiguration { @@ -66,6 +82,6 @@ KubernetesClient kubernetesClient() { return mock(KubernetesClient.class); } - } + } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java index 83576e7f5c..e89016aadf 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfigurationTests.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.discovery; @@ -40,15 +39,18 @@ public class KubernetesDiscoveryClientAutoConfigurationTests { @Test public void kubernetesDiscoveryClientCreated() { - assertThat(discoveryClient).isNotNull() - .isInstanceOf(CompositeDiscoveryClient.class); + assertThat(this.discoveryClient).isNotNull() + .isInstanceOf(CompositeDiscoveryClient.class); - CompositeDiscoveryClient composite = (CompositeDiscoveryClient) discoveryClient; + CompositeDiscoveryClient composite = (CompositeDiscoveryClient) this.discoveryClient; assertThat(composite.getDiscoveryClients().stream() - .anyMatch(dc -> dc instanceof KubernetesDiscoveryClient)).isTrue(); + .anyMatch(dc -> dc instanceof KubernetesDiscoveryClient)).isTrue(); } @SpringBootConfiguration @EnableAutoConfiguration - protected static class TestConfig {} + protected static class TestConfig { + + } + } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java index c62dafb2ed..eb18cc0fb0 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.discovery; import java.util.Collections; @@ -44,6 +44,7 @@ * @author Zhanwei Wang */ public class KubernetesDiscoveryClientConfigClientBootstrapConfigurationTests { + private AnnotationConfigApplicationContext context; @After @@ -59,17 +60,15 @@ public void close() { @Test public void onWhenRequested() throws Exception { setup("server.port=7000", "spring.cloud.config.discovery.enabled=true", - "spring.cloud.kubernetes.discovery.enabled:true", - "spring.cloud.kubernetes.enabled:true", - "spring.application.name:test", - "spring.cloud.config.discovery.service-id:configserver"); - assertEquals( 1, this.context.getParent() - .getBeanNamesForType(DiscoveryClient.class).length); - DiscoveryClient client = this.context.getParent().getBean( - DiscoveryClient.class); + "spring.cloud.kubernetes.discovery.enabled:true", + "spring.cloud.kubernetes.enabled:true", "spring.application.name:test", + "spring.cloud.config.discovery.service-id:configserver"); + assertEquals(1, this.context.getParent() + .getBeanNamesForType(DiscoveryClient.class).length); + DiscoveryClient client = this.context.getParent().getBean(DiscoveryClient.class); verify(client, atLeast(2)).getInstances("configserver"); ConfigClientProperties locator = this.context - .getBean(ConfigClientProperties.class); + .getBean(ConfigClientProperties.class); assertEquals("http://fake:8888/", locator.getUri()[0]); } @@ -77,16 +76,16 @@ private void setup(String... env) { AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); TestPropertyValues.of(env).applyTo(parent); parent.register(UtilAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, EnvironmentKnobbler.class, - KubernetesDiscoveryClientConfigClientBootstrapConfiguration.class, - DiscoveryClientConfigServiceBootstrapConfiguration.class, - ConfigClientProperties.class); + PropertyPlaceholderAutoConfiguration.class, EnvironmentKnobbler.class, + KubernetesDiscoveryClientConfigClientBootstrapConfiguration.class, + DiscoveryClientConfigServiceBootstrapConfiguration.class, + ConfigClientProperties.class); parent.refresh(); this.context = new AnnotationConfigApplicationContext(); this.context.setParent(parent); this.context.register(PropertyPlaceholderAutoConfiguration.class, - KubernetesAutoConfiguration.class, - KubernetesDiscoveryClientAutoConfiguration.class); + KubernetesAutoConfiguration.class, + KubernetesDiscoveryClientAutoConfiguration.class); this.context.refresh(); } @@ -97,10 +96,12 @@ protected static class EnvironmentKnobbler { public KubernetesDiscoveryClient kubernetesDiscoveryClient() { KubernetesDiscoveryClient client = mock(KubernetesDiscoveryClient.class); ServiceInstance instance = new DefaultServiceInstance("configserver1", - "configserver", "fake", 8888, false); + "configserver", "fake", 8888, false); given(client.getInstances("configserver")) - .willReturn(Collections.singletonList(instance)); + .willReturn(Collections.singletonList(instance)); return client; } + } + } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java index 74fa84c6e4..2874c012b9 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java @@ -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. @@ -12,10 +12,14 @@ * 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.kubernetes.discovery; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import io.fabric8.kubernetes.api.model.DoneableEndpoints; import io.fabric8.kubernetes.api.model.DoneableService; import io.fabric8.kubernetes.api.model.EndpointPort; @@ -38,11 +42,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import org.springframework.cloud.client.ServiceInstance; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import org.springframework.cloud.client.ServiceInstance; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; @@ -83,26 +84,28 @@ public class KubernetesDiscoveryClientFilterMetadataTest { public void testAllExtraMetadataDisabled() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(false); - when(metadata.isAddAnnotations()).thenReturn(false); - when(metadata.isAddPorts()).thenReturn(false); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "lab"); - }}, - new HashMap() {{ - put("l1", "lab"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }} - ); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(false); + when(this.metadata.isAddAnnotations()).thenReturn(false); + when(this.metadata.isAddPorts()).thenReturn(false); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "lab"); + } + }, new HashMap() { + { + put("l1", "lab"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); assertThat(instances.get(0).getMetadata()).isEmpty(); } @@ -111,144 +114,159 @@ public void testAllExtraMetadataDisabled() { public void testLabelsEnabled() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(true); - when(metadata.isAddAnnotations()).thenReturn(false); - when(metadata.isAddPorts()).thenReturn(false); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "v1"); - put("l2", "v2"); - }}, - new HashMap() {{ - put("l1", "lab"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }} - ); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(true); + when(this.metadata.isAddAnnotations()).thenReturn(false); + when(this.metadata.isAddPorts()).thenReturn(false); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "v1"); + put("l2", "v2"); + } + }, new HashMap() { + { + put("l1", "lab"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); - assertThat(instances.get(0).getMetadata()).containsOnly(entry("l1", "v1"), entry("l2", "v2")); + assertThat(instances.get(0).getMetadata()).containsOnly(entry("l1", "v1"), + entry("l2", "v2")); } @Test public void testLabelsEnabledWithPrefix() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(true); - when(metadata.getLabelsPrefix()).thenReturn("l_"); - when(metadata.isAddAnnotations()).thenReturn(false); - when(metadata.isAddPorts()).thenReturn(false); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "v1"); - put("l2", "v2"); - }}, - new HashMap() {{ - put("l1", "lab"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }}); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(true); + when(this.metadata.getLabelsPrefix()).thenReturn("l_"); + when(this.metadata.isAddAnnotations()).thenReturn(false); + when(this.metadata.isAddPorts()).thenReturn(false); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "v1"); + put("l2", "v2"); + } + }, new HashMap() { + { + put("l1", "lab"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); - assertThat(instances.get(0).getMetadata()).containsOnly(entry("l_l1", "v1"), entry("l_l2", "v2")); + assertThat(instances.get(0).getMetadata()).containsOnly(entry("l_l1", "v1"), + entry("l_l2", "v2")); } @Test public void testAnnotationsEnabled() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(false); - when(metadata.isAddAnnotations()).thenReturn(true); - when(metadata.isAddPorts()).thenReturn(false); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "v1"); - }}, - new HashMap() {{ - put("a1", "v1"); - put("a2", "v2"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }} - ); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(false); + when(this.metadata.isAddAnnotations()).thenReturn(true); + when(this.metadata.isAddPorts()).thenReturn(false); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "v1"); + } + }, new HashMap() { + { + put("a1", "v1"); + put("a2", "v2"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); - assertThat(instances.get(0).getMetadata()).containsOnly(entry("a1", "v1"), entry("a2", "v2")); + assertThat(instances.get(0).getMetadata()).containsOnly(entry("a1", "v1"), + entry("a2", "v2")); } @Test public void testAnnotationsEnabledWithPrefix() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(false); - when(metadata.isAddAnnotations()).thenReturn(true); - when(metadata.getAnnotationsPrefix()).thenReturn("a_"); - when(metadata.isAddPorts()).thenReturn(false); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "v1"); - }}, - new HashMap() {{ - put("a1", "v1"); - put("a2", "v2"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }} - ); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(false); + when(this.metadata.isAddAnnotations()).thenReturn(true); + when(this.metadata.getAnnotationsPrefix()).thenReturn("a_"); + when(this.metadata.isAddPorts()).thenReturn(false); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "v1"); + } + }, new HashMap() { + { + put("a1", "v1"); + put("a2", "v2"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); - assertThat(instances.get(0).getMetadata()).containsOnly(entry("a_a1", "v1"), entry("a_a2", "v2")); + assertThat(instances.get(0).getMetadata()).containsOnly(entry("a_a1", "v1"), + entry("a_a2", "v2")); } @Test public void testPortsEnabled() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(false); - when(metadata.isAddAnnotations()).thenReturn(false); - when(metadata.isAddPorts()).thenReturn(true); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "v1"); - }}, - new HashMap() {{ - put("a1", "v1"); - put("a2", "v2"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }} - ); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(false); + when(this.metadata.isAddAnnotations()).thenReturn(false); + when(this.metadata.isAddPorts()).thenReturn(true); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "v1"); + } + }, new HashMap() { + { + put("a1", "v1"); + put("a2", "v2"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); assertThat(instances.get(0).getMetadata()).containsOnly(entry("http", "80")); } @@ -257,28 +275,30 @@ public void testPortsEnabled() { public void testPortsEnabledWithPrefix() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(false); - when(metadata.isAddAnnotations()).thenReturn(false); - when(metadata.isAddPorts()).thenReturn(true); - when(metadata.getPortsPrefix()).thenReturn("p_"); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "v1"); - }}, - new HashMap() {{ - put("a1", "v1"); - put("a2", "v2"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }} - ); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(false); + when(this.metadata.isAddAnnotations()).thenReturn(false); + when(this.metadata.isAddPorts()).thenReturn(true); + when(this.metadata.getPortsPrefix()).thenReturn("p_"); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "v1"); + } + }, new HashMap() { + { + put("a1", "v1"); + put("a2", "v2"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); assertThat(instances.get(0).getMetadata()).containsOnly(entry("p_http", "80")); } @@ -287,90 +307,77 @@ public void testPortsEnabledWithPrefix() { public void testLabelsAndAnnotationsAndPortsEnabledWithPrefix() { final String serviceId = "s"; - when(properties.getMetadata()).thenReturn(metadata); - when(metadata.isAddLabels()).thenReturn(true); - when(metadata.getLabelsPrefix()).thenReturn("l_"); - when(metadata.isAddAnnotations()).thenReturn(true); - when(metadata.getAnnotationsPrefix()).thenReturn("a_"); - when(metadata.isAddPorts()).thenReturn(true); - when(metadata.getPortsPrefix()).thenReturn("p_"); - - setupServiceWithLabelsAndAnnotationsAndPorts( - serviceId, - new HashMap() {{ - put("l1", "la1"); - }}, - new HashMap() {{ - put("a1", "an1"); - put("a2", "an2"); - }}, - new HashMap() {{ - put(80, "http"); - put(5555, ""); - }} - ); - - final List instances = underTest.getInstances(serviceId); + when(this.properties.getMetadata()).thenReturn(this.metadata); + when(this.metadata.isAddLabels()).thenReturn(true); + when(this.metadata.getLabelsPrefix()).thenReturn("l_"); + when(this.metadata.isAddAnnotations()).thenReturn(true); + when(this.metadata.getAnnotationsPrefix()).thenReturn("a_"); + when(this.metadata.isAddPorts()).thenReturn(true); + when(this.metadata.getPortsPrefix()).thenReturn("p_"); + + setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, + new HashMap() { + { + put("l1", "la1"); + } + }, new HashMap() { + { + put("a1", "an1"); + put("a2", "an2"); + } + }, new HashMap() { + { + put(80, "http"); + put(5555, ""); + } + }); + + final List instances = this.underTest.getInstances(serviceId); assertThat(instances).hasSize(1); - assertThat(instances.get(0).getMetadata()).containsOnly( - entry("a_a1", "an1"), entry("a_a2", "an2"), entry("l_l1", "la1"), entry("p_http", "80")); + assertThat(instances.get(0).getMetadata()).containsOnly(entry("a_a1", "an1"), + entry("a_a2", "an2"), entry("l_l1", "la1"), entry("p_http", "80")); } private void setupServiceWithLabelsAndAnnotationsAndPorts(String serviceId, - Map labels, Map annotations, Map ports) { - final Service service = - new ServiceBuilder() - .withNewMetadata() - .withLabels(labels) - .withAnnotations(annotations) - .endMetadata() - .withNewSpec() - .withPorts(getServicePorts(ports)) - .endSpec() - .build(); - when(serviceOperation.withName(serviceId)).thenReturn(serviceResource); - when(serviceResource.get()).thenReturn(service); - when(kubernetesClient.services()).thenReturn(serviceOperation); - - final Endpoints endpoints = - new EndpointsBuilder() - .addNewSubset() - .addAllToPorts(getEndpointPorts(ports)) - .addNewAddress() - .endAddress() - .endSubset() - .build(); - - when(endpointsResource.get()).thenReturn(endpoints); - when(endpointsOperation.withName(serviceId)).thenReturn(endpointsResource); - when(kubernetesClient.endpoints()).thenReturn(endpointsOperation); + Map labels, Map annotations, + Map ports) { + final Service service = new ServiceBuilder().withNewMetadata().withLabels(labels) + .withAnnotations(annotations).endMetadata().withNewSpec() + .withPorts(getServicePorts(ports)).endSpec().build(); + when(this.serviceOperation.withName(serviceId)).thenReturn(this.serviceResource); + when(this.serviceResource.get()).thenReturn(service); + when(this.kubernetesClient.services()).thenReturn(this.serviceOperation); + + final Endpoints endpoints = new EndpointsBuilder().addNewSubset() + .addAllToPorts(getEndpointPorts(ports)).addNewAddress().endAddress() + .endSubset().build(); + + when(this.endpointsResource.get()).thenReturn(endpoints); + when(this.endpointsOperation.withName(serviceId)) + .thenReturn(this.endpointsResource); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); } private List getServicePorts(Map ports) { - return ports.entrySet().stream() - .map(e -> { - ServicePortBuilder servicePortBuilder = new ServicePortBuilder(); - servicePortBuilder.withPort(e.getKey()); - if (!Strings.isNullOrEmpty(e.getValue())) { - servicePortBuilder.withName(e.getValue()); - } - return servicePortBuilder.build(); - }) - .collect(toList()); + return ports.entrySet().stream().map(e -> { + ServicePortBuilder servicePortBuilder = new ServicePortBuilder(); + servicePortBuilder.withPort(e.getKey()); + if (!Strings.isNullOrEmpty(e.getValue())) { + servicePortBuilder.withName(e.getValue()); + } + return servicePortBuilder.build(); + }).collect(toList()); } private List getEndpointPorts(Map ports) { - return ports.entrySet().stream() - .map(e -> { - EndpointPortBuilder endpointPortBuilder = new EndpointPortBuilder(); - endpointPortBuilder.withPort(e.getKey()); - if (!Strings.isNullOrEmpty(e.getValue())) { - endpointPortBuilder.withName(e.getValue()); - } - return endpointPortBuilder.build(); - }) - .collect(toList()); + return ports.entrySet().stream().map(e -> { + EndpointPortBuilder endpointPortBuilder = new EndpointPortBuilder(); + endpointPortBuilder.withPort(e.getKey()); + if (!Strings.isNullOrEmpty(e.getValue())) { + endpointPortBuilder.withName(e.getValue()); + } + return endpointPortBuilder.build(); + }).collect(toList()); } - } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterTest.java index 2936a88bb7..955f5e638a 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterTest.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.discovery; import java.util.ArrayList; @@ -30,13 +30,10 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) @@ -57,7 +54,8 @@ public class KubernetesDiscoveryClientFilterTest { @Before public void setUp() { - underTest = new KubernetesDiscoveryClient(kubernetesClient, properties, kubernetesClientServicesFunction); + this.underTest = new KubernetesDiscoveryClient(this.kubernetesClient, + this.properties, this.kubernetesClientServicesFunction); } @Test @@ -74,22 +72,23 @@ public void testFilteredServices() { ServiceList serviceList = new ServiceList(); serviceList.setItems(services); - when(serviceOperation.list()) - .thenReturn(serviceList); - when(kubernetesClient.services()).thenReturn(serviceOperation); + when(this.serviceOperation.list()).thenReturn(serviceList); + when(this.kubernetesClient.services()).thenReturn(this.serviceOperation); - when(properties.getFilter()).thenReturn("metadata.additionalProperties['spring-boot']"); + when(this.properties.getFilter()) + .thenReturn("metadata.additionalProperties['spring-boot']"); - List filteredServices = underTest.getServices(); + List filteredServices = this.underTest.getServices(); System.out.println("Filtered Services: " + filteredServices); - assertEquals(springBootServiceNames, filteredServices); + assertThat(filteredServices).isEqualTo(springBootServiceNames); } @Test public void testFilteredServicesByPrefix() { - List springBootServiceNames = Arrays.asList("serviceA", "serviceB", "serviceC"); + List springBootServiceNames = Arrays.asList("serviceA", "serviceB", + "serviceC"); List services = createSpringBootServiceByName(springBootServiceNames); // Add non spring boot service @@ -101,36 +100,36 @@ public void testFilteredServicesByPrefix() { ServiceList serviceList = new ServiceList(); serviceList.setItems(services); - when(serviceOperation.list()) - .thenReturn(serviceList); - when(kubernetesClient.services()).thenReturn(serviceOperation); + when(this.serviceOperation.list()).thenReturn(serviceList); + when(this.kubernetesClient.services()).thenReturn(this.serviceOperation); - when(properties.getFilter()).thenReturn("metadata.name.startsWith('service')"); + when(this.properties.getFilter()) + .thenReturn("metadata.name.startsWith('service')"); - List filteredServices = underTest.getServices(); + List filteredServices = this.underTest.getServices(); System.out.println("Filtered Services: " + filteredServices); - assertEquals(springBootServiceNames, filteredServices); + assertThat(filteredServices).isEqualTo(springBootServiceNames); } @Test public void testNoExpression() { - List springBootServiceNames = Arrays.asList("serviceA", "serviceB", "serviceC"); + List springBootServiceNames = Arrays.asList("serviceA", "serviceB", + "serviceC"); List services = createSpringBootServiceByName(springBootServiceNames); ServiceList serviceList = new ServiceList(); serviceList.setItems(services); - when(serviceOperation.list()) - .thenReturn(serviceList); - when(kubernetesClient.services()).thenReturn(serviceOperation); + when(this.serviceOperation.list()).thenReturn(serviceList); + when(this.kubernetesClient.services()).thenReturn(this.serviceOperation); - when(properties.getFilter()).thenReturn(""); + when(this.properties.getFilter()).thenReturn(""); - List filteredServices = underTest.getServices(); + List filteredServices = this.underTest.getServices(); System.out.println("Filtered Services: " + filteredServices); - assertEquals(springBootServiceNames, filteredServices); + assertThat(filteredServices).isEqualTo(springBootServiceNames); } diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml index 855328074e..3b95487973 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml @@ -16,58 +16,58 @@ ~ --> - - 4.0.0 - - org.springframework.cloud - kubernetes-circuitbreaker-ribbon-example - 1.0.1.BUILD-SNAPSHOT - + + 4.0.0 + + org.springframework.cloud + kubernetes-circuitbreaker-ribbon-example + 1.0.1.BUILD-SNAPSHOT + - greeting-service - Circuit Breaker & Load Balancer :: Greeting Service - Circuit Breaker & Load Balancer :: Greeting Service + greeting-service + Circuit Breaker & Load Balancer :: Greeting Service + Circuit Breaker & Load Balancer :: Greeting Service - - - - org.apache.maven.plugins - maven-deploy-plugin - ${maven-deploy-plugin.version} - - true - - - - + + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + true + + + + - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - - - org.springframework.cloud - spring-cloud-starter-kubernetes-ribbon - - - com.squareup.okhttp3 - okhttp - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-netflix-ribbon + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + + + org.springframework.cloud + spring-cloud-starter-kubernetes-ribbon + + + com.squareup.okhttp3 + okhttp + - + diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingController.java b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingController.java index 5aa0ada3df..9cd2be615d 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingController.java +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingController.java @@ -35,18 +35,20 @@ public GreetingController(NameService nameService) { } /** - * Endpoint to get a greeting. This endpoint uses a name server to get a name for the greeting. + * Endpoint to get a greeting. This endpoint uses a name server to get a name for the + * greeting. * - * Request to the name service is guarded with a circuit breaker. Therefore if a name service is not available or is too - * slow to response fallback name is used. + * Request to the name service is guarded with a circuit breaker. Therefore if a name + * service is not available or is too slow to response fallback name is used. * * Delay parameter can me used to make name service response slower. - * - * @param delay Milliseconds for how long the response from name service should be delayed. + * @param delay Milliseconds for how long the response from name service should be + * delayed. * @return Greeting string. */ @RequestMapping("/greeting") - public String getGreeting(@RequestParam(value = "delay", defaultValue = "0") int delay) { + public String getGreeting( + @RequestParam(value = "delay", defaultValue = "0") int delay) { return String.format("Hello from %s!", this.nameService.getName(delay)); } diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingServiceApplication.java b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingServiceApplication.java index e9b717f9a3..63d5a9355d 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingServiceApplication.java +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/GreetingServiceApplication.java @@ -47,4 +47,3 @@ RestTemplate restTemplate() { } } - diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameService.java b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameService.java index c458521343..3959016876 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameService.java +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameService.java @@ -37,10 +37,10 @@ public NameService(RestTemplate restTemplate) { } @HystrixCommand(fallbackMethod = "getFallbackName", commandProperties = { - @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") - }) + @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }) public String getName(int delay) { - return this.restTemplate.getForObject(String.format("http://name-service/name?delay=%d", delay), String.class); + return this.restTemplate.getForObject( + String.format("http://name-service/name?delay=%d", delay), String.class); } private String getFallbackName(int delay) { diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/RibbonConfiguration.java b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/RibbonConfiguration.java index 27d537c802..c4d24757e1 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/RibbonConfiguration.java +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/java/org/springframework/cloud/kubernetes/examples/RibbonConfiguration.java @@ -36,10 +36,10 @@ public class RibbonConfiguration { IClientConfig ribbonClientConfig; /** - * PingUrl will ping a URL to check the status of each server. - * Say Hello has, as you’ll recall, a method mapped to the /path; that means that Ribbon will get an HTTP 200 response when it pings a running Backend Server - * - * @param config Client configuration + * PingUrl will ping a URL to check the status of each server. Say Hello has, as + * you’ll recall, a method mapped to the /path; that means that Ribbon will get an + * HTTP 200 response when it pings a running Backend Server + * @param config Client configuration * @return The URL to be used for the Ping */ @Bean @@ -48,14 +48,16 @@ public IPing ribbonPing(IClientConfig config) { } /** - * AvailabilityFilteringRule will use Ribbon’s built-in circuit breaker functionality to filter out any servers in an “open-circuit” state: - * if a ping fails to connect to a given server, or if it gets a read failure for the server, Ribbon will consider that server “dead” until it begins to respond normally. - * - * @param config Client configuration + * AvailabilityFilteringRule will use Ribbon’s built-in circuit breaker functionality + * to filter out any servers in an “open-circuit” state: if a ping fails to connect to + * a given server, or if it gets a read failure for the server, Ribbon will consider + * that server “dead” until it begins to respond normally. + * @param config Client configuration * @return The Load Balancer rule */ @Bean public IRule ribbonRule(IClientConfig config) { return new AvailabilityFilteringRule(); } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/resources/application.yml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/resources/application.yml index 5017c76697..83f34e7e4e 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/resources/application.yml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/src/main/resources/application.yml @@ -10,7 +10,7 @@ backend: eureka: enabled: false client: - enabled: true + enabled: true ServerListRefreshInterval: 5000 hystrix.command.BackendCall.execution.isolation.thread.timeoutInMilliseconds: 5000 diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml index 07933ab5f5..1dcfe1e415 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml @@ -16,42 +16,42 @@ ~ --> - - 4.0.0 - - org.springframework.cloud - kubernetes-circuitbreaker-ribbon-example - 1.0.1.BUILD-SNAPSHOT - + + 4.0.0 + + org.springframework.cloud + kubernetes-circuitbreaker-ribbon-example + 1.0.1.BUILD-SNAPSHOT + - name-service + name-service - Circuit Breaker & Load Balancer :: Name Service - Circuit Breaker & Load Balancer :: Name Service + Circuit Breaker & Load Balancer :: Name Service + Circuit Breaker & Load Balancer :: Name Service - - - - org.apache.maven.plugins - maven-deploy-plugin - ${maven-deploy-plugin.version} - - true - - - - + + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + true + + + + - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameController.java b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameController.java index 4672b96cf8..0f7e0b8a10 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameController.java +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameController.java @@ -42,14 +42,16 @@ public String ribbonPing() { } /** - * Endpoint to get a name with a capability to delay a response for some number of milliseconds. - * + * Endpoint to get a name with a capability to delay a response for some number of + * milliseconds. * @param delayValue Milliseconds for how long the response should be delayed. * @return Host name. */ @RequestMapping("/name") - public String getName(@RequestParam(value = "delay", defaultValue = "0") int delayValue) { - LOG.info(String.format("Returning a name '%s' with a delay '%d'", this.hostName, delayValue)); + public String getName( + @RequestParam(value = "delay", defaultValue = "0") int delayValue) { + LOG.info(String.format("Returning a name '%s' with a delay '%d'", this.hostName, + delayValue)); delay(delayValue); return this.hostName; } @@ -62,4 +64,5 @@ private void delay(int delayValue) { e.printStackTrace(); } } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameServiceApplication.java b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameServiceApplication.java index 5bb4f56f6e..e264da19b6 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameServiceApplication.java +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/src/main/java/org/springframework/cloud/kubernetes/examples/NameServiceApplication.java @@ -26,7 +26,9 @@ */ @SpringBootApplication public class NameServiceApplication { + public static void main(String[] args) { SpringApplication.run(NameServiceApplication.class, args); } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml index fe9a3c0ea4..60bf42573c 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml @@ -16,8 +16,8 @@ ~ --> - 4.0.0 @@ -35,7 +35,7 @@ name-service greeting-service - + diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml index b850294a44..bc0f124214 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml @@ -1,6 +1,6 @@ - spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java index c359877cd7..60340d9d52 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.examples; import org.springframework.boot.SpringApplication; @@ -30,4 +30,5 @@ public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java index 0a032f3783..9a7d5d957b 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.examples; @@ -21,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; @@ -43,4 +43,5 @@ public String hello() { public List services() { return this.discoveryClient.getServices(); } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/ApplicationTestIT.java b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/ApplicationTestIT.java index dbc33d793e..8e07a3432d 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/ApplicationTestIT.java +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/ApplicationTestIT.java @@ -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. @@ -12,19 +12,19 @@ * 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.kubernetes.examples; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit4.SpringRunner; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) @@ -39,6 +39,7 @@ public class ApplicationTestIT { */ @Test public void contextLoads() throws Exception { - assertThat(context).isNotNull(); + assertThat(this.context).isNotNull(); } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/resources/logback-test.xml index 60916e947b..13a928a183 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/resources/logback-test.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/resources/logback-test.xml @@ -8,9 +8,10 @@ - - + + - + diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index 75df7e4534..ccb7663c72 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 @@ -11,7 +11,8 @@ kubernetes-leader-election-example Spring Cloud Kubernetes :: Examples :: Leader Election - Leader election demonstration with Spring Integration and ConfigMap + Leader election demonstration with Spring Integration and ConfigMap + diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/rb.yaml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/rb.yaml index 3aa757461b..f3646344de 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/rb.yaml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/rb.yaml @@ -8,6 +8,6 @@ roleRef: kind: Role name: leader subjects: -- kind: ServiceAccount - name: default - namespace: default + - kind: ServiceAccount + name: default + namespace: default diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/role.yaml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/role.yaml index 988a9f002d..3f15dd3be7 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/role.yaml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/fabric8/role.yaml @@ -4,9 +4,9 @@ metadata: name: leader namespace: default rules: -- apiGroups: - resources: - - pods - - configmaps - verbs: - - "*" + - apiGroups: + resources: + - pods + - configmaps + verbs: + - "*" diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java index 87a1c73317..db04f84be1 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 to the original authors. + * Copyright 2018-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 + * 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, diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/LeaderController.java b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/LeaderController.java index d8943d8bae..d610e951ef 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/LeaderController.java +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/main/java/org/springframework/cloud/kubernetes/examples/LeaderController.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 to the original 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -45,61 +45,58 @@ public LeaderController() throws UnknownHostException { /** * Return a message whether this instance is a leader or not. - * - * @return + * @return info */ @GetMapping public String getInfo() { - if (context == null) { - return String.format("I am '%s' but I am not a leader of the '%s'", host, role); + if (this.context == null) { + return String.format("I am '%s' but I am not a leader of the '%s'", this.host, + this.role); } - return String.format("I am '%s' and I am the leader of the '%s'", host, role); + return String.format("I am '%s' and I am the leader of the '%s'", this.host, + this.role); } /** - * PUT request to try and revoke a leadership of this instance. - * If the instance is not a leader, leadership cannot be revoked. Thus "HTTP Bad Request" response. - * If the instance is a leader, it must have a leadership context instance which can be used to give up the - * leadership. - * - * @return + * PUT request to try and revoke a leadership of this instance. If the instance is not + * a leader, leadership cannot be revoked. Thus "HTTP Bad Request" response. If the + * instance is a leader, it must have a leadership context instance which can be used + * to give up the leadership. + * @return info about leadership */ @PutMapping public ResponseEntity revokeLeadership() { - if (context == null) { - String message = String.format("Cannot revoke leadership because '%s' is not a leader", host); - return ResponseEntity - .badRequest() - .body(message); + if (this.context == null) { + String message = String.format( + "Cannot revoke leadership because '%s' is not a leader", this.host); + return ResponseEntity.badRequest().body(message); } - context.yield(); + this.context.yield(); - String message = String.format("Leadership revoked for '%s'", host); - return ResponseEntity - .ok(message); + String message = String.format("Leadership revoked for '%s'", this.host); + return ResponseEntity.ok(message); } /** * Handle a notification that this instance has become a leader. - * - * @param event + * @param event on granted event */ @EventListener public void handleEvent(OnGrantedEvent event) { System.out.println(String.format("'%s' leadership granted", event.getRole())); - context = event.getContext(); + this.context = event.getContext(); } /** * Handle a notification that this instance's leadership has been revoked. - * - * @param event + * @param event on revoked event */ @EventListener public void handleEvent(OnRevokedEvent event) { System.out.println(String.format("'%s' leadership revoked", event.getRole())); - context = null; + this.context = null; } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java index 7ce0ebc792..b1e6bfac06 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java @@ -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.kubernetes.examples; import java.net.InetAddress; @@ -8,6 +24,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.integration.leader.Context; @@ -37,58 +54,62 @@ public class LeaderControllerTest { @Before public void before() throws UnknownHostException { - host = InetAddress.getLocalHost().getHostName(); - leaderController = new LeaderController(); + this.host = InetAddress.getLocalHost().getHostName(); + this.leaderController = new LeaderController(); } @Test public void shouldGetNonLeaderInfo() { - String message = String.format("I am '%s' but I am not a leader of the 'null'", host); - assertThat(leaderController.getInfo()).isEqualTo(message); + String message = String.format("I am '%s' but I am not a leader of the 'null'", + this.host); + assertThat(this.leaderController.getInfo()).isEqualTo(message); } @Test public void shouldHandleGrantedEvent() { - given(mockOnGrantedEvent.getContext()).willReturn(mockContext); + given(this.mockOnGrantedEvent.getContext()).willReturn(this.mockContext); - leaderController.handleEvent(mockOnGrantedEvent); + this.leaderController.handleEvent(this.mockOnGrantedEvent); - String message = String.format("I am '%s' and I am the leader of the 'null'", host); - assertThat(leaderController.getInfo()).isEqualTo(message); + String message = String.format("I am '%s' and I am the leader of the 'null'", + this.host); + assertThat(this.leaderController.getInfo()).isEqualTo(message); } @Test public void shouldHandleRevokedEvent() { - given(mockOnGrantedEvent.getContext()).willReturn(mockContext); + given(this.mockOnGrantedEvent.getContext()).willReturn(this.mockContext); - leaderController.handleEvent(mockOnGrantedEvent); - leaderController.handleEvent(mockOnRevokedEvent); + this.leaderController.handleEvent(this.mockOnGrantedEvent); + this.leaderController.handleEvent(this.mockOnRevokedEvent); - String message = String.format("I am '%s' but I am not a leader of the 'null'", host); - assertThat(leaderController.getInfo()).isEqualTo(message); + String message = String.format("I am '%s' but I am not a leader of the 'null'", + this.host); + assertThat(this.leaderController.getInfo()).isEqualTo(message); } @Test public void shouldRevokeLeadership() { - given(mockOnGrantedEvent.getContext()).willReturn(mockContext); + given(this.mockOnGrantedEvent.getContext()).willReturn(this.mockContext); - leaderController.handleEvent(mockOnGrantedEvent); - ResponseEntity responseEntity = leaderController.revokeLeadership(); + this.leaderController.handleEvent(this.mockOnGrantedEvent); + ResponseEntity responseEntity = this.leaderController.revokeLeadership(); - String message = String.format("Leadership revoked for '%s'", host); + String message = String.format("Leadership revoked for '%s'", this.host); assertThat(responseEntity.getBody()).isEqualTo(message); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); - verify(mockContext).yield(); + verify(this.mockContext).yield(); } @Test public void shouldNotRevokeLeadershipIfNotLeader() { - ResponseEntity responseEntity = leaderController.revokeLeadership(); + ResponseEntity responseEntity = this.leaderController.revokeLeadership(); - String message = String.format("Cannot revoke leadership because '%s' is not a leader", host); + String message = String.format( + "Cannot revoke leadership because '%s' is not a leader", this.host); assertThat(responseEntity.getBody()).isEqualTo(message); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - verify(mockContext, times(0)).yield(); + verify(this.mockContext, times(0)).yield(); } } diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml index 11aa6cf1da..d78b454d5b 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml @@ -16,8 +16,8 @@ ~ --> - spring-cloud-kubernetes-examples @@ -29,7 +29,8 @@ spring-cloud-kubernetes-example-reload Spring Cloud Kubernetes :: Examples :: Reload ConfigMap - Example demonstrating how to use the configuration reload feature. + Example demonstrating how to use the configuration reload feature. + diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java index 72cbf22858..b4d7065605 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java @@ -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. @@ -12,17 +12,14 @@ * 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.kubernetes.examples; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; -/** - * - */ @SpringBootApplication @EnableScheduling public class App { diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/DummyConfig.java b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/DummyConfig.java index f396517214..84eb4b4b0b 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/DummyConfig.java +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/DummyConfig.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.examples; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -26,7 +26,7 @@ public class DummyConfig { private String message = "this is a dummy message"; public String getMessage() { - return message; + return this.message; } public void setMessage(String message) { diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyBean.java b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyBean.java index 8271f1400c..09538a0874 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyBean.java +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyBean.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.examples; import org.springframework.beans.factory.annotation.Autowired; @@ -31,9 +31,8 @@ public class MyBean { @Scheduled(fixedDelay = 5000) public void hello() { - System.out.println("The first message is: " + myConfig.getMessage()); - System.out.println("The other message is: " + dummyConfig.getMessage()); + System.out.println("The first message is: " + this.myConfig.getMessage()); + System.out.println("The other message is: " + this.dummyConfig.getMessage()); } - } diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyConfig.java b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyConfig.java index eb219ba720..34b11ac46b 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyConfig.java +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/MyConfig.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.examples; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -26,7 +26,7 @@ public class MyConfig { private String message = "a message that can be changed live"; public String getMessage() { - return message; + return this.message; } public void setMessage(String message) { diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/logback.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/logback.xml index 5fa4e753f2..aa0ff5ab93 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/logback.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/logback.xml @@ -1,6 +1,7 @@ - - - + + + diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/old-application.properties b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/old-application.properties index e45b7c66ae..6fea4d14a0 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/old-application.properties +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/old-application.properties @@ -3,7 +3,6 @@ management.endpoint.health.enabled=true management.endpoint.info.enabled=true management.endpoint.restart.enabled=true spring.cloud.kubernetes.reload.enabled=true - #spring.cloud.kubernetes.reload.strategy=restart_context #spring.cloud.kubernetes.reload.mode=polling #spring.cloud.kubernetes.reload.period=5000 diff --git a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml index ea96c8e65f..b46204eaaa 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml @@ -16,8 +16,8 @@ ~ --> - spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/TraceController.java b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/TraceController.java index 9afef855f3..3b60a71d42 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/TraceController.java +++ b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/TraceController.java @@ -21,9 +21,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; -import org.springframework.cloud.sleuth.SpanAccessor; import org.springframework.cloud.sleuth.Tracer; import org.springframework.context.ApplicationListener; import org.springframework.web.bind.annotation.RequestMapping; @@ -31,25 +31,28 @@ import org.springframework.web.client.RestTemplate; @RestController -public class TraceController implements -ApplicationListener { +public class TraceController + implements ApplicationListener { private static final Log log = LogFactory.getLog(TraceController.class); @Autowired private RestTemplate restTemplate; + @Autowired private Tracer tracer; + @Autowired private Random random; + private int port; @RequestMapping("/") public String say() throws InterruptedException { Thread.sleep(this.random.nextInt(1000)); log.info("Home"); - String s = this.restTemplate.getForObject("http://localhost:" + this.port - + "/hi", String.class); + String s = this.restTemplate.getForObject("http://localhost:" + this.port + "/hi", + String.class); return "hi/" + s; } @@ -66,4 +69,5 @@ public String hi() throws InterruptedException { public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) { this.port = event.getEmbeddedServletContainer().getPort(); } + } diff --git a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/ZipkinApplication.java b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/ZipkinApplication.java index 980115efe9..b36ab01c95 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/ZipkinApplication.java +++ b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/src/main/java/org/springframework/cloud/kubernetes/examples/ZipkinApplication.java @@ -19,10 +19,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.sleuth.zipkin.ZipkinSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.scheduling.annotation.EnableAsync; diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml index 88f1369fcd..da73a35c5c 100644 --- a/spring-cloud-kubernetes-examples/pom.xml +++ b/spring-cloud-kubernetes-examples/pom.xml @@ -16,8 +16,8 @@ ~ --> - 4.0.0 @@ -30,7 +30,8 @@ pom Spring Cloud Kubernetes :: Examples - Examples showing how to use features of Spring Cloud Kubernetes. + Examples showing how to use features of Spring Cloud Kubernetes. + kubernetes-reload-example diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml index f3713c3fa5..d3183db9b0 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml @@ -1,31 +1,31 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - discovery-parent - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + discovery-parent + 1.0.1.BUILD-SNAPSHOT + - discovery-client - Spring Cloud Kubernetes :: Integration Tests :: Discovery Client + discovery-client + Spring Cloud Kubernetes :: Integration Tests :: Discovery Client - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-kubernetes-discovery - - - - \ No newline at end of file + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-kubernetes-discovery + + + + diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/fabric8/deployment.yml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/fabric8/deployment.yml index 3c8b53a3f7..f40eb7e97f 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/fabric8/deployment.yml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/fabric8/deployment.yml @@ -5,6 +5,6 @@ spec: spec: containers: - env: - - name: KUBERNETES_TRUST_CERTIFICATES - value: true + - name: KUBERNETES_TRUST_CERTIFICATES + value: true diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/java/org/springframework/cloud/kubernetes/it/DiscoveryClientApplication.java b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/java/org/springframework/cloud/kubernetes/it/DiscoveryClientApplication.java index d7ce6f62b6..d1ebbbbef4 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/java/org/springframework/cloud/kubernetes/it/DiscoveryClientApplication.java +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/src/main/java/org/springframework/cloud/kubernetes/it/DiscoveryClientApplication.java @@ -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. @@ -12,11 +12,12 @@ * 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.kubernetes.it; +import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -24,21 +25,20 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @SpringBootApplication @RestController public class DiscoveryClientApplication { - @Autowired - private DiscoveryClient discoveryClient; + @Autowired + private DiscoveryClient discoveryClient; + + public static void main(String[] args) { + SpringApplication.run(DiscoveryClientApplication.class, args); + } - @GetMapping("/services") - public List services() { - return discoveryClient.getServices(); - } + @GetMapping("/services") + public List services() { + return this.discoveryClient.getServices(); + } - public static void main(String[] args) { - SpringApplication.run(DiscoveryClientApplication.class, args); - } } diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml index 6ebf5b7ed2..f48bb3925e 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml @@ -1,29 +1,28 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - discovery-parent - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + discovery-parent + 1.0.1.BUILD-SNAPSHOT + - discovery-service-a - Spring Cloud Kubernetes :: Integration Tests :: Discovery Service A + discovery-service-a + Spring Cloud Kubernetes :: Integration Tests :: Discovery Service A - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + - - \ No newline at end of file + diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java index 526ff32e9d..fa2af6e9a5 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.it; @@ -26,25 +25,27 @@ @RestController public class SimpleSpringBootApplication { - @GetMapping("/greeting") - public Greeting home() { - return new Greeting("Hello from Service A"); - } + public static void main(String[] args) { + SpringApplication.run(SimpleSpringBootApplication.class, args); + } + + @GetMapping("/greeting") + public Greeting home() { + return new Greeting("Hello from Service A"); + } + + public static class Greeting { - public static void main(String[] args) { - SpringApplication.run(SimpleSpringBootApplication.class, args); - } + private final String message; - public static class Greeting { + public Greeting(String message) { + this.message = message; + } - private final String message; + public String getMessage() { + return this.message; + } - public Greeting(String message) { - this.message = message; - } + } - public String getMessage() { - return message; - } - } } diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml index 8bd4e290a9..a9b237a27c 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml @@ -1,28 +1,28 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - discovery-parent - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + discovery-parent + 1.0.1.BUILD-SNAPSHOT + - discovery-service-b - Spring Cloud Kubernetes :: Integration Tests :: Discovery Service B + discovery-service-b + Spring Cloud Kubernetes :: Integration Tests :: Discovery Service B - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + - - \ No newline at end of file + + diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java index e09bcaa7dd..6d3d259039 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/src/main/java/org/springframework/cloud/kubernetes/it/SimpleSpringBootApplication.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.it; @@ -26,25 +25,27 @@ @RestController public class SimpleSpringBootApplication { - @GetMapping("/greeting") - public Greeting home() { - return new Greeting("Hello from Service B"); - } + public static void main(String[] args) { + SpringApplication.run(SimpleSpringBootApplication.class, args); + } + + @GetMapping("/greeting") + public Greeting home() { + return new Greeting("Hello from Service B"); + } + + public static class Greeting { - public static void main(String[] args) { - SpringApplication.run(SimpleSpringBootApplication.class, args); - } + private final String message; - public static class Greeting { + public Greeting(String message) { + this.message = message; + } - private final String message; + public String getMessage() { + return this.message; + } - public Greeting(String message) { - this.message = message; - } + } - public String getMessage() { - return message; - } - } } diff --git a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml index 561f2eb270..a0ff74ab31 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml @@ -1,26 +1,25 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - spring-cloud-kubernetes-integration-tests - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 1.0.1.BUILD-SNAPSHOT + - Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent - discovery-parent - pom + Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent + discovery-parent + pom - - discovery-service-a - discovery-service-b - discovery-client - tests - + + discovery-service-a + discovery-service-b + discovery-client + tests + - - \ No newline at end of file + diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index c502853cec..c69f76a4f6 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -1,115 +1,115 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - discovery-parent - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + discovery-parent + 1.0.1.BUILD-SNAPSHOT + - tests - Spring Cloud Kubernetes :: Integration Tests :: Discovery Tests + tests + Spring Cloud Kubernetes :: Integration Tests :: Discovery Tests - - - org.springframework.boot - spring-boot-starter-test - test - - - org.arquillian.cube - arquillian-cube-kubernetes - ${arquillian-cube.version} - test - - - undertow-core - io.undertow - - - - - org.jboss.arquillian.junit - arquillian-junit-standalone - test - - - io.rest-assured - rest-assured - test - - - + + + org.springframework.boot + spring-boot-starter-test + test + + + org.arquillian.cube + arquillian-cube-kubernetes + ${arquillian-cube.version} + test + + + undertow-core + io.undertow + + + + + org.jboss.arquillian.junit + arquillian-junit-standalone + test + + + io.rest-assured + rest-assured + test + - - - - - org.springframework.boot - spring-boot-maven-plugin - - true - - - - io.fabric8 - fabric8-maven-plugin - - true - - - - + - - - it - - - - io.fabric8 - fabric8-maven-plugin - - false - aggregate - - - - - org.springframework.cloud - discovery-client - ${project.version} - - - org.springframework.cloud - discovery-service-a - ${project.version} - - - org.springframework.cloud - discovery-service-b - ${project.version} - - - - javax.validation - validation-api - 2.0.1.Final - - - - - - - + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + io.fabric8 + fabric8-maven-plugin + + true + + + + - \ No newline at end of file + + + it + + + + io.fabric8 + fabric8-maven-plugin + + false + aggregate + + + + + org.springframework.cloud + discovery-client + ${project.version} + + + org.springframework.cloud + discovery-service-a + ${project.version} + + + org.springframework.cloud + discovery-service-b + ${project.version} + + + + javax.validation + validation-api + 2.0.1.Final + + + + + + + + + diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/java/org/springframework/cloud/kubernetes/it/ServicesIT.java b/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/java/org/springframework/cloud/kubernetes/it/ServicesIT.java index 2f897e568e..3d5314e11f 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/java/org/springframework/cloud/kubernetes/it/ServicesIT.java +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/java/org/springframework/cloud/kubernetes/it/ServicesIT.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.it; @@ -30,21 +29,19 @@ public class ServicesIT { private static final String HOST = System.getProperty("service.host"); - private static final Integer PORT = Integer.valueOf(System.getProperty("service.port")); + + private static final Integer PORT = Integer + .valueOf(System.getProperty("service.port")); @Test public void testServicesEndpoint() { - given() - .baseUri(String.format("http://%s:%d", HOST, PORT)) - .get("services") - .then() - .statusCode(200) - .body(new StringContains("service-a") { - @Override - protected boolean evalSubstringOf(String s) { - return s.contains("service-a") && s.contains("service-b"); - } - }); + given().baseUri(String.format("http://%s:%d", HOST, PORT)).get("services").then() + .statusCode(200).body(new StringContains("service-a") { + @Override + protected boolean evalSubstringOf(String s) { + return s.contains("service-a") && s.contains("service-b"); + } + }); } } diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/resources/arquillian.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/resources/arquillian.xml index 0eb7aad11d..9d588056ef 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/resources/arquillian.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/src/test/resources/arquillian.xml @@ -1,9 +1,9 @@ + xmlns="http://jboss.org/schema/arquillian" + xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> - - default - + + default + diff --git a/spring-cloud-kubernetes-integration-tests/istio/pom.xml b/spring-cloud-kubernetes-integration-tests/istio/pom.xml index e33bf317b2..ab2a2238b8 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/istio/pom.xml @@ -1,17 +1,17 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - spring-cloud-kubernetes-integration-tests - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 1.0.1.BUILD-SNAPSHOT + Spring Cloud Kubernetes :: Integration Tests :: Istio - istio + istio jar diff --git a/spring-cloud-kubernetes-integration-tests/istio/src/main/fabric8/deployment.yml b/spring-cloud-kubernetes-integration-tests/istio/src/main/fabric8/deployment.yml index 3c8b53a3f7..f40eb7e97f 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/src/main/fabric8/deployment.yml +++ b/spring-cloud-kubernetes-integration-tests/istio/src/main/fabric8/deployment.yml @@ -5,6 +5,6 @@ spec: spec: containers: - env: - - name: KUBERNETES_TRUST_CERTIFICATES - value: true + - name: KUBERNETES_TRUST_CERTIFICATES + value: true diff --git a/spring-cloud-kubernetes-integration-tests/istio/src/main/java/org/springframework/cloud/kubernetes/it/IstioApplication.java b/spring-cloud-kubernetes-integration-tests/istio/src/main/java/org/springframework/cloud/kubernetes/it/IstioApplication.java index e154535847..9eb5993820 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/src/main/java/org/springframework/cloud/kubernetes/it/IstioApplication.java +++ b/spring-cloud-kubernetes-integration-tests/istio/src/main/java/org/springframework/cloud/kubernetes/it/IstioApplication.java @@ -1,6 +1,26 @@ +/* + * 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.kubernetes.it; +import java.util.Arrays; +import java.util.List; + import me.snowdrop.istio.client.IstioClient; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -8,27 +28,24 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.Arrays; -import java.util.List; - @SpringBootApplication @RestController public class IstioApplication { - @Autowired - private Environment environment; + @Autowired + private Environment environment; - // used just to ensure that the IstioClient is properly injected into the context - @Autowired - private IstioClient istioClient; - - @GetMapping("/profiles") - public List profiles() { - return Arrays.asList(environment.getActiveProfiles()); - } + // used just to ensure that the IstioClient is properly injected into the context + @Autowired + private IstioClient istioClient; public static void main(String[] args) { SpringApplication.run(IstioApplication.class, args); } + @GetMapping("/profiles") + public List profiles() { + return Arrays.asList(this.environment.getActiveProfiles()); + } + } diff --git a/spring-cloud-kubernetes-integration-tests/istio/src/test/java/org/springframework/cloud/kubernetes/it/ProfilesIT.java b/spring-cloud-kubernetes-integration-tests/istio/src/test/java/org/springframework/cloud/kubernetes/it/ProfilesIT.java index 1575893a33..e23062c6d7 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/src/test/java/org/springframework/cloud/kubernetes/it/ProfilesIT.java +++ b/spring-cloud-kubernetes-integration-tests/istio/src/test/java/org/springframework/cloud/kubernetes/it/ProfilesIT.java @@ -1,6 +1,20 @@ -package org.springframework.cloud.kubernetes.it; +/* + * 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 io.restassured.RestAssured.given; +package org.springframework.cloud.kubernetes.it; import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes; import org.hamcrest.core.StringContains; @@ -8,21 +22,21 @@ import org.junit.Test; import org.junit.runner.RunWith; +import static io.restassured.RestAssured.given; + @RequiresKubernetes @RunWith(Arquillian.class) public class ProfilesIT { private static final String HOST = System.getProperty("service.host"); - private static final Integer PORT = Integer.valueOf(System.getProperty("service.port")); + + private static final Integer PORT = Integer + .valueOf(System.getProperty("service.port")); @Test public void testProfileEndpoint() { - given() - .baseUri(String.format("http://%s:%d", HOST, PORT)) - .get("profiles") - .then() - .statusCode(200) - .body(new StringContains("istio")); + given().baseUri(String.format("http://%s:%d", HOST, PORT)).get("profiles").then() + .statusCode(200).body(new StringContains("istio")); } } diff --git a/spring-cloud-kubernetes-integration-tests/istio/src/test/resources/arquillian.xml b/spring-cloud-kubernetes-integration-tests/istio/src/test/resources/arquillian.xml index 315c6d10e6..58f2aae06e 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/src/test/resources/arquillian.xml +++ b/spring-cloud-kubernetes-integration-tests/istio/src/test/resources/arquillian.xml @@ -1,9 +1,9 @@ + xmlns="http://jboss.org/schema/arquillian" + xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> - - istio-test - + + istio-test + diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index b174f9752c..9b4d8d3f65 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -1,7 +1,7 @@ - + 4.0.0 org.springframework.cloud @@ -13,7 +13,8 @@ pom Spring Cloud Kubernetes :: Integration Tests - Integration tests where SCK applications are run inside a Kubernetes cluster + Integration tests where SCK applications are run inside a Kubernetes + cluster @@ -92,7 +93,8 @@ localhost ${nodeport.value} - ${project.build.outputDirectory} + ${project.build.outputDirectory} + @@ -129,7 +131,7 @@ simple-core simple-configmap istio - discovery + discovery diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index 8ea3a0742f..0ed5ab0cfb 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -1,18 +1,18 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - spring-cloud-kubernetes-integration-tests - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 1.0.1.BUILD-SNAPSHOT + Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap - simple-configmap - jar + simple-configmap + jar diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/fabric8/deployment.yml b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/fabric8/deployment.yml index 3c8b53a3f7..f40eb7e97f 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/fabric8/deployment.yml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/fabric8/deployment.yml @@ -5,6 +5,6 @@ spec: spec: containers: - env: - - name: KUBERNETES_TRUST_CERTIFICATES - value: true + - name: KUBERNETES_TRUST_CERTIFICATES + value: true diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/DummyConfig.java b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/DummyConfig.java index 1aec26a2f1..1c1e4b4f43 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/DummyConfig.java +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/DummyConfig.java @@ -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. @@ -12,8 +12,8 @@ * 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.kubernetes.it; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -24,7 +24,7 @@ public class DummyConfig { private String message = "This is a dummy message"; public String getMessage() { - return message; + return this.message; } public void setMessage(String message) { diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/SimpleConfigMapApplication.java b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/SimpleConfigMapApplication.java index 62a29a85f2..c288e3304a 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/SimpleConfigMapApplication.java +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/main/java/org/springframework/cloud/kubernetes/it/SimpleConfigMapApplication.java @@ -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.kubernetes.it; import org.springframework.beans.factory.annotation.Autowired; @@ -15,15 +31,15 @@ public class SimpleConfigMapApplication { @Autowired private DummyConfig dummyConfig; - @GetMapping("/greeting") - public Greeting greeting() { - return new Greeting(dummyConfig.getMessage()); - } - public static void main(String[] args) { SpringApplication.run(SimpleConfigMapApplication.class, args); } + @GetMapping("/greeting") + public Greeting greeting() { + return new Greeting(this.dummyConfig.getMessage()); + } + public static class Greeting { private final String message; @@ -33,8 +49,9 @@ public Greeting(String message) { } public String getMessage() { - return message; + return this.message; } + } } diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/java/org/springframework/cloud/kubernetes/it/GreetingIT.java b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/java/org/springframework/cloud/kubernetes/it/GreetingIT.java index e56f16d20a..6e46eba838 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/java/org/springframework/cloud/kubernetes/it/GreetingIT.java +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/java/org/springframework/cloud/kubernetes/it/GreetingIT.java @@ -1,7 +1,20 @@ -package org.springframework.cloud.kubernetes.it; +/* + * 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 io.restassured.RestAssured.given; -import static org.hamcrest.core.Is.is; +package org.springframework.cloud.kubernetes.it; import org.arquillian.cube.kubernetes.annotations.KubernetesResource; import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes; @@ -11,22 +24,23 @@ import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; +import static io.restassured.RestAssured.given; +import static org.hamcrest.core.Is.is; + @RequiresKubernetes @RunWith(Arquillian.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class GreetingIT { private static final String HOST = System.getProperty("service.host"); - private static final Integer PORT = Integer.valueOf(System.getProperty("service.port")); + + private static final Integer PORT = Integer + .valueOf(System.getProperty("service.port")); @Test public void firstTestThatTheDefaultMessageIsReturned() { - given() - .baseUri(String.format("http://%s:%d", HOST, PORT)) - .get("greeting") - .then() - .statusCode(200) - .body("message", is("This is a dummy message")); + given().baseUri(String.format("http://%s:%d", HOST, PORT)).get("greeting").then() + .statusCode(200).body("message", is("This is a dummy message")); } @Test @@ -34,18 +48,16 @@ public void firstTestThatTheDefaultMessageIsReturned() { public void thenApplyAConfigMapAndEnsureThatTheMessageIsUpdated() { waitForApplicationToReload(); - given() - .baseUri(String.format("http://%s:%d", HOST, PORT)) - .get("greeting") - .then() - .statusCode(200) - .body("message", is("Hello from Spring Cloud Kubernetes!")); + given().baseUri(String.format("http://%s:%d", HOST, PORT)).get("greeting").then() + .statusCode(200) + .body("message", is("Hello from Spring Cloud Kubernetes!")); } private void waitForApplicationToReload() { try { Thread.sleep(15000); - } catch (InterruptedException e) { + } + catch (InterruptedException e) { } } diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/arquillian.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/arquillian.xml index 0eb7aad11d..9d588056ef 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/arquillian.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/arquillian.xml @@ -1,9 +1,9 @@ + xmlns="http://jboss.org/schema/arquillian" + xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> - - default - + + default + diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/logback-test.xml index 9f754ed5a1..358256d985 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/logback-test.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/src/test/resources/logback-test.xml @@ -1,5 +1,6 @@ - - - \ No newline at end of file + + + diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index f4f7742d18..4a9add6fd0 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -1,17 +1,17 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.cloud - spring-cloud-kubernetes-integration-tests - 1.0.1.BUILD-SNAPSHOT - + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 1.0.1.BUILD-SNAPSHOT + Spring Cloud Kubernetes :: Integration Tests :: Simple Core - simple-core + simple-core jar diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/src/main/fabric8/deployment.yml b/spring-cloud-kubernetes-integration-tests/simple-core/src/main/fabric8/deployment.yml index 3c8b53a3f7..f40eb7e97f 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/src/main/fabric8/deployment.yml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/src/main/fabric8/deployment.yml @@ -5,6 +5,6 @@ spec: spec: containers: - env: - - name: KUBERNETES_TRUST_CERTIFICATES - value: true + - name: KUBERNETES_TRUST_CERTIFICATES + value: true diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/src/main/java/org/springframework/cloud/kubernetes/it/SimpleCoreApplication.java b/spring-cloud-kubernetes-integration-tests/simple-core/src/main/java/org/springframework/cloud/kubernetes/it/SimpleCoreApplication.java index 0e4a9bea8f..442cc45354 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/src/main/java/org/springframework/cloud/kubernetes/it/SimpleCoreApplication.java +++ b/spring-cloud-kubernetes-integration-tests/simple-core/src/main/java/org/springframework/cloud/kubernetes/it/SimpleCoreApplication.java @@ -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.kubernetes.it; import org.springframework.boot.SpringApplication; @@ -9,15 +25,15 @@ @RestController public class SimpleCoreApplication { + public static void main(String[] args) { + SpringApplication.run(SimpleCoreApplication.class, args); + } + @GetMapping("/greeting") public Greeting home() { return new Greeting("Hello Spring Boot"); } - public static void main(String[] args) { - SpringApplication.run(SimpleCoreApplication.class, args); - } - public static class Greeting { private final String message; @@ -27,8 +43,9 @@ public Greeting(String message) { } public String getMessage() { - return message; + return this.message; } + } } diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/src/test/java/org/springframework/cloud/kubernetes/it/GreetingAndHealthIT.java b/spring-cloud-kubernetes-integration-tests/simple-core/src/test/java/org/springframework/cloud/kubernetes/it/GreetingAndHealthIT.java index 8dc3da57f2..0fcf97d104 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/src/test/java/org/springframework/cloud/kubernetes/it/GreetingAndHealthIT.java +++ b/spring-cloud-kubernetes-integration-tests/simple-core/src/test/java/org/springframework/cloud/kubernetes/it/GreetingAndHealthIT.java @@ -1,39 +1,49 @@ -package org.springframework.cloud.kubernetes.it; +/* + * 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 io.restassured.RestAssured.given; -import static org.hamcrest.core.Is.is; +package org.springframework.cloud.kubernetes.it; import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes; import org.jboss.arquillian.junit.Arquillian; import org.junit.Test; import org.junit.runner.RunWith; +import static io.restassured.RestAssured.given; +import static org.hamcrest.core.Is.is; + @RequiresKubernetes @RunWith(Arquillian.class) public class GreetingAndHealthIT { private static final String HOST = System.getProperty("service.host"); - private static final Integer PORT = Integer.valueOf(System.getProperty("service.port")); + + private static final Integer PORT = Integer + .valueOf(System.getProperty("service.port")); @Test public void testGreetingEndpoint() { - given() - .baseUri(String.format("http://%s:%d", HOST, PORT)) - .get("greeting") - .then() - .statusCode(200) - .body("message", is("Hello Spring Boot")); + given().baseUri(String.format("http://%s:%d", HOST, PORT)).get("greeting").then() + .statusCode(200).body("message", is("Hello Spring Boot")); } @Test public void testHealthEndpoint() { - given() - .baseUri(String.format("http://%s:%d", HOST, PORT)) - .contentType("application/json") - .get("actuator/health") - .then() - .statusCode(200) - .body("details.kubernetes.details.inside", is(true)); + given().baseUri(String.format("http://%s:%d", HOST, PORT)) + .contentType("application/json").get("actuator/health").then() + .statusCode(200).body("details.kubernetes.details.inside", is(true)); } } diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/arquillian.xml b/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/arquillian.xml index 0eb7aad11d..9d588056ef 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/arquillian.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/arquillian.xml @@ -1,9 +1,9 @@ + xmlns="http://jboss.org/schema/arquillian" + xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> - - default - + + default + diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/logback-test.xml index 9f754ed5a1..358256d985 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/logback-test.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/src/test/resources/logback-test.xml @@ -1,5 +1,6 @@ - - - \ No newline at end of file + + + diff --git a/spring-cloud-kubernetes-istio/pom.xml b/spring-cloud-kubernetes-istio/pom.xml index 88be96f31c..d6afdfe80e 100644 --- a/spring-cloud-kubernetes-istio/pom.xml +++ b/spring-cloud-kubernetes-istio/pom.xml @@ -1,6 +1,6 @@ - spring-cloud-kubernetes @@ -10,7 +10,7 @@ 4.0.0 spring-cloud-kubernetes-istio - Spring Cloud Kubernetes :: Istio + Spring Cloud Kubernetes :: Istio diff --git a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioAutoConfiguration.java b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioAutoConfiguration.java index b248124ad7..4b029eaa37 100644 --- a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioAutoConfiguration.java +++ b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioAutoConfiguration.java @@ -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. @@ -12,25 +12,32 @@ * 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.kubernetes.istio; import io.fabric8.kubernetes.client.Config; import me.snowdrop.istio.client.DefaultIstioClient; import me.snowdrop.istio.client.IstioClient; + import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +/** + * Auto configration for Istio. + * + * @author Mauricio Salatino + */ @Configuration @ConditionalOnProperty(value = "spring.cloud.istio.enabled", matchIfMissing = true) public class IstioAutoConfiguration { - @Bean - @ConditionalOnMissingBean - public IstioClient istioClient(Config config) { - return new DefaultIstioClient(config); - } + @Bean + @ConditionalOnMissingBean + public IstioClient istioClient(Config config) { + return new DefaultIstioClient(config); + } + } diff --git a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioBootstrapConfiguration.java b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioBootstrapConfiguration.java index e09ece03cf..b0efa549a5 100644 --- a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioBootstrapConfiguration.java +++ b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioBootstrapConfiguration.java @@ -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. @@ -12,12 +12,17 @@ * 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.kubernetes.istio; +import java.util.Arrays; + +import javax.annotation.PostConstruct; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -26,9 +31,12 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; -import javax.annotation.PostConstruct; -import java.util.Arrays; +/** + * Auto configuration for Istio bootstrap. + * + * @author Mauricio Salatino + */ @Configuration @ConditionalOnProperty(value = "spring.cloud.istio.enabled", matchIfMissing = true) @EnableConfigurationProperties(IstioClientProperties.class) @@ -49,42 +57,46 @@ protected static class IstioDetectionConfiguration { private final MeshUtils utils; - private final ConfigurableEnvironment environment; - public IstioDetectionConfiguration(MeshUtils utils, ConfigurableEnvironment environment) { + public IstioDetectionConfiguration(MeshUtils utils, + ConfigurableEnvironment environment) { this.utils = utils; this.environment = environment; } @PostConstruct public void detectIstio() { - addIstioProfile(environment); + addIstioProfile(this.environment); } void addIstioProfile(ConfigurableEnvironment environment) { - if (utils.isIstioEnabled()) { + if (this.utils.isIstioEnabled()) { if (hasIstioProfile(environment)) { if (LOG.isDebugEnabled()) { LOG.debug("'istio' already in list of active profiles"); } - } else { + } + else { if (LOG.isDebugEnabled()) { LOG.debug("Adding 'istio' to list of active profiles"); } environment.addActiveProfile(ISTIO_PROFILE); } - } else { + } + else { if (LOG.isDebugEnabled()) { - LOG.debug("Not running inside kubernetes with istio enabled. Skipping 'istio' profile activation."); + LOG.debug( + "Not running inside kubernetes with istio enabled. Skipping 'istio' profile activation."); } } } private boolean hasIstioProfile(Environment environment) { - return Arrays.stream(environment.getActiveProfiles()).anyMatch(ISTIO_PROFILE::equalsIgnoreCase); + return Arrays.stream(environment.getActiveProfiles()) + .anyMatch(ISTIO_PROFILE::equalsIgnoreCase); } - } + } } diff --git a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioClientProperties.java b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioClientProperties.java index 14b513fa63..77ecf6e2b4 100644 --- a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioClientProperties.java +++ b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/IstioClientProperties.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.istio; @@ -20,15 +19,21 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +/** + * Istio client properties. + * + * @author Mauricio Salatino + */ @Configuration @ConfigurationProperties("spring.cloud.istio.client") public class IstioClientProperties { private Integer envoyPort = 15090; + private String testPath = "stats/prometheus"; public Integer getEnvoyPort() { - return envoyPort; + return this.envoyPort; } public void setEnvoyPort(Integer envoyPort) { @@ -36,10 +41,11 @@ public void setEnvoyPort(Integer envoyPort) { } public String getTestPath() { - return testPath; + return this.testPath; } public void setTestPath(String testPath) { this.testPath = testPath; } + } diff --git a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/utils/MeshUtils.java b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/utils/MeshUtils.java index 740ffa073e..f26258b35d 100644 --- a/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/utils/MeshUtils.java +++ b/spring-cloud-kubernetes-istio/src/main/java/org/springframework/cloud/kubernetes/istio/utils/MeshUtils.java @@ -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. @@ -12,21 +12,25 @@ * 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.kubernetes.istio.utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.kubernetes.istio.IstioClientProperties; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; +/** + * Utility class to work with meshes. + * + * @author Mauricio Salatino + */ public class MeshUtils { - private static final Log LOG = LogFactory.getLog(MeshUtils.class); private final IstioClientProperties istioClientProperties; @@ -43,24 +47,33 @@ public Boolean isIstioEnabled() { private synchronized boolean checkIstioServices() { try { - //Check if Istio Envoy proxy is installed. Notice that the check is done to localhost. + // Check if Istio Envoy proxy is installed. Notice that the check is done to + // localhost. // TODO: We can improve this initial detection if better methods are found. - String resource = "http://localhost:" + istioClientProperties.getEnvoyPort(); - ResponseEntity response = restTemplate.getForEntity(resource + "/" + istioClientProperties.getTestPath(), String.class); + String resource = "http://localhost:" + + this.istioClientProperties.getEnvoyPort(); + ResponseEntity response = this.restTemplate.getForEntity( + resource + "/" + this.istioClientProperties.getTestPath(), + String.class); if (response.getStatusCode().is2xxSuccessful()) { LOG.info("Istio Resources Found."); return true; } - LOG.warn("Although Envoy proxy did respond at port" + istioClientProperties.getEnvoyPort() + - ", it did not respond with HTTP 200 to path: " + istioClientProperties.getTestPath() + - ". You may need to tweak the test path in order to get proper Istio support"); + LOG.warn("Although Envoy proxy did respond at port" + + this.istioClientProperties.getEnvoyPort() + + ", it did not respond with HTTP 200 to path: " + + this.istioClientProperties.getTestPath() + + ". You may need to tweak the test path in order to get proper Istio support"); return false; - } catch (Throwable t) { + } + catch (Throwable t) { if (LOG.isDebugEnabled()) { - LOG.debug("Envoy proxy could not be located at port: " + istioClientProperties.getEnvoyPort() + - ". Assuming that the application is not running inside the Istio Service Mesh"); + LOG.debug("Envoy proxy could not be located at port: " + + this.istioClientProperties.getEnvoyPort() + + ". Assuming that the application is not running inside the Istio Service Mesh"); } return false; } } + } diff --git a/spring-cloud-kubernetes-istio/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-istio/src/main/resources/META-INF/spring.factories index d3d14ce3bf..f16342d2c6 100644 --- a/spring-cloud-kubernetes-istio/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-kubernetes-istio/src/main/resources/META-INF/spring.factories @@ -1,5 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.kubernetes.istio.IstioAutoConfiguration - org.springframework.cloud.bootstrap.BootstrapConfiguration=\ org.springframework.cloud.kubernetes.istio.IstioBootstrapConfiguration diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index 6bbd512ab4..a4874046b3 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -15,8 +15,8 @@ ~ limitations under the License. ~ --> - 4.0.0 diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/Leader.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/Leader.java index ff1bcb325f..89771e6e78 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/Leader.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/Leader.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -36,11 +35,11 @@ public Leader(String role, String id) { } public String getRole() { - return role; + return this.role; } public String getId() { - return id; + return this.id; } public boolean isCandidate(Candidate candidate) { @@ -48,7 +47,8 @@ public boolean isCandidate(Candidate candidate) { return false; } - return Objects.equals(role, candidate.getRole()) && Objects.equals(id, candidate.getId()); + return Objects.equals(this.role, candidate.getRole()) + && Objects.equals(this.id, candidate.getId()); } @Override @@ -63,17 +63,18 @@ public boolean equals(Object o) { Leader leader = (Leader) o; - return Objects.equals(role, leader.role) && Objects.equals(id, leader.id); + return Objects.equals(this.role, leader.role) + && Objects.equals(this.id, leader.id); } @Override public int hashCode() { - return Objects.hash(role, id); + return Objects.hash(this.role, this.id); } @Override public String toString() { - return String.format("Leader{role='%s', id='%s'}", role, id); + return String.format("Leader{role='%s', id='%s'}", this.role, this.id); } } diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfiguration.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfiguration.java index 3242eb6955..7687e13a5d 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfiguration.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfiguration.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -21,6 +20,7 @@ import java.net.UnknownHostException; import io.fabric8.kubernetes.client.KubernetesClient; + import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -44,12 +44,14 @@ public class LeaderAutoConfiguration { @Bean @ConditionalOnMissingBean(LeaderEventPublisher.class) - public LeaderEventPublisher defaultLeaderEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + public LeaderEventPublisher defaultLeaderEventPublisher( + ApplicationEventPublisher applicationEventPublisher) { return new DefaultLeaderEventPublisher(applicationEventPublisher); } @Bean - public Candidate candidate(LeaderProperties leaderProperties) throws UnknownHostException { + public Candidate candidate(LeaderProperties leaderProperties) + throws UnknownHostException { String id = Inet4Address.getLocalHost().getHostName(); String role = leaderProperties.getRole(); @@ -57,26 +59,35 @@ public Candidate candidate(LeaderProperties leaderProperties) throws UnknownHost } @Bean - public LeadershipController leadershipController(Candidate candidate, LeaderProperties leaderProperties, - LeaderEventPublisher leaderEventPublisher, KubernetesClient kubernetesClient) { - return new LeadershipController(candidate, leaderProperties, leaderEventPublisher, kubernetesClient); + public LeadershipController leadershipController(Candidate candidate, + LeaderProperties leaderProperties, LeaderEventPublisher leaderEventPublisher, + KubernetesClient kubernetesClient) { + return new LeadershipController(candidate, leaderProperties, leaderEventPublisher, + kubernetesClient); } @Bean public LeaderRecordWatcher leaderRecordWatcher(LeaderProperties leaderProperties, - LeadershipController leadershipController, KubernetesClient kubernetesClient) { - return new LeaderRecordWatcher(leaderProperties, leadershipController, kubernetesClient); + LeadershipController leadershipController, + KubernetesClient kubernetesClient) { + return new LeaderRecordWatcher(leaderProperties, leadershipController, + kubernetesClient); } @Bean - public PodReadinessWatcher hostPodWatcher(Candidate candidate, KubernetesClient kubernetesClient, - LeadershipController leadershipController) { - return new PodReadinessWatcher(candidate.getId(), kubernetesClient, leadershipController); + public PodReadinessWatcher hostPodWatcher(Candidate candidate, + KubernetesClient kubernetesClient, + LeadershipController leadershipController) { + return new PodReadinessWatcher(candidate.getId(), kubernetesClient, + leadershipController); } @Bean(destroyMethod = "stop") - public LeaderInitiator leaderInitiator(LeaderProperties leaderProperties, LeadershipController leadershipController, - LeaderRecordWatcher leaderRecordWatcher, PodReadinessWatcher hostPodWatcher) { - return new LeaderInitiator(leaderProperties, leadershipController, leaderRecordWatcher, hostPodWatcher); + public LeaderInitiator leaderInitiator(LeaderProperties leaderProperties, + LeadershipController leadershipController, + LeaderRecordWatcher leaderRecordWatcher, PodReadinessWatcher hostPodWatcher) { + return new LeaderInitiator(leaderProperties, leadershipController, + leaderRecordWatcher, hostPodWatcher); } + } diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderContext.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderContext.java index 44ba849231..09e2d45bb7 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderContext.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderContext.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -36,15 +35,13 @@ public LeaderContext(Candidate candidate, LeadershipController leadershipControl @Override public boolean isLeader() { - return leadershipController - .getLocalLeader() - .filter(l -> l.isCandidate(candidate)) - .isPresent(); + return this.leadershipController.getLocalLeader() + .filter(l -> l.isCandidate(this.candidate)).isPresent(); } @Override public void yield() { - leadershipController.revoke(); + this.leadershipController.revoke(); } } diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderInitiator.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderInitiator.java index 29bdd51ce3..3cf8100a00 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderInitiator.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderInitiator.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -23,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.context.SmartLifecycle; /** @@ -44,8 +44,9 @@ public class LeaderInitiator implements SmartLifecycle { private boolean isRunning; - public LeaderInitiator(LeaderProperties leaderProperties, LeadershipController leadershipController, - LeaderRecordWatcher leaderRecordWatcher, PodReadinessWatcher hostPodWatcher) { + public LeaderInitiator(LeaderProperties leaderProperties, + LeadershipController leadershipController, + LeaderRecordWatcher leaderRecordWatcher, PodReadinessWatcher hostPodWatcher) { this.leaderProperties = leaderProperties; this.leadershipController = leadershipController; this.leaderRecordWatcher = leaderRecordWatcher; @@ -54,19 +55,22 @@ public LeaderInitiator(LeaderProperties leaderProperties, LeadershipController l @Override public boolean isAutoStartup() { - return leaderProperties.isAutoStartup(); + return this.leaderProperties.isAutoStartup(); } @Override public void start() { if (!isRunning()) { LOGGER.debug("Leader initiator starting"); - leaderRecordWatcher.start(); - hostPodWatcher.start(); - scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); - scheduledExecutorService.scheduleAtFixedRate(leadershipController::update, - leaderProperties.getUpdatePeriod().toMillis(), leaderProperties.getUpdatePeriod().toMillis(), TimeUnit.MILLISECONDS); - isRunning = true; + this.leaderRecordWatcher.start(); + this.hostPodWatcher.start(); + this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + this.scheduledExecutorService.scheduleAtFixedRate( + this.leadershipController::update, + this.leaderProperties.getUpdatePeriod().toMillis(), + this.leaderProperties.getUpdatePeriod().toMillis(), + TimeUnit.MILLISECONDS); + this.isRunning = true; } } @@ -74,12 +78,12 @@ public void start() { public void stop() { if (isRunning()) { LOGGER.debug("Leader initiator stopping"); - scheduledExecutorService.shutdown(); - scheduledExecutorService = null; - hostPodWatcher.stop(); - leaderRecordWatcher.stop(); - leadershipController.revoke(); - isRunning = false; + this.scheduledExecutorService.shutdown(); + this.scheduledExecutorService = null; + this.hostPodWatcher.stop(); + this.leaderRecordWatcher.stop(); + this.leadershipController.revoke(); + this.isRunning = false; } } @@ -91,11 +95,12 @@ public void stop(Runnable callback) { @Override public boolean isRunning() { - return isRunning; + return this.isRunning; } @Override public int getPhase() { return 0; } + } diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderProperties.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderProperties.java index 1846d5df24..92e985ba63 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderProperties.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderProperties.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -40,14 +39,12 @@ public class LeaderProperties { private static final boolean DEFAULT_PUBLISH_FAILED_EVENTS = false; /** - * Should leader election be enabled. - * Default: true + * Should leader election be enabled. Default: true */ private boolean enabled = DEFAULT_ENABLED; /** - * Should leader election be started automatically on startup. - * Default: true + * Should leader election be started automatically on startup. Default: true */ private boolean autoStartup = DEFAULT_AUTO_STARTUP; @@ -62,31 +59,28 @@ public class LeaderProperties { private String namespace; /** - * Kubernetes ConfigMap where leaders information will be stored. - * Default: leaders + * Kubernetes ConfigMap where leaders information will be stored. Default: leaders */ private String configMapName = DEFAULT_CONFIG_MAP_NAME; /** - * Leader id property prefix for the ConfigMap. - * Default: leader.id. + * Leader id property prefix for the ConfigMap. Default: leader.id. */ private String leaderIdPrefix = DEFAULT_LEADER_ID_PREFIX; /** - * Leadership status check period. - * Default: 60s + * Leadership status check period. Default: 60s */ private Duration updatePeriod = DEFAULT_UPDATE_PERIOD; /** - * Enable/disable publishing events in case leadership acquisition fails. - * Default: false + * Enable/disable publishing events in case leadership acquisition fails. Default: + * false */ private boolean publishFailedEvents = DEFAULT_PUBLISH_FAILED_EVENTS; public boolean isEnabled() { - return enabled; + return this.enabled; } public void setEnabled(boolean enabled) { @@ -94,7 +88,7 @@ public void setEnabled(boolean enabled) { } public boolean isAutoStartup() { - return autoStartup; + return this.autoStartup; } public void setAutoStartup(boolean autoStartup) { @@ -102,7 +96,7 @@ public void setAutoStartup(boolean autoStartup) { } public String getRole() { - return role; + return this.role; } public void setRole(String role) { @@ -110,23 +104,23 @@ public void setRole(String role) { } public String getNamespace() { - return namespace; + return this.namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; } public String getNamespace(String defaultValue) { - if (namespace == null || namespace.isEmpty()) { + if (this.namespace == null || this.namespace.isEmpty()) { return defaultValue; } - return namespace; - } - - public void setNamespace(String namespace) { - this.namespace = namespace; + return this.namespace; } public String getConfigMapName() { - return configMapName; + return this.configMapName; } public void setConfigMapName(String configMapName) { @@ -134,7 +128,7 @@ public void setConfigMapName(String configMapName) { } public String getLeaderIdPrefix() { - return leaderIdPrefix; + return this.leaderIdPrefix; } public void setLeaderIdPrefix(String leaderIdPrefix) { @@ -142,7 +136,7 @@ public void setLeaderIdPrefix(String leaderIdPrefix) { } public Duration getUpdatePeriod() { - return updatePeriod; + return this.updatePeriod; } public void setUpdatePeriod(Duration updatePeriod) { @@ -150,10 +144,11 @@ public void setUpdatePeriod(Duration updatePeriod) { } public boolean isPublishFailedEvents() { - return publishFailedEvents; + return this.publishFailedEvents; } public void setPublishFailedEvents(boolean publishFailedEvents) { this.publishFailedEvents = publishFailedEvents; } + } diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcher.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcher.java index 41bdc63c94..2ed825542b 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcher.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcher.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -30,7 +29,8 @@ */ public class LeaderRecordWatcher implements Watcher { - private static final Logger LOGGER = LoggerFactory.getLogger(LeaderRecordWatcher.class); + private static final Logger LOGGER = LoggerFactory + .getLogger(LeaderRecordWatcher.class); private final Object lock = new Object(); @@ -42,35 +42,36 @@ public class LeaderRecordWatcher implements Watcher { private Watch watch; - public LeaderRecordWatcher(LeaderProperties leaderProperties, LeadershipController leadershipController, - KubernetesClient kubernetesClient) { + public LeaderRecordWatcher(LeaderProperties leaderProperties, + LeadershipController leadershipController, + KubernetesClient kubernetesClient) { this.leadershipController = leadershipController; this.leaderProperties = leaderProperties; this.kubernetesClient = kubernetesClient; } public void start() { - if (watch == null) { - synchronized (lock) { - if (watch == null) { + if (this.watch == null) { + synchronized (this.lock) { + if (this.watch == null) { LOGGER.debug("Starting leader record watcher"); - watch = kubernetesClient - .configMaps() - .inNamespace(leaderProperties.getNamespace(kubernetesClient.getNamespace())) - .withName(leaderProperties.getConfigMapName()) - .watch(this); + this.watch = this.kubernetesClient.configMaps() + .inNamespace(this.leaderProperties + .getNamespace(this.kubernetesClient.getNamespace())) + .withName(this.leaderProperties.getConfigMapName()) + .watch(this); } } } } public void stop() { - if (watch != null) { - synchronized (lock) { - if (watch != null) { + if (this.watch != null) { + synchronized (this.lock) { + if (this.watch != null) { LOGGER.debug("Stopping leader record watcher"); - watch.close(); - watch = null; + this.watch.close(); + this.watch = null; } } } @@ -81,18 +82,19 @@ public void eventReceived(Action action, ConfigMap configMap) { LOGGER.debug("'{}' event received, triggering leadership update", action); if (!Action.ERROR.equals(action)) { - leadershipController.update(); + this.leadershipController.update(); } } @Override public void onClose(KubernetesClientException cause) { if (cause != null) { - synchronized (lock) { + synchronized (this.lock) { LOGGER.warn("Watcher stopped unexpectedly, will restart", cause); - watch = null; + this.watch = null; start(); } } } + } diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeadershipController.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeadershipController.java index db94e50e28..3cd7eb9fe8 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeadershipController.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeadershipController.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -28,6 +27,7 @@ import io.fabric8.kubernetes.client.KubernetesClientException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.integration.leader.Candidate; import org.springframework.integration.leader.Context; import org.springframework.integration.leader.event.LeaderEventPublisher; @@ -45,7 +45,8 @@ public class LeadershipController { private static final String KIND = "leaders"; - private static final Logger LOGGER = LoggerFactory.getLogger(LeadershipController.class); + private static final Logger LOGGER = LoggerFactory + .getLogger(LeadershipController.class); private final Candidate candidate; @@ -60,7 +61,8 @@ public class LeadershipController { private PodReadinessWatcher leaderReadinessWatcher; public LeadershipController(Candidate candidate, LeaderProperties leaderProperties, - LeaderEventPublisher leaderEventPublisher, KubernetesClient kubernetesClient) { + LeaderEventPublisher leaderEventPublisher, + KubernetesClient kubernetesClient) { this.candidate = candidate; this.leaderProperties = leaderProperties; this.leaderEventPublisher = leaderEventPublisher; @@ -68,7 +70,7 @@ public LeadershipController(Candidate candidate, LeaderProperties leaderProperti } public Optional getLocalLeader() { - return Optional.ofNullable(localLeader); + return Optional.ofNullable(this.localLeader); } public synchronized void update() { @@ -81,9 +83,10 @@ public synchronized void update() { return; } - if (leader != null && leader.isCandidate(candidate)) { + if (leader != null && leader.isCandidate(this.candidate)) { revoke(configMap); - } else { + } + else { acquire(configMap); } } @@ -92,100 +95,116 @@ public synchronized void revoke() { ConfigMap configMap = getConfigMap(); Leader leader = extractLeader(configMap); - if (leader != null && leader.isCandidate(candidate)) { + if (leader != null && leader.isCandidate(this.candidate)) { revoke(configMap); } } private void revoke(ConfigMap configMap) { - LOGGER.debug("Trying to revoke leadership for '{}'", candidate); + LOGGER.debug("Trying to revoke leadership for '{}'", this.candidate); try { String leaderKey = getLeaderKey(); removeConfigMapEntry(configMap, leaderKey); handleLeaderChange(null); - } catch (KubernetesClientException e) { - LOGGER.warn("Failure when revoking leadership for '{}': {}", candidate, e.getMessage()); + } + catch (KubernetesClientException e) { + LOGGER.warn("Failure when revoking leadership for '{}': {}", this.candidate, + e.getMessage()); } } private void acquire(ConfigMap configMap) { - LOGGER.debug("Trying to acquire leadership for '{}'", candidate); + LOGGER.debug("Trying to acquire leadership for '{}'", this.candidate); - if (!isPodReady(candidate.getId())) { - LOGGER.debug("Pod of '{}' is not ready at the moment, cannot acquire leadership", candidate); + if (!isPodReady(this.candidate.getId())) { + LOGGER.debug( + "Pod of '{}' is not ready at the moment, cannot acquire leadership", + this.candidate); return; } try { - Map data = getLeaderData(candidate); + Map data = getLeaderData(this.candidate); if (configMap == null) { createConfigMap(data); - } else { + } + else { updateConfigMapEntry(configMap, data); } - Leader newLeader = new Leader(candidate.getRole(), candidate.getId()); + Leader newLeader = new Leader(this.candidate.getRole(), + this.candidate.getId()); handleLeaderChange(newLeader); - } catch (KubernetesClientException e) { - LOGGER.warn("Failure when acquiring leadership for '{}': {}", candidate, e.getMessage()); + } + catch (KubernetesClientException e) { + LOGGER.warn("Failure when acquiring leadership for '{}': {}", this.candidate, + e.getMessage()); notifyOnFailedToAcquire(); } } private void handleLeaderChange(Leader newLeader) { - if (Objects.equals(localLeader, newLeader)) { - LOGGER.debug("Leader is still '{}'", localLeader); + if (Objects.equals(this.localLeader, newLeader)) { + LOGGER.debug("Leader is still '{}'", this.localLeader); return; - } else if (localLeader != null && localLeader.isCandidate(candidate)) { + } + else if (this.localLeader != null + && this.localLeader.isCandidate(this.candidate)) { notifyOnRevoked(); - } else if (newLeader != null && newLeader.isCandidate(candidate)) { + } + else if (newLeader != null && newLeader.isCandidate(this.candidate)) { notifyOnGranted(); } - localLeader = newLeader; - if (leaderReadinessWatcher != null) { - leaderReadinessWatcher.stop(); - leaderReadinessWatcher = null; + this.localLeader = newLeader; + if (this.leaderReadinessWatcher != null) { + this.leaderReadinessWatcher.stop(); + this.leaderReadinessWatcher = null; } - if (localLeader != null && !localLeader.isCandidate(candidate)) { - leaderReadinessWatcher = new PodReadinessWatcher(localLeader.getId(), kubernetesClient, this); - leaderReadinessWatcher.start(); + if (this.localLeader != null && !this.localLeader.isCandidate(this.candidate)) { + this.leaderReadinessWatcher = new PodReadinessWatcher( + this.localLeader.getId(), this.kubernetesClient, this); + this.leaderReadinessWatcher.start(); } - LOGGER.debug("New leader is '{}'", localLeader); + LOGGER.debug("New leader is '{}'", this.localLeader); } private void notifyOnGranted() { - LOGGER.debug("Leadership has been granted for '{}'", candidate); + LOGGER.debug("Leadership has been granted for '{}'", this.candidate); - Context context = new LeaderContext(candidate, this); - leaderEventPublisher.publishOnGranted(this, context, candidate.getRole()); + Context context = new LeaderContext(this.candidate, this); + this.leaderEventPublisher.publishOnGranted(this, context, + this.candidate.getRole()); try { - candidate.onGranted(context); - } catch (InterruptedException e) { + this.candidate.onGranted(context); + } + catch (InterruptedException e) { LOGGER.warn(e.getMessage()); Thread.currentThread().interrupt(); } } private void notifyOnRevoked() { - LOGGER.debug("Leadership has been revoked for '{}'", candidate); + LOGGER.debug("Leadership has been revoked for '{}'", this.candidate); - Context context = new LeaderContext(candidate, this); - leaderEventPublisher.publishOnRevoked(this, context, candidate.getRole()); - candidate.onRevoked(context); + Context context = new LeaderContext(this.candidate, this); + this.leaderEventPublisher.publishOnRevoked(this, context, + this.candidate.getRole()); + this.candidate.onRevoked(context); } private void notifyOnFailedToAcquire() { - if (leaderProperties.isPublishFailedEvents()) { - Context context = new LeaderContext(candidate, this); - leaderEventPublisher.publishOnFailedToAcquire(this, context, candidate.getRole()); + if (this.leaderProperties.isPublishFailedEvents()) { + Context context = new LeaderContext(this.candidate, this); + this.leaderEventPublisher.publishOnFailedToAcquire(this, context, + this.candidate.getRole()); } } private String getLeaderKey() { - return leaderProperties.getLeaderIdPrefix() + candidate.getRole(); + return this.leaderProperties.getLeaderIdPrefix() + this.candidate.getRole(); } private Map getLeaderData(Candidate candidate) { @@ -205,44 +224,39 @@ private Leader extractLeader(ConfigMap configMap) { return null; } - return new Leader(candidate.getRole(), leaderId); + return new Leader(this.candidate.getRole(), leaderId); } private boolean isPodReady(String name) { - return kubernetesClient.pods() - .withName(name) - .isReady(); + return this.kubernetesClient.pods().withName(name).isReady(); } private ConfigMap getConfigMap() { - return kubernetesClient.configMaps() - .inNamespace(leaderProperties.getNamespace(kubernetesClient.getNamespace())) - .withName(leaderProperties.getConfigMapName()) - .get(); + return this.kubernetesClient.configMaps() + .inNamespace(this.leaderProperties + .getNamespace(this.kubernetesClient.getNamespace())) + .withName(this.leaderProperties.getConfigMapName()).get(); } private void createConfigMap(Map data) { LOGGER.debug("Creating new config map with data: {}", data); ConfigMap newConfigMap = new ConfigMapBuilder().withNewMetadata() - .withName(leaderProperties.getConfigMapName()) - .addToLabels(PROVIDER_KEY, PROVIDER) - .addToLabels(KIND_KEY, KIND) - .endMetadata() - .addToData(data) - .build(); - - kubernetesClient.configMaps() - .inNamespace(leaderProperties.getNamespace(kubernetesClient.getNamespace())) - .create(newConfigMap); + .withName(this.leaderProperties.getConfigMapName()) + .addToLabels(PROVIDER_KEY, PROVIDER).addToLabels(KIND_KEY, KIND) + .endMetadata().addToData(data).build(); + + this.kubernetesClient.configMaps() + .inNamespace(this.leaderProperties + .getNamespace(this.kubernetesClient.getNamespace())) + .create(newConfigMap); } private void updateConfigMapEntry(ConfigMap configMap, Map newData) { LOGGER.debug("Adding new data to config map: {}", newData); - ConfigMap newConfigMap = new ConfigMapBuilder(configMap) - .addToData(newData) - .build(); + ConfigMap newConfigMap = new ConfigMapBuilder(configMap).addToData(newData) + .build(); updateConfigMap(configMap, newConfigMap); } @@ -250,18 +264,19 @@ private void updateConfigMapEntry(ConfigMap configMap, Map newDa private void removeConfigMapEntry(ConfigMap configMap, String key) { LOGGER.debug("Removing config map entry '{}'", key); - ConfigMap newConfigMap = new ConfigMapBuilder(configMap) - .removeFromData(key) - .build(); + ConfigMap newConfigMap = new ConfigMapBuilder(configMap).removeFromData(key) + .build(); updateConfigMap(configMap, newConfigMap); } private void updateConfigMap(ConfigMap oldConfigMap, ConfigMap newConfigMap) { - kubernetesClient.configMaps() - .inNamespace(leaderProperties.getNamespace(kubernetesClient.getNamespace())) - .withName(leaderProperties.getConfigMapName()) - .lockResourceVersion(oldConfigMap.getMetadata().getResourceVersion()) - .replace(newConfigMap); + this.kubernetesClient.configMaps() + .inNamespace(this.leaderProperties + .getNamespace(this.kubernetesClient.getNamespace())) + .withName(this.leaderProperties.getConfigMapName()) + .lockResourceVersion(oldConfigMap.getMetadata().getResourceVersion()) + .replace(newConfigMap); } + } diff --git a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcher.java b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcher.java index a6fd2724d2..6a5182681c 100644 --- a/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcher.java +++ b/spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcher.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -33,7 +32,8 @@ */ public class PodReadinessWatcher implements Watcher { - private static final Logger LOGGER = LoggerFactory.getLogger(PodReadinessWatcher.class); + private static final Logger LOGGER = LoggerFactory + .getLogger(PodReadinessWatcher.class); private final Object lock = new Object(); @@ -48,34 +48,33 @@ public class PodReadinessWatcher implements Watcher { private Watch watch; public PodReadinessWatcher(String podName, KubernetesClient kubernetesClient, - LeadershipController leadershipController) { + LeadershipController leadershipController) { this.podName = podName; this.kubernetesClient = kubernetesClient; this.leadershipController = leadershipController; } public void start() { - if (watch == null) { - synchronized (lock) { - if (watch == null) { - LOGGER.debug("Starting pod readiness watcher for '{}'", podName); - PodResource podResource = kubernetesClient - .pods() - .withName(podName); - previousState = podResource.isReady(); - watch = podResource.watch(this); + if (this.watch == null) { + synchronized (this.lock) { + if (this.watch == null) { + LOGGER.debug("Starting pod readiness watcher for '{}'", this.podName); + PodResource podResource = this.kubernetesClient + .pods().withName(this.podName); + this.previousState = podResource.isReady(); + this.watch = podResource.watch(this); } } } } public void stop() { - if (watch != null) { - synchronized (lock) { - if (watch != null) { - LOGGER.debug("Stopping pod readiness watcher for '{}'", podName); - watch.close(); - watch = null; + if (this.watch != null) { + synchronized (this.lock) { + if (this.watch != null) { + LOGGER.debug("Stopping pod readiness watcher for '{}'", this.podName); + this.watch.close(); + this.watch = null; } } } @@ -84,12 +83,14 @@ public void stop() { @Override public void eventReceived(Action action, Pod pod) { boolean currentState = Readiness.isPodReady(pod); - if (previousState != currentState) { - synchronized (lock) { - if (previousState != currentState) { - LOGGER.debug("'{}' readiness status changed to '{}', triggering leadership update", podName, currentState); - previousState = currentState; - leadershipController.update(); + if (this.previousState != currentState) { + synchronized (this.lock) { + if (this.previousState != currentState) { + LOGGER.debug( + "'{}' readiness status changed to '{}', triggering leadership update", + this.podName, currentState); + this.previousState = currentState; + this.leadershipController.update(); } } } @@ -98,11 +99,12 @@ public void eventReceived(Action action, Pod pod) { @Override public void onClose(KubernetesClientException cause) { if (cause != null) { - synchronized (lock) { + synchronized (this.lock) { LOGGER.warn("Watcher stopped unexpectedly, will restart", cause); - watch = null; + this.watch = null; start(); } } } + } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java index c85adfb933..e169f0e462 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java @@ -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. @@ -12,24 +12,23 @@ * 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.kubernetes.leader; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "spring.cloud.kubernetes.leader.autoStartup=false" // Make sure test passes without Kubernetes cluster - } -) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "spring.cloud.kubernetes.leader.autoStartup=false" // Make sure test passes + // without Kubernetes cluster +}) public class LeaderAutoConfigurationTests { @Test @@ -38,6 +37,8 @@ public void contextLoads() { @SpringBootConfiguration @EnableAutoConfiguration - protected static class TestConfig {} + protected static class TestConfig { + + } } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java index be0d93a54c..59890b3463 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -24,6 +23,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.integration.leader.Candidate; import static org.assertj.core.api.Assertions.assertThat; @@ -49,42 +49,46 @@ public class LeaderContextTest { @Before public void before() { - leaderContext = new LeaderContext(mockCandidate, mockLeadershipController); + this.leaderContext = new LeaderContext(this.mockCandidate, + this.mockLeadershipController); } @Test public void testIsLeaderWithoutLeader() { - given(mockLeadershipController.getLocalLeader()).willReturn(Optional.empty()); + given(this.mockLeadershipController.getLocalLeader()) + .willReturn(Optional.empty()); - boolean result = leaderContext.isLeader(); + boolean result = this.leaderContext.isLeader(); assertThat(result).isFalse(); } @Test public void testIsLeaderWithAnotherLeader() { - given(mockLeadershipController.getLocalLeader()).willReturn(Optional.of(mockLeader)); + given(this.mockLeadershipController.getLocalLeader()) + .willReturn(Optional.of(this.mockLeader)); - boolean result = leaderContext.isLeader(); + boolean result = this.leaderContext.isLeader(); assertThat(result).isFalse(); } @Test public void testIsLeaderWhenLeader() { - given(mockLeadershipController.getLocalLeader()).willReturn(Optional.of(mockLeader)); - given(mockLeader.isCandidate(mockCandidate)).willReturn(true); + given(this.mockLeadershipController.getLocalLeader()) + .willReturn(Optional.of(this.mockLeader)); + given(this.mockLeader.isCandidate(this.mockCandidate)).willReturn(true); - boolean result = leaderContext.isLeader(); + boolean result = this.leaderContext.isLeader(); assertThat(result).isTrue(); } @Test public void shouldYieldLeadership() { - leaderContext.yield(); + this.leaderContext.yield(); - verify(mockLeadershipController).revoke(); + verify(this.mockLeadershipController).revoke(); } } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java index ea2c6951c1..5e801ae393 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java @@ -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. @@ -12,11 +12,12 @@ * 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.kubernetes.leader; +import java.time.Duration; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -29,8 +30,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.internal.verification.VerificationModeFactory.atLeastOnce; -import java.time.Duration; - /** * @author Gytis Trikleris */ @@ -56,80 +55,87 @@ public class LeaderInitiatorTest { @Before public void before() { - leaderInitiator = new LeaderInitiator(mockLeaderProperties, mockLeadershipController, mockLeaderRecordWatcher, - mockPodReadinessWatcher); + this.leaderInitiator = new LeaderInitiator(this.mockLeaderProperties, + this.mockLeadershipController, this.mockLeaderRecordWatcher, + this.mockPodReadinessWatcher); } @After public void after() { - leaderInitiator.stop(); + this.leaderInitiator.stop(); } @Test public void testIsAutoStartup() { - given(mockLeaderProperties.isAutoStartup()).willReturn(true); + given(this.mockLeaderProperties.isAutoStartup()).willReturn(true); - assertThat(leaderInitiator.isAutoStartup()).isTrue(); + assertThat(this.leaderInitiator.isAutoStartup()).isTrue(); } @Test public void shouldStart() throws InterruptedException { - given(mockLeaderProperties.getUpdatePeriod()).willReturn(Duration.ofMillis(1L)); + given(this.mockLeaderProperties.getUpdatePeriod()) + .willReturn(Duration.ofMillis(1L)); - leaderInitiator.start(); + this.leaderInitiator.start(); - assertThat(leaderInitiator.isRunning()).isTrue(); - verify(mockLeaderRecordWatcher).start(); - verify(mockPodReadinessWatcher).start(); + assertThat(this.leaderInitiator.isRunning()).isTrue(); + verify(this.mockLeaderRecordWatcher).start(); + verify(this.mockPodReadinessWatcher).start(); Thread.sleep(10); - verify(mockLeadershipController, atLeastOnce()).update(); + verify(this.mockLeadershipController, atLeastOnce()).update(); } @Test public void shouldStartOnlyOnce() { - given(mockLeaderProperties.getUpdatePeriod()).willReturn(Duration.ofMillis(10000L)); + given(this.mockLeaderProperties.getUpdatePeriod()) + .willReturn(Duration.ofMillis(10000L)); - leaderInitiator.start(); - leaderInitiator.start(); + this.leaderInitiator.start(); + this.leaderInitiator.start(); - verify(mockLeaderRecordWatcher).start(); + verify(this.mockLeaderRecordWatcher).start(); } @Test public void shouldStop() { - given(mockLeaderProperties.getUpdatePeriod()).willReturn(Duration.ofMillis(10000L)); + given(this.mockLeaderProperties.getUpdatePeriod()) + .willReturn(Duration.ofMillis(10000L)); - leaderInitiator.start(); - leaderInitiator.stop(); + this.leaderInitiator.start(); + this.leaderInitiator.stop(); - assertThat(leaderInitiator.isRunning()).isFalse(); - verify(mockLeaderRecordWatcher).stop(); - verify(mockPodReadinessWatcher).start(); - verify(mockLeadershipController).revoke(); + assertThat(this.leaderInitiator.isRunning()).isFalse(); + verify(this.mockLeaderRecordWatcher).stop(); + verify(this.mockPodReadinessWatcher).start(); + verify(this.mockLeadershipController).revoke(); } @Test public void shouldStopOnlyOnce() { - given(mockLeaderProperties.getUpdatePeriod()).willReturn(Duration.ofMillis(10000L)); + given(this.mockLeaderProperties.getUpdatePeriod()) + .willReturn(Duration.ofMillis(10000L)); - leaderInitiator.start(); - leaderInitiator.stop(); - leaderInitiator.stop(); + this.leaderInitiator.start(); + this.leaderInitiator.stop(); + this.leaderInitiator.stop(); - verify(mockLeaderRecordWatcher).stop(); + verify(this.mockLeaderRecordWatcher).stop(); } @Test public void shouldStopAndExecuteCallback() { - given(mockLeaderProperties.getUpdatePeriod()).willReturn(Duration.ofMillis(10000L)); + given(this.mockLeaderProperties.getUpdatePeriod()) + .willReturn(Duration.ofMillis(10000L)); - leaderInitiator.start(); - leaderInitiator.stop(mockRunnable); + this.leaderInitiator.start(); + this.leaderInitiator.stop(this.mockRunnable); - assertThat(leaderInitiator.isRunning()).isFalse(); - verify(mockLeaderRecordWatcher).stop(); - verify(mockPodReadinessWatcher).start(); - verify(mockLeadershipController).revoke(); - verify(mockRunnable).run(); + assertThat(this.leaderInitiator.isRunning()).isFalse(); + verify(this.mockLeaderRecordWatcher).stop(); + verify(this.mockPodReadinessWatcher).start(); + verify(this.mockLeadershipController).revoke(); + verify(this.mockRunnable).run(); } + } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java index 85add96b30..7cea7bb425 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -53,12 +52,10 @@ public class LeaderRecordWatcherTest { private KubernetesClient mockKubernetesClient; @Mock - private MixedOperation> - mockConfigMapsOperation; + private MixedOperation> mockConfigMapsOperation; @Mock - private NonNamespaceOperation> - mockInNamespaceOperation; + private NonNamespaceOperation> mockInNamespaceOperation; @Mock private Resource mockWithNameResource; @@ -76,59 +73,63 @@ public class LeaderRecordWatcherTest { @Before public void before() { - watcher = new LeaderRecordWatcher(mockLeaderProperties, mockLeadershipController, mockKubernetesClient); - - given(mockKubernetesClient.configMaps()).willReturn(mockConfigMapsOperation); - given(mockConfigMapsOperation.inNamespace(null)).willReturn(mockInNamespaceOperation); - given(mockInNamespaceOperation.withName(null)).willReturn(mockWithNameResource); - given(mockWithNameResource.watch(watcher)).willReturn(mockWatch); + this.watcher = new LeaderRecordWatcher(this.mockLeaderProperties, + this.mockLeadershipController, this.mockKubernetesClient); + + given(this.mockKubernetesClient.configMaps()) + .willReturn(this.mockConfigMapsOperation); + given(this.mockConfigMapsOperation.inNamespace(null)) + .willReturn(this.mockInNamespaceOperation); + given(this.mockInNamespaceOperation.withName(null)) + .willReturn(this.mockWithNameResource); + given(this.mockWithNameResource.watch(this.watcher)).willReturn(this.mockWatch); } @Test public void shouldStartOnce() { - watcher.start(); - watcher.start(); + this.watcher.start(); + this.watcher.start(); - verify(mockWithNameResource).watch(watcher); + verify(this.mockWithNameResource).watch(this.watcher); } @Test public void shouldStopOnce() { - watcher.start(); - watcher.stop(); - watcher.stop(); + this.watcher.start(); + this.watcher.stop(); + this.watcher.stop(); - verify(mockWatch).close(); + verify(this.mockWatch).close(); } @Test public void shouldHandleEvent() { - watcher.eventReceived(Watcher.Action.ADDED, mockConfigMap); - watcher.eventReceived(Watcher.Action.DELETED, mockConfigMap); - watcher.eventReceived(Watcher.Action.MODIFIED, mockConfigMap); + this.watcher.eventReceived(Watcher.Action.ADDED, this.mockConfigMap); + this.watcher.eventReceived(Watcher.Action.DELETED, this.mockConfigMap); + this.watcher.eventReceived(Watcher.Action.MODIFIED, this.mockConfigMap); - verify(mockLeadershipController, times(3)).update(); + verify(this.mockLeadershipController, times(3)).update(); } @Test public void shouldIgnoreErrorEvent() { - watcher.eventReceived(Watcher.Action.ERROR, mockConfigMap); + this.watcher.eventReceived(Watcher.Action.ERROR, this.mockConfigMap); - verify(mockLeadershipController, times(0)).update(); + verify(this.mockLeadershipController, times(0)).update(); } @Test public void shouldHandleClose() { - watcher.onClose(mockKubernetesClientException); + this.watcher.onClose(this.mockKubernetesClientException); - verify(mockWithNameResource).watch(watcher); + verify(this.mockWithNameResource).watch(this.watcher); } @Test public void shouldIgnoreCloseWithoutCause() { - watcher.onClose(null); + this.watcher.onClose(null); - verify(mockWithNameResource, times(0)).watch(watcher); + verify(this.mockWithNameResource, times(0)).watch(this.watcher); } } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java index 12b501d4ba..73bc89bf00 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -22,12 +21,11 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.integration.leader.Candidate; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.within; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; /** * @author Gytis Trikleris @@ -46,30 +44,30 @@ public class LeaderTest { @Before public void before() { - leader = new Leader(ROLE, ID); + this.leader = new Leader(ROLE, ID); } @Test public void shouldGetRole() { - assertThat(leader.getRole()).isEqualTo(ROLE); + assertThat(this.leader.getRole()).isEqualTo(ROLE); } @Test public void shouldGetId() { - assertThat(leader.getId()).isEqualTo(ID); + assertThat(this.leader.getId()).isEqualTo(ID); } @Test public void shouldCheckWithNullCandidate() { - assertThat(leader.isCandidate(null)).isEqualTo(false); + assertThat(this.leader.isCandidate(null)).isEqualTo(false); } @Test public void shouldCheckCandidate() { - given(mockCandidate.getId()).willReturn(ID); - given(mockCandidate.getRole()).willReturn(ROLE); + given(this.mockCandidate.getId()).willReturn(ID); + given(this.mockCandidate.getRole()).willReturn(ROLE); - assertThat(leader.isCandidate(mockCandidate)).isTrue(); + assertThat(this.leader.isCandidate(this.mockCandidate)).isTrue(); } } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java index 6a1bde2b64..413ee2395d 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.leader; @@ -23,6 +22,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.integration.leader.Candidate; import org.springframework.integration.leader.event.LeaderEventPublisher; @@ -50,13 +50,14 @@ public class LeadershipControllerTest { @Before public void before() { - leadershipController = new LeadershipController(mockCandidate, mockLeaderProperties, mockLeaderEventPublisher, - mockKubernetesClient); + this.leadershipController = new LeadershipController(this.mockCandidate, + this.mockLeaderProperties, this.mockLeaderEventPublisher, + this.mockKubernetesClient); } @Test public void shouldGetEmptyLocalLeader() { - assertThat(leadershipController.getLocalLeader().isPresent()).isFalse(); + assertThat(this.leadershipController.getLocalLeader().isPresent()).isFalse(); } } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java index 34f577ef1f..75faca62ff 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java @@ -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. @@ -12,16 +12,12 @@ * 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.kubernetes.leader; -import java.util.Collections; - import io.fabric8.kubernetes.api.model.DoneablePod; import io.fabric8.kubernetes.api.model.Pod; -import io.fabric8.kubernetes.api.model.PodCondition; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.PodStatus; import io.fabric8.kubernetes.client.KubernetesClient; @@ -76,63 +72,64 @@ public class PodReadinessWatcherTest { @Before public void before() { - watcher = new PodReadinessWatcher(POD_NAME, mockKubernetesClient, mockLeadershipController); + this.watcher = new PodReadinessWatcher(POD_NAME, this.mockKubernetesClient, + this.mockLeadershipController); - given(mockKubernetesClient.pods()).willReturn(mockPodsOperation); - given(mockPodsOperation.withName(POD_NAME)).willReturn(mockPodResource); - given(mockPodResource.watch(watcher)).willReturn(mockWatch); + given(this.mockKubernetesClient.pods()).willReturn(this.mockPodsOperation); + given(this.mockPodsOperation.withName(POD_NAME)).willReturn(this.mockPodResource); + given(this.mockPodResource.watch(this.watcher)).willReturn(this.mockWatch); } @Test public void shouldStartOnce() { - watcher.start(); - watcher.start(); + this.watcher.start(); + this.watcher.start(); - verify(mockPodResource).watch(watcher); + verify(this.mockPodResource).watch(this.watcher); } @Test public void shouldStopOnce() { - watcher.start(); - watcher.stop(); - watcher.stop(); + this.watcher.start(); + this.watcher.stop(); + this.watcher.stop(); - verify(mockWatch).close(); + verify(this.mockWatch).close(); } @Test public void shouldHandleEventWithStateChange() { - given(mockPodResource.isReady()).willReturn(true); - given(mockPod.getStatus()).willReturn(mockPodStatus); + given(this.mockPodResource.isReady()).willReturn(true); + given(this.mockPod.getStatus()).willReturn(this.mockPodStatus); - watcher.start(); - watcher.eventReceived(Watcher.Action.ADDED, mockPod); + this.watcher.start(); + this.watcher.eventReceived(Watcher.Action.ADDED, this.mockPod); - verify(mockLeadershipController).update(); + verify(this.mockLeadershipController).update(); } @Test public void shouldIgnoreEventIfStateDoesNotChange() { - given(mockPod.getStatus()).willReturn(mockPodStatus); + given(this.mockPod.getStatus()).willReturn(this.mockPodStatus); - watcher.start(); - watcher.eventReceived(Watcher.Action.ADDED, mockPod); + this.watcher.start(); + this.watcher.eventReceived(Watcher.Action.ADDED, this.mockPod); - verify(mockLeadershipController, times(0)).update(); + verify(this.mockLeadershipController, times(0)).update(); } @Test public void shouldHandleClose() { - watcher.onClose(mockKubernetesClientException); + this.watcher.onClose(this.mockKubernetesClientException); - verify(mockPodResource).watch(watcher); + verify(this.mockPodResource).watch(this.watcher); } @Test public void shouldIgnoreCloseWithoutCause() { - watcher.onClose(null); + this.watcher.onClose(null); - verify(mockPodResource, times(0)).watch(watcher); + verify(this.mockPodResource, times(0)).watch(this.watcher); } } diff --git a/spring-cloud-kubernetes-ribbon/pom.xml b/spring-cloud-kubernetes-ribbon/pom.xml index e4c6b997e0..3ab53f3b44 100644 --- a/spring-cloud-kubernetes-ribbon/pom.xml +++ b/spring-cloud-kubernetes-ribbon/pom.xml @@ -16,8 +16,8 @@ ~ --> - spring-cloud-kubernetes diff --git a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKey.java b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKey.java index 900bf2a1ff..247ed6cb59 100644 --- a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKey.java +++ b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKey.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; @@ -24,34 +23,66 @@ import java.util.HashSet; import java.util.Set; -import org.springframework.util.Assert; - import com.netflix.client.config.IClientConfigKey; +import org.springframework.util.Assert; + +/** + * Kubernetes implementation of a Ribbon {@link IClientConfigKey}. + * + * @param type of key + * @author Ioannis Canellos + */ public abstract class KubernetesConfigKey implements IClientConfigKey { - public static final IClientConfigKey Namespace = new KubernetesConfigKey("KubernetesNamespace") { + /** + * Namespace configuration key. + */ + public static final IClientConfigKey Namespace = new KubernetesConfigKey( + "KubernetesNamespace") { }; - public static final IClientConfigKey PortName = new KubernetesConfigKey("PortName") { + + /** + * Port name configuration key. + */ + public static final IClientConfigKey PortName = new KubernetesConfigKey( + "PortName") { }; private static final Set keys = new HashSet(); static { for (Field f : KubernetesConfigKey.class.getDeclaredFields()) { - if (Modifier.isStatic(f.getModifiers()) //&& Modifier.isPublic(f.getModifiers()) - && IClientConfigKey.class.isAssignableFrom(f.getType())) { + if (Modifier.isStatic(f.getModifiers()) // && + // Modifier.isPublic(f.getModifiers()) + && IClientConfigKey.class.isAssignableFrom(f.getType())) { try { keys.add((IClientConfigKey) f.get(null)); - } catch (IllegalAccessException e) { + } + catch (IllegalAccessException e) { throw new RuntimeException(e); } } } } + private final String configKey; + + private final Class type; + + @SuppressWarnings("unchecked") + protected KubernetesConfigKey(String configKey) { + this.configKey = configKey; + Type superclass = getClass().getGenericSuperclass(); + Assert.isTrue(superclass instanceof ParameterizedType, + superclass + " isn't parameterized"); + Type runtimeType = ((ParameterizedType) superclass).getActualTypeArguments()[0]; + this.type = (Class) Types.rawType(runtimeType); + } + /** * @deprecated see {@link #keys()} + * @return array of {@link IClientConfigKey} */ @Deprecated public static IClientConfigKey[] values() { @@ -59,7 +90,7 @@ public static IClientConfigKey[] values() { } /** - * return all the public static keys defined in this class + * @return all the public static keys defined in this class */ public static Set keys() { return keys; @@ -84,34 +115,24 @@ public Class type() { }; } - private final String configKey; - private final Class type; - - @SuppressWarnings("unchecked") - protected KubernetesConfigKey(String configKey) { - this.configKey = configKey; - Type superclass = getClass().getGenericSuperclass(); - Assert.isTrue(superclass instanceof ParameterizedType, - superclass + " isn't parameterized"); - Type runtimeType = ((ParameterizedType) superclass).getActualTypeArguments()[0]; - type = (Class) Types.rawType(runtimeType); - } - @Override public Class type() { - return type; + return this.type; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.netflix.niws.client.ClientConfig#key() */ @Override public String key() { - return configKey; + return this.configKey; } @Override public String toString() { - return configKey; + return this.configKey; } + } diff --git a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesRibbonClientConfiguration.java b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesRibbonClientConfiguration.java index be19033b23..a7421996a2 100644 --- a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesRibbonClientConfiguration.java +++ b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesRibbonClientConfiguration.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; @@ -25,6 +24,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +/** + * Kubernetes version of a Ribbon client configuration. + * + * @author Ioannis Canellos + */ @Configuration public class KubernetesRibbonClientConfiguration { @@ -38,4 +42,5 @@ public ServerList ribbonServerList(KubernetesClient client, IClientConfig con serverList.initWithNiwsConfig(config); return serverList; } + } diff --git a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesServerList.java b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesServerList.java index 75b25d65cb..88f24c6ae1 100644 --- a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesServerList.java +++ b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/KubernetesServerList.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; @@ -34,10 +33,16 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +/** + * Kubernetes {@link ServerList}. + * + * @author Ioannis Canellos + */ public class KubernetesServerList extends AbstractServerList implements ServerList { private static final int FIRST = 0; + private static final Log LOG = LogFactory.getLog(KubernetesServerList.class); private final KubernetesClient client; @@ -45,6 +50,7 @@ public class KubernetesServerList extends AbstractServerList private String serviceId; private String namespace; + private String portName; public KubernetesServerList(KubernetesClient client) { @@ -54,7 +60,7 @@ public KubernetesServerList(KubernetesClient client) { public void initWithNiwsConfig(IClientConfig clientConfig) { this.serviceId = clientConfig.getClientName(); this.namespace = clientConfig.getPropertyAsString(KubernetesConfigKey.Namespace, - client.getNamespace()); + this.client.getNamespace()); this.portName = clientConfig.getPropertyAsString(KubernetesConfigKey.PortName, null); } @@ -64,17 +70,18 @@ public List getInitialListOfServers() { } public List getUpdatedListOfServers() { - Endpoints endpoints = namespace != null - ? client.endpoints().inNamespace(namespace).withName(serviceId).get() - : client.endpoints().withName(serviceId).get(); + Endpoints endpoints = this.namespace != null + ? this.client.endpoints().inNamespace(this.namespace) + .withName(this.serviceId).get() + : this.client.endpoints().withName(this.serviceId).get(); List result = new ArrayList(); if (endpoints != null) { if (LOG.isDebugEnabled()) { LOG.debug("Found [" + endpoints.getSubsets().size() - + "] endpoints in namespace [" + namespace + "] for name [" - + serviceId + "] and portName [" + portName + "]"); + + "] endpoints in namespace [" + this.namespace + "] for name [" + + this.serviceId + "] and portName [" + this.portName + "]"); } for (EndpointSubset subset : endpoints.getSubsets()) { @@ -86,8 +93,8 @@ public List getUpdatedListOfServers() { } else { for (EndpointPort port : subset.getPorts()) { - if (Utils.isNullOrEmpty(portName) - || portName.endsWith(port.getName())) { + if (Utils.isNullOrEmpty(this.portName) + || this.portName.endsWith(port.getName())) { for (EndpointAddress address : subset.getAddresses()) { result.add(new Server(address.getIp(), port.getPort())); } @@ -97,9 +104,11 @@ public List getUpdatedListOfServers() { } } else { - LOG.warn("Did not find any endpoints in ribbon in namespace [" + namespace - + "] for name [" + serviceId + "] and portName [" + portName + "]"); + LOG.warn("Did not find any endpoints in ribbon in namespace [" + + this.namespace + "] for name [" + this.serviceId + + "] and portName [" + this.portName + "]"); } return result; } + } diff --git a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/RibbonKubernetesAutoConfiguration.java b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/RibbonKubernetesAutoConfiguration.java index 0a8772a5c7..722edf6b8f 100644 --- a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/RibbonKubernetesAutoConfiguration.java +++ b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/RibbonKubernetesAutoConfiguration.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; @@ -26,6 +25,11 @@ import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.context.annotation.Configuration; +/** + * Auto configuration for Ribbon. + * + * @author Ioannis Canellos + */ @Configuration @EnableConfigurationProperties @ConditionalOnBean(SpringClientFactory.class) @@ -33,4 +37,5 @@ @AutoConfigureAfter(RibbonAutoConfiguration.class) @RibbonClients(defaultConfiguration = KubernetesRibbonClientConfiguration.class) public class RibbonKubernetesAutoConfiguration { + } diff --git a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/Types.java b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/Types.java index d8766e77c1..41928348cc 100644 --- a/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/Types.java +++ b/spring-cloud-kubernetes-ribbon/src/main/java/org/springframework/cloud/kubernetes/ribbon/Types.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; @@ -52,4 +51,5 @@ private static Type firstOrObject(Type[] types) { return Void.class; } } + } diff --git a/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/RibbonTest.groovy b/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/RibbonTest.groovy index 91e4d14762..9dcf2a3657 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/RibbonTest.groovy +++ b/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/RibbonTest.groovy @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon.test @@ -21,86 +20,93 @@ import io.fabric8.kubernetes.api.model.EndpointsBuilder import io.fabric8.kubernetes.client.Config import io.fabric8.kubernetes.client.KubernetesClient import io.fabric8.kubernetes.server.mock.KubernetesMockServer -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.cloud.kubernetes.ribbon.KubernetesRibbonClientConfiguration +import spock.lang.Specification + 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.loadbalancer.LoadBalancerInterceptor +import org.springframework.cloud.kubernetes.ribbon.KubernetesRibbonClientConfiguration import org.springframework.cloud.netflix.ribbon.RibbonClient import org.springframework.test.context.ContextConfiguration import org.springframework.web.client.RestTemplate -import spock.lang.Specification @EnableAutoConfiguration -@ContextConfiguration(classes=[TestApplication.class]) -@SpringBootTest(properties= - [ - "spring.application.name=testapp", - "spring.cloud.kubernetes.client.namespace=testns", - "spring.cloud.kubernetes.client.trustCerts=true", - "spring.cloud.kubernetes.config.namespace=testns" - ]) +@ContextConfiguration(classes = [TestApplication.class]) +@SpringBootTest(properties = + [ + "spring.application.name=testapp", + "spring.cloud.kubernetes.client.namespace=testns", + "spring.cloud.kubernetes.client.trustCerts=true", + "spring.cloud.kubernetes.config.namespace=testns" + ]) @RibbonClient(name = "testapp", configuration = KubernetesRibbonClientConfiguration.class) class RibbonTest extends Specification { - private static KubernetesMockServer mockServer = new KubernetesMockServer() - private static KubernetesMockServer mockEndpointA = new KubernetesMockServer(false) - private static KubernetesMockServer mockEndpointB = new KubernetesMockServer(false) - private static KubernetesClient mockClient; + private static KubernetesMockServer mockServer = new KubernetesMockServer() + private static KubernetesMockServer mockEndpointA = new KubernetesMockServer(false) + private static KubernetesMockServer mockEndpointB = new KubernetesMockServer(false) + private static KubernetesClient mockClient; - @Autowired - RestTemplate restTemplate; + @Autowired + RestTemplate restTemplate; - @Autowired - LoadBalancerInterceptor interceptor; + @Autowired + LoadBalancerInterceptor interceptor; - def setupSpec() { - mockServer.init() - mockEndpointA.init() - mockEndpointB.init() - mockClient = mockServer.createClient() + def setupSpec() { + mockServer.init() + mockEndpointA.init() + mockEndpointB.init() + mockClient = mockServer.createClient() - //Configure the kubernetes master url to point to the mock server - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl()) - System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true") - System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false") - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false") + //Configure the kubernetes master url to point to the mock server + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient. + getConfiguration().getMasterUrl()) + System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true") + System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false") + System. + setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false") - //Configured - mockServer.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp").andReturn(200, new EndpointsBuilder() - .withNewMetadata() - .withName("testapp-a") - .endMetadata() - .addNewSubset() - .addNewAddress().withIp(mockEndpointA.getServer().hostName).endAddress() - .addNewPort("http", mockEndpointA.getServer().port, "http") - .endSubset() - .addNewSubset() - .addNewAddress().withIp(mockEndpointB.getServer().hostName).endAddress() - .addNewPort("http", mockEndpointB.getServer().port, "http") - .endSubset() - .build()).always() + //Configured + mockServer.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp"). + andReturn(200, new EndpointsBuilder() + .withNewMetadata() + .withName("testapp-a") + .endMetadata() + .addNewSubset() + .addNewAddress().withIp(mockEndpointA.getServer().hostName).endAddress() + .addNewPort("http", mockEndpointA.getServer().port, "http") + .endSubset() + .addNewSubset() + .addNewAddress().withIp(mockEndpointB.getServer().hostName).endAddress() + .addNewPort("http", mockEndpointB.getServer().port, "http") + .endSubset() + .build()).always() - mockEndpointA.expect().get().withPath("/greeting").andReturn(200, "Hello from A").always() - mockEndpointB.expect().get().withPath("/greeting").andReturn(200, "Hello from B").always() - } + mockEndpointA.expect().get().withPath("/greeting").andReturn(200, "Hello from A"). + always() + mockEndpointB.expect().get().withPath("/greeting").andReturn(200, "Hello from B"). + always() + } - def cleanupSpec() { - mockServer.destroy() - mockEndpointA.destroy() - mockEndpointB.destroy() - } + def cleanupSpec() { + mockServer.destroy() + mockEndpointA.destroy() + mockEndpointB.destroy() + } - def "A ribbon rest template should round robin over the available kubernetes endpoints"() { - given: - List grettings = new ArrayList<>() - when: - for (int i = 0; i < 2 ; i++) { - grettings.add(restTemplate.getForObject("http://testapp/greeting", String.class)) - } - then: - grettings.contains("Hello from A") - grettings.contains("Hello from B") - } + def "A ribbon rest template should round robin over the available kubernetes endpoints"() { + given: + List grettings = new ArrayList<>() + when: + for (int i = 0; i < 2; i++) { + grettings.add(restTemplate. + getForObject("http://testapp/greeting", String.class)) + } + then: + grettings.contains("Hello from A") + grettings.contains("Hello from B") + } } diff --git a/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/TestApplication.groovy b/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/TestApplication.groovy index ccb9df653a..64271e05d5 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/TestApplication.groovy +++ b/spring-cloud-kubernetes-ribbon/src/test/groovy/io/fabric8/spring/cloud/kubernetes/ribbon/test/TestApplication.groovy @@ -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. @@ -12,10 +12,10 @@ * 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.kubernetes.ribbon.test + import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.cloud.client.loadbalancer.LoadBalanced @@ -25,13 +25,13 @@ import org.springframework.web.client.RestTemplate @SpringBootApplication class TestApplication { - def main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } + def main(String[] args) { + SpringApplication.run(TestApplication.class, args); + } - @LoadBalanced - @Bean - def RestTemplate restTemplate() { - return new RestTemplate(); - } + @LoadBalanced + @Bean + def RestTemplate restTemplate() { + return new RestTemplate(); + } } diff --git a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKeyTest.java b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKeyTest.java index 0af6418ecb..7d1fc8a694 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKeyTest.java +++ b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/KubernetesConfigKeyTest.java @@ -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. @@ -12,18 +12,15 @@ * 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.kubernetes.ribbon; -import org.junit.Assert; import org.junit.Test; -public class KubernetesConfigKeyTest { +import static org.assertj.core.api.Assertions.assertThat; - private class TypeOne { - } +public class KubernetesConfigKeyTest { @Test public void testTypes() { @@ -39,9 +36,13 @@ public void testTypes() { KubernetesConfigKey key3 = new KubernetesConfigKey("key3") { }; - Assert.assertEquals(String.class, key1.type()); - Assert.assertEquals(TypeOne.class, key2.type()); - Assert.assertEquals(Object.class, key3.type()); + assertThat(key1.type()).isEqualTo(String.class); + assertThat(key2.type()).isEqualTo(TypeOne.class); + assertThat(key3.type()).isEqualTo(Object.class); + } + + private class TypeOne { + } } diff --git a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java index 6964349580..84b76df5a0 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java +++ b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; @@ -25,7 +24,6 @@ import io.fabric8.mockwebserver.DefaultMockServer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; @@ -39,7 +37,8 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; /** * @author Charles Moulliard @@ -54,6 +53,8 @@ @EnableDiscoveryClient public class RibbonFallbackTest { + private static final Log LOG = LogFactory.getLog(RibbonFallbackTest.class); + @ClassRule public static KubernetesServer mockServer = new KubernetesServer(false); @@ -61,7 +62,8 @@ public class RibbonFallbackTest { public static KubernetesClient mockClient; - private static final Log LOG = LogFactory.getLog(RibbonFallbackTest.class); + @Autowired + RestTemplate restTemplate; @Value("${service.occurrence}") private int serviceOccurrence; @@ -69,9 +71,6 @@ public class RibbonFallbackTest { @Value("${testapp.ribbon.ServerListRefreshInterval}") private int serverListRefreshInterval; - @Autowired - RestTemplate restTemplate; - @BeforeClass public static void setUpBefore() throws Exception { mockClient = mockServer.getClient(); @@ -88,6 +87,24 @@ public static void setUpBefore() throws Exception { mockEndpoint.start(); } + public static Endpoints newEndpoint(String name, String namespace, + DefaultMockServer mockServer) { + // @formatter:off + return new EndpointsBuilder() + .withNewMetadata() + .withName(name) + .withNamespace(namespace) + .endMetadata() + .addNewSubset() + .addNewAddress() + .withIp(mockServer.getHostName()) + .endAddress() + .addNewPort("http", mockServer.getPort(), "http") + .endSubset() + .build(); + // @formatter:on + } + @Test public void testFallBackGreetingEndpoint() { /** @@ -105,25 +122,25 @@ public void testFallBackGreetingEndpoint() { // to be sure that Ribbon will get the mockendpoint to access it for the call mockServer.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp") .andReturn(200, newEndpoint("testapp-a", "testns", mockEndpoint)) - .times(serviceOccurrence); + .times(this.serviceOccurrence); mockEndpoint.expect().get().withPath("/greeting").andReturn(200, "Hello from A") .once(); - String response = restTemplate.getForObject("http://testapp/greeting", + String response = this.restTemplate.getForObject("http://testapp/greeting", String.class); - Assert.assertEquals("Hello from A", response); + assertThat(response).isEqualTo("Hello from A"); LOG.info(">>>>>>>>>> END PART 1 <<<<<<<<<<<<<"); LOG.info(">>>>>>>>>> BEGIN PART 2 <<<<<<<<<<<<<"); try { ensureEndpointsNoLongerReturnedByAPIServer(); - restTemplate.getForObject("http://testapp/greeting", String.class); + this.restTemplate.getForObject("http://testapp/greeting", String.class); fail("Ribbon was supposed to throw an Exception due to not knowing of any endpoints to route the request to"); } catch (Exception e) { // No endpoint is available anymore and Ribbon list is empty - Assert.assertEquals("No instances available for testapp", e.getMessage()); + assertThat(e.getMessage()).isEqualTo("No instances available for testapp"); } LOG.info(">>>>>>>>>> END PART 2 <<<<<<<<<<<<<"); @@ -149,8 +166,9 @@ public void testFallBackGreetingEndpoint() { mockEndpoint.expect().get().withPath("/greeting").andReturn(200, "Hello from A") .once(); - response = restTemplate.getForObject("http://testapp/greeting", String.class); - Assert.assertEquals("Hello from A", response); + response = this.restTemplate.getForObject("http://testapp/greeting", + String.class); + assertThat(response).isEqualTo("Hello from A"); LOG.info(">>>>>>>>>> END PART 3 <<<<<<<<<<<<<"); } @@ -160,25 +178,7 @@ public void testFallBackGreetingEndpoint() { // serverListRefreshInterval milliseconds private void ensureEndpointsNoLongerReturnedByAPIServer() throws InterruptedException { - Thread.sleep((serviceOccurrence + 1) * serverListRefreshInterval); - } - - public static Endpoints newEndpoint(String name, String namespace, - DefaultMockServer mockServer) { - // @formatter:off - return new EndpointsBuilder() - .withNewMetadata() - .withName(name) - .withNamespace(namespace) - .endMetadata() - .addNewSubset() - .addNewAddress() - .withIp(mockServer.getHostName()) - .endAddress() - .addNewPort("http", mockServer.getPort(), "http") - .endSubset() - .build(); - // @formatter:on + Thread.sleep((this.serviceOccurrence + 1) * this.serverListRefreshInterval); } } diff --git a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java index a0bfada28f..518ca4543e 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java +++ b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; @@ -102,8 +101,8 @@ public static void setUpBefore() throws Exception { public void testGreetingEndpoint() { List greetings = new ArrayList<>(); for (int i = 0; i < 2; i++) { - greetings.add( - restTemplate.getForObject("http://testapp/greeting", String.class)); + greetings.add(this.restTemplate.getForObject("http://testapp/greeting", + String.class)); } greetings.contains("Hello from A"); greetings.contains("Hello from B"); diff --git a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/TestApplication.java b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/TestApplication.java index bbf631d89b..eb36df544f 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/TestApplication.java +++ b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/TestApplication.java @@ -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. @@ -12,7 +12,6 @@ * 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.kubernetes.ribbon; diff --git a/spring-cloud-kubernetes-ribbon/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-ribbon/src/test/resources/logback-test.xml index 75d20a0a6f..5d1ac6d06a 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/resources/logback-test.xml +++ b/spring-cloud-kubernetes-ribbon/src/test/resources/logback-test.xml @@ -1,6 +1,7 @@ - - - + + + diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index 35cf0f227c..c8b1a496c7 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -16,8 +16,8 @@ ~ --> - spring-cloud-kubernetes diff --git a/spring-cloud-starter-kubernetes-config/pom.xml b/spring-cloud-starter-kubernetes-config/pom.xml index 618a6ac32f..562cb0ea2d 100644 --- a/spring-cloud-starter-kubernetes-config/pom.xml +++ b/spring-cloud-starter-kubernetes-config/pom.xml @@ -16,8 +16,8 @@ ~ --> - spring-cloud-kubernetes diff --git a/spring-cloud-starter-kubernetes-ribbon/pom.xml b/spring-cloud-starter-kubernetes-ribbon/pom.xml index d67286b081..2d9195fe99 100644 --- a/spring-cloud-starter-kubernetes-ribbon/pom.xml +++ b/spring-cloud-starter-kubernetes-ribbon/pom.xml @@ -16,8 +16,8 @@ ~ --> - spring-cloud-kubernetes diff --git a/spring-cloud-starter-kubernetes/pom.xml b/spring-cloud-starter-kubernetes/pom.xml index 1fc3eefdfe..072ea9f1fd 100644 --- a/spring-cloud-starter-kubernetes/pom.xml +++ b/spring-cloud-starter-kubernetes/pom.xml @@ -16,8 +16,8 @@ ~ --> - spring-cloud-kubernetes diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml new file mode 100644 index 0000000000..a32117d2be --- /dev/null +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -0,0 +1,15 @@ + + + + + + + + + +