diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..0679d88a9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = tab +indent_size = 4 +end_of_line = lf +insert_final_newline = true + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 000000000..fa4f7b499 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + 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.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar old mode 100644 new mode 100755 index 5fd4d5023..01e679973 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 6637cedb2..00d32aab1 --- 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.3.9/apache-maven-3.3.9-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/.settings.xml b/.settings.xml index 6c355129e..6f542c940 100644 --- a/.settings.xml +++ b/.settings.xml @@ -1,66 +1,68 @@ - - - repo.spring.io - ${env.CI_DEPLOY_USERNAME} - ${env.CI_DEPLOY_PASSWORD} - - - - - - spring - true - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - http://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - http://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - http://repo.spring.io/libs-milestone-local - - false - - - - - + + + repo.spring.io + ${env.CI_DEPLOY_USERNAME} + ${env.CI_DEPLOY_PASSWORD} + + + + + + spring + + true + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + http://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/libs-milestone-local + + false + + + + + diff --git a/spring-cloud-stream-tools/.jdk8 b/.springformat similarity index 100% rename from spring-cloud-stream-tools/.jdk8 rename to .springformat diff --git a/docs/pom.xml b/docs/pom.xml index 7485e6976..33199fd55 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 spring-cloud-stream-core-docs @@ -15,36 +17,35 @@ ${basedir}/.. - - docs - - - - org.apache.maven.plugins - maven-dependency-plugin - - - org.asciidoctor - asciidoctor-maven-plugin - false - - - com.agilejava.docbkx - docbkx-maven-plugin - - - org.apache.maven.plugins - maven-antrun-plugin - false - - - org.codehaus.mojo - build-helper-maven-plugin - false - - - - - + + docs + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.asciidoctor + asciidoctor-maven-plugin + false + + + com.agilejava.docbkx + docbkx-maven-plugin + + + org.apache.maven.plugins + maven-antrun-plugin + false + + + org.codehaus.mojo + build-helper-maven-plugin + false + + + + + - \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-stream.adoc b/docs/src/main/asciidoc/spring-cloud-stream.adoc index 576f753d0..74021c2d2 100644 --- a/docs/src/main/asciidoc/spring-cloud-stream.adoc +++ b/docs/src/main/asciidoc/spring-cloud-stream.adoc @@ -88,7 +88,7 @@ public class StreamApplicationTests { @Test public void contextLoads() { - assertNotNull(this.sink.input()); + assertThat(this.sink.input()).isNotNull(); } } ---- diff --git a/mvnw b/mvnw index 0a7dac221..5551fde8e 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,30 +195,92 @@ concat_lines() { fi } -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -echo "Running version check" -VERSION=$( sed '\!//' -e 's!.*$!!' ) -echo "The found version is [${VERSION}]" - -if echo $VERSION | egrep -q 'M|RC'; then - echo Activating \"milestone\" profile for version=\"$VERSION\" - echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone" -else - echo Deactivating \"milestone\" profile for version=\"$VERSION\" - echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//') -fi - exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@" + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd old mode 100644 new mode 100755 index fc8302432..48363fa60 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -35,6 +35,8 @@ @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% @@ -80,8 +82,6 @@ goto error :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. @@ -117,11 +117,27 @@ for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do s :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.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% +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 diff --git a/pom.xml b/pom.xml index 6b5a6ef4d..2609cc4f9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,282 +1,276 @@ - - 4.0.0 - spring-cloud-stream-parent - 2.1.1.BUILD-SNAPSHOT - pom - - org.springframework.cloud - spring-cloud-build - 2.1.0.BUILD-SNAPSHOT - - - - https://github.com/spring-cloud/spring-cloud-stream - scm:git:git://github.com/spring-cloud/spring-cloud-stream.git - scm:git:ssh://git@github.com/spring-cloud/spring-cloud-stream.git - HEAD - - - 1.8 - 1.0.0.RELEASE - 1.0.0.RELEASE - Californium-RELEASE - 3.0.3 - 2.1 - 2.0.0.BUILD-SNAPSHOT - - - - - org.springframework.cloud - spring-cloud-function-context - ${spring-cloud-function.version} - - - org.springframework.cloud - spring-cloud-stream - ${project.version} - - - org.springframework.cloud - spring-cloud-stream-tools - ${project.version} - - - org.springframework.cloud - spring-cloud-stream-schema-server - ${project.version} - - - org.springframework.cloud - spring-cloud-stream-binder-test - ${project.version} - - - org.springframework - spring-tuple - ${spring.tuple.version} - - - org.springframework.integration - spring-integration-tuple - ${spring.integration.tuple.version} - - - org.springframework.cloud - spring-cloud-stream-test-support - ${project.version} - - - org.springframework.cloud - spring-cloud-stream-test-support-internal - ${project.version} - - - com.esotericsoftware - kryo-shaded - ${kryo-shaded.version} - - - io.projectreactor - reactor-bom - ${reactor.version} - pom - import - - - org.objenesis - objenesis - ${objenesis.version} - - - org.springframework.cloud - spring-cloud-stream - ${project.version} - test-jar - test - test-binder - - - - - spring-cloud-stream - spring-cloud-stream-binder-test - spring-cloud-stream-test-support - spring-cloud-stream-test-support-internal - spring-cloud-stream-integration-tests - spring-cloud-stream-reactive - spring-cloud-stream-schema - spring-cloud-stream-schema-server - spring-cloud-stream-tools + + 4.0.0 + spring-cloud-stream-parent + 2.1.1.BUILD-SNAPSHOT + pom + + org.springframework.cloud + spring-cloud-build + 2.1.3.BUILD-SNAPSHOT + + + + https://github.com/spring-cloud/spring-cloud-stream + scm:git:git://github.com/spring-cloud/spring-cloud-stream.git + + + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-stream.git + + HEAD + + + 1.8 + 1.0.0.RELEASE + 1.0.0.RELEASE + Californium-RELEASE + 3.0.3 + 2.1 + 2.0.0.BUILD-SNAPSHOT + + + true + true + + true + + + + + + org.springframework.cloud + spring-cloud-function-context + ${spring-cloud-function.version} + + + org.springframework.cloud + spring-cloud-stream + ${project.version} + + + org.springframework.cloud + spring-cloud-stream-tools + ${project.version} + + + org.springframework.cloud + spring-cloud-stream-schema-server + ${project.version} + + + org.springframework.cloud + spring-cloud-stream-binder-test + ${project.version} + + + org.springframework + spring-tuple + ${spring.tuple.version} + + + org.springframework.integration + spring-integration-tuple + ${spring.integration.tuple.version} + + + org.springframework.cloud + spring-cloud-stream-test-support + ${project.version} + + + org.springframework.cloud + spring-cloud-stream-test-support-internal + ${project.version} + + + com.esotericsoftware + kryo-shaded + ${kryo-shaded.version} + + + io.projectreactor + reactor-bom + ${reactor.version} + pom + import + + + org.objenesis + objenesis + ${objenesis.version} + + + org.springframework.cloud + spring-cloud-stream + ${project.version} + test-jar + test + test-binder + + + + + spring-cloud-stream + spring-cloud-stream-binder-test + spring-cloud-stream-test-support + spring-cloud-stream-test-support-internal + spring-cloud-stream-integration-tests + spring-cloud-stream-reactive + spring-cloud-stream-schema + spring-cloud-stream-schema-server docs - - - - - - org.apache.maven.plugins - maven-antrun-plugin - 1.7 - - - org.apache.maven.plugins - maven-checkstyle-plugin - 2.17 - - - com.puppycrawl.tools - checkstyle - 7.1 - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - true - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - - + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - -parameters - + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + -parameters + - - org.apache.maven.plugins - maven-checkstyle-plugin - - - checkstyle-validation - validate - - spring-cloud-stream-tools/src/main/resources/checkstyle.xml - spring-cloud-stream-tools/src/main/resources/checkstyle-header.txt - spring-cloud-stream-tools/src/main/resources/checkstyle-suppressions.xml - UTF-8 - true - true - true - - - check - - - - - - - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/libs-release-local - - false - - - - - - coverage - - - env.TRAVIS - true - - - - - - org.jacoco - jacoco-maven-plugin - 0.7.9 - - - agent - - prepare-agent - - - - report - test - - report - - - - - - - - + + org.apache.maven.plugins + maven-checkstyle-plugin + + + io.spring.javaformat + spring-javaformat-maven-plugin + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + + + + spring + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/libs-snapshot-local + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/libs-snapshot-local + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/libs-release-local + + false + + + + + + coverage + + + env.TRAVIS + true + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.9 + + + agent + + prepare-agent + + + + report + test + + report + + + + + + + + diff --git a/spring-cloud-stream-binder-test/pom.xml b/spring-cloud-stream-binder-test/pom.xml index dcc11a58f..7b94c05a3 100644 --- a/spring-cloud-stream-binder-test/pom.xml +++ b/spring-cloud-stream-binder-test/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 spring-cloud-stream-binder-test diff --git a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractBinderTests.java b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractBinderTests.java index 2d02e4650..7660c83b5 100644 --- a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractBinderTests.java +++ b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractBinderTests.java @@ -63,8 +63,6 @@ import org.springframework.util.MimeTypeUtils; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; /** * @author Gary Russell @@ -76,20 +74,18 @@ import static org.junit.Assert.assertTrue; * @author Jacob Severson * @author Artem Bilan */ +// @checkstyle:off @SuppressWarnings("unchecked") public abstract class AbstractBinderTests, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties> { + // @checkstyle:on + protected final Log logger = LogFactory.getLog(this.getClass()); protected B testBinder; protected SmartMessageConverter messageConverter; - @Before - public void before() { - this.messageConverter = new CompositeMessageConverterFactory().getMessageConverterForAllRegistered(); - } - /** * Subclasses may override this default value to have tests wait longer for a message * receive, for example if running in an environment that is known to be slow (e.g. @@ -97,6 +93,12 @@ public abstract class AbstractBinderTests receive(PollableChannel channel, int additionalMultiplier) { long startTime = System.currentTimeMillis(); Message receive = channel - .receive((int) (1000 * timeoutMultiplier * additionalMultiplier)); + .receive((int) (1000 * this.timeoutMultiplier * additionalMultiplier)); long elapsed = System.currentTimeMillis() - startTime; - logger.debug("receive() took " + elapsed / 1000 + " seconds"); + this.logger.debug("receive() took " + elapsed / 1000 + " seconds"); return receive; } @@ -124,20 +126,25 @@ public abstract class AbstractBinderTests foo0ProducerBinding = binder.bindProducer(String.format("foo%s0", - getDestinationNameDelimiter()), this.createBindableChannel("output", new BindingProperties()), + Binding foo0ProducerBinding = binder.bindProducer( + String.format("foo%s0", getDestinationNameDelimiter()), + this.createBindableChannel("output", new BindingProperties()), createProducerProperties()); - Binding foo0ConsumerBinding = binder.bindConsumer(String.format("foo%s0", - getDestinationNameDelimiter()), "testClean", this.createBindableChannel("input", - new BindingProperties()), createConsumerProperties()); - Binding foo1ProducerBinding = binder.bindProducer(String.format("foo%s1", - getDestinationNameDelimiter()), this.createBindableChannel("output", new BindingProperties()), + Binding foo0ConsumerBinding = binder.bindConsumer( + String.format("foo%s0", getDestinationNameDelimiter()), "testClean", + this.createBindableChannel("input", new BindingProperties()), + createConsumerProperties()); + Binding foo1ProducerBinding = binder.bindProducer( + String.format("foo%s1", getDestinationNameDelimiter()), + this.createBindableChannel("output", new BindingProperties()), createProducerProperties()); - Binding foo1ConsumerBinding = binder.bindConsumer(String.format("foo%s1", - getDestinationNameDelimiter()), "testClean", this.createBindableChannel("input", - new BindingProperties()), createConsumerProperties()); - Binding foo2ProducerBinding = binder.bindProducer(String.format("foo%s2", - getDestinationNameDelimiter()), this.createBindableChannel("output", new BindingProperties()), + Binding foo1ConsumerBinding = binder.bindConsumer( + String.format("foo%s1", getDestinationNameDelimiter()), "testClean", + this.createBindableChannel("input", new BindingProperties()), + createConsumerProperties()); + Binding foo2ProducerBinding = binder.bindProducer( + String.format("foo%s2", getDestinationNameDelimiter()), + this.createBindableChannel("output", new BindingProperties()), createProducerProperties()); foo0ProducerBinding.unbind(); assertThat(TestUtils @@ -165,18 +172,25 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("foo%s0", - getDestinationNameDelimiter()), moduleOutputChannel, outputBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("foo%s0", - getDestinationNameDelimiter()), "testSendAndReceive", moduleInputChannel, inputBindingProperties.getConsumer()); - Message message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE, "text/plain") - .build(); + Binding producerBinding = binder.bindProducer( + String.format("foo%s0", getDestinationNameDelimiter()), + moduleOutputChannel, outputBindingProperties.getProducer()); + Binding consumerBinding = binder.bindConsumer( + String.format("foo%s0", getDestinationNameDelimiter()), + "testSendAndReceive", moduleInputChannel, + inputBindingProperties.getConsumer()); + Message message = MessageBuilder.withPayload("foo") + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build(); // Let the consumer actually bind to the producer before sending a msg binderBindUnbindLatency(); @@ -195,44 +209,39 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("foo%s0x", - getDestinationNameDelimiter()), moduleOutputChannel, outputBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("foo%s0x", - getDestinationNameDelimiter()), "testSendAndReceiveKryo", moduleInputChannel, inputBindingProperties.getConsumer()); + Binding producerBinding = binder.bindProducer( + String.format("foo%s0x", getDestinationNameDelimiter()), + moduleOutputChannel, outputBindingProperties.getProducer()); + Binding consumerBinding = binder.bindConsumer( + String.format("foo%s0x", getDestinationNameDelimiter()), + "testSendAndReceiveKryo", moduleInputChannel, + inputBindingProperties.getConsumer()); Foo foo = new Foo(); foo.setName("Bill"); - Message message = MessageBuilder.withPayload(foo).setHeader(MessageHeaders.CONTENT_TYPE, MessageConverterUtils.X_JAVA_OBJECT) - .build(); + Message message = MessageBuilder.withPayload(foo).setHeader( + MessageHeaders.CONTENT_TYPE, MessageConverterUtils.X_JAVA_OBJECT).build(); // Let the consumer actually bind to the producer before sending a msg binderBindUnbindLatency(); @@ -252,34 +261,41 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("foo%s0y", - getDestinationNameDelimiter()), moduleOutputChannel, outputBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("foo%s0y", getDestinationNameDelimiter()), + moduleOutputChannel, outputBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("foo%s0y", - getDestinationNameDelimiter()), "testSendAndReceiveJavaSerialization", moduleInputChannel, + Binding consumerBinding = binder.bindConsumer( + String.format("foo%s0y", getDestinationNameDelimiter()), + "testSendAndReceiveJavaSerialization", moduleInputChannel, inputBindingProperties.getConsumer()); SerializableFoo foo = new SerializableFoo(); - Message message = - MessageBuilder.withPayload(foo) - .setHeader(MessageHeaders.CONTENT_TYPE, MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT) - .build(); + Message message = MessageBuilder.withPayload(foo) + .setHeader(MessageHeaders.CONTENT_TYPE, + MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT) + .build(); // Let the consumer actually bind to the producer before sending a msg binderBindUnbindLatency(); @@ -298,10 +314,13 @@ public abstract class AbstractBinderTests producerBinding1 = binder.bindProducer(String.format("foo%sxy", - getDestinationNameDelimiter()), moduleOutputChannel1, producerBindingProperties.getProducer()); - Binding producerBinding2 = binder.bindProducer(String.format("foo%syz", + Binding producerBinding1 = binder.bindProducer( + String.format("foo%sxy", getDestinationNameDelimiter()), + moduleOutputChannel1, producerBindingProperties.getProducer()); + Binding producerBinding2 = binder.bindProducer( + String.format("foo%syz", - getDestinationNameDelimiter()), moduleOutputChannel2, producerBindingProperties.getProducer()); + getDestinationNameDelimiter()), + moduleOutputChannel2, producerBindingProperties.getProducer()); - Binding consumerBinding1 = binder.bindConsumer(String.format("foo%sxy", - getDestinationNameDelimiter()), "testSendAndReceiveMultipleTopics", moduleInputChannel, + Binding consumerBinding1 = binder.bindConsumer( + String.format("foo%sxy", getDestinationNameDelimiter()), + "testSendAndReceiveMultipleTopics", moduleInputChannel, createConsumerProperties()); - Binding consumerBinding2 = binder.bindConsumer(String.format("foo%syz", - getDestinationNameDelimiter()), "testSendAndReceiveMultipleTopics", moduleInputChannel, + Binding consumerBinding2 = binder.bindConsumer( + String.format("foo%syz", getDestinationNameDelimiter()), + "testSendAndReceiveMultipleTopics", moduleInputChannel, createConsumerProperties()); String testPayload1 = "foo" + UUID.randomUUID().toString(); @@ -373,12 +400,16 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("bar%s0", - getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("bar%s0", - getDestinationNameDelimiter()), "testSendAndReceiveNoOriginalContentType", moduleInputChannel, + BindingProperties inputBindingProperties = createConsumerBindingProperties( + createConsumerProperties()); + DirectChannel moduleInputChannel = createBindableChannel("input", + inputBindingProperties); + Binding producerBinding = binder.bindProducer( + String.format("bar%s0", getDestinationNameDelimiter()), + moduleOutputChannel, producerBindingProperties.getProducer()); + Binding consumerBinding = binder.bindConsumer( + String.format("bar%s0", getDestinationNameDelimiter()), + "testSendAndReceiveNoOriginalContentType", moduleInputChannel, createConsumerProperties()); binderBindUnbindLatency(); @@ -400,8 +431,8 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("bad%s0a", - getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("bad%s0a", getDestinationNameDelimiter()), + moduleOutputChannel, producerBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("bad%s0a", - getDestinationNameDelimiter()), "test-1", moduleInputChannel, consumerBindingProperties.getConsumer()); + Binding consumerBinding = binder.bindConsumer( + String.format("bad%s0a", getDestinationNameDelimiter()), "test-1", + moduleInputChannel, consumerBindingProperties.getConsumer()); Station station = new Station(); Message message = MessageBuilder.withPayload(station).build(); @@ -530,7 +573,7 @@ public abstract class AbstractBinderTests replyMessage = replyChannel.receive(5000); - assertTrue(replyMessage.getPayload() instanceof Station); + assertThat(replyMessage.getPayload() instanceof Station).isTrue(); producerBinding.unbind(); consumerBinding.unbind(); } @@ -543,19 +586,25 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("bad%s0b", - getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("bad%s0b", getDestinationNameDelimiter()), + moduleOutputChannel, producerBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("bad%s0b", - getDestinationNameDelimiter()), "test-2", moduleInputChannel, consumerBindingProperties.getConsumer()); + Binding consumerBinding = binder.bindConsumer( + String.format("bad%s0b", getDestinationNameDelimiter()), "test-2", + moduleInputChannel, consumerBindingProperties.getConsumer()); Station station = new Station(); Message message = MessageBuilder.withPayload(station).setHeader( @@ -566,7 +615,7 @@ public abstract class AbstractBinderTests replyMessage = replyChannel.receive(5000); - assertTrue(replyMessage.getPayload() instanceof Station); + assertThat(replyMessage.getPayload() instanceof Station).isTrue(); producerBinding.unbind(); consumerBinding.unbind(); } @@ -576,19 +625,25 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("bad%s0c", - getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("bad%s0c", getDestinationNameDelimiter()), + moduleOutputChannel, producerBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("bad%s0c", - getDestinationNameDelimiter()), "test-3", moduleInputChannel, consumerBindingProperties.getConsumer()); + Binding consumerBinding = binder.bindConsumer( + String.format("bad%s0c", getDestinationNameDelimiter()), "test-3", + moduleInputChannel, consumerBindingProperties.getConsumer()); try { Station station = new Station(); Message message = MessageBuilder.withPayload(station) @@ -610,22 +665,29 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("bad%s0d", - getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("bad%s0d", getDestinationNameDelimiter()), + moduleOutputChannel, producerBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("bad%s0d", - getDestinationNameDelimiter()), "test-4", moduleInputChannel, consumerBindingProperties.getConsumer()); + Binding consumerBinding = binder.bindConsumer( + String.format("bad%s0d", getDestinationNameDelimiter()), "test-4", + moduleInputChannel, consumerBindingProperties.getConsumer()); String value = "{\"readings\":[{\"stationid\":\"fgh\"," - + "\"customerid\":\"12345\",\"timestamp\":null},{\"stationid\":\"hjk\",\"customerid\":\"222\",\"timestamp\":null}]}"; + + "\"customerid\":\"12345\",\"timestamp\":null}," + + "{\"stationid\":\"hjk\",\"customerid\":\"222\",\"timestamp\":null}]}"; Message message = MessageBuilder.withPayload(value) .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON) @@ -637,8 +699,8 @@ public abstract class AbstractBinderTests reply = (Message) channel.receive(5000); - assertNotNull(reply); - assertTrue(reply.getPayload() instanceof Station); + assertThat(reply).isNotNull(); + assertThat(reply.getPayload() instanceof Station).isTrue(); producerBinding.unbind(); consumerBinding.unbind(); } @@ -650,22 +712,29 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("bad%s0e", - getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("bad%s0e", getDestinationNameDelimiter()), + moduleOutputChannel, producerBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("bad%s0e", - getDestinationNameDelimiter()), "test-5", moduleInputChannel, consumerBindingProperties.getConsumer()); + Binding consumerBinding = binder.bindConsumer( + String.format("bad%s0e", getDestinationNameDelimiter()), "test-5", + moduleInputChannel, consumerBindingProperties.getConsumer()); String value = "{\"readings\":[{\"stationid\":\"fgh\"," - + "\"customerid\":\"12345\",\"timestamp\":null},{\"stationid\":\"hjk\",\"customerid\":\"222\",\"timestamp\":null}]}"; + + "\"customerid\":\"12345\",\"timestamp\":null}," + + "{\"stationid\":\"hjk\",\"customerid\":\"222\",\"timestamp\":null}]}"; Message message = MessageBuilder.withPayload(value) .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON) @@ -677,8 +746,8 @@ public abstract class AbstractBinderTests reply = (Message) channel.receive(5000); - assertNotNull(reply); - assertTrue(reply.getPayload() instanceof String); + assertThat(reply).isNotNull(); + assertThat(reply.getPayload() instanceof String).isTrue(); producerBinding.unbind(); consumerBinding.unbind(); } @@ -690,19 +759,25 @@ public abstract class AbstractBinderTests producerBinding = binder.bindProducer(String.format("bad%s0f", - getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("bad%s0f", getDestinationNameDelimiter()), + moduleOutputChannel, producerBindingProperties.getProducer()); - Binding consumerBinding = binder.bindConsumer(String.format("bad%s0f", - getDestinationNameDelimiter()), "test-6", moduleInputChannel, consumerBindingProperties.getConsumer()); + Binding consumerBinding = binder.bindConsumer( + String.format("bad%s0f", getDestinationNameDelimiter()), "test-6", + moduleInputChannel, consumerBindingProperties.getConsumer()); Readings r1 = new Readings(); r1.setCustomerid("123"); @@ -722,8 +797,8 @@ public abstract class AbstractBinderTests reply = (Message) channel.receive(5000); - assertNotNull(reply); - assertTrue(reply.getPayload() instanceof Station); + assertThat(reply).isNotNull(); + assertThat(reply.getPayload() instanceof Station).isTrue(); producerBinding.unbind(); consumerBinding.unbind(); } @@ -756,7 +831,7 @@ public abstract class AbstractBinderTests readings = new ArrayList<>(); public List getReadings() { - return readings; + return this.readings; } public void setReadings(List readings) { @@ -786,7 +861,7 @@ public abstract class AbstractBinderTests binder type + * @param consumer properties type + * @param producer properties type * @author Gary Russell * @since 2.0 - * */ -public abstract class AbstractPollableConsumerTestBinder, - CP extends ConsumerProperties, PP extends ProducerProperties> extends AbstractTestBinder - implements PollableConsumerBinder{ +// @checkstyle:off +public abstract class AbstractPollableConsumerTestBinder, CP extends ConsumerProperties, PP extends ProducerProperties> + extends AbstractTestBinder + implements PollableConsumerBinder { + + // @checkstyle:on private PollableConsumerBinder binder; @SuppressWarnings("unchecked") - public void setPollableConsumerBinder(PollableConsumerBinder binder) { + public void setPollableConsumerBinder( + PollableConsumerBinder binder) { super.setBinder((C) binder); this.binder = binder; } @Override - public Binding> bindPollableConsumer(String name, String group, - PollableSource inboundBindTarget, CP consumerProperties) { - return this.binder.bindPollableConsumer(name, group, inboundBindTarget, consumerProperties); + public Binding> bindPollableConsumer(String name, + String group, PollableSource inboundBindTarget, + CP consumerProperties) { + return this.binder.bindPollableConsumer(name, group, inboundBindTarget, + consumerProperties); } } diff --git a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractTestBinder.java b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractTestBinder.java index 46f8e6041..afe51db2c 100644 --- a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractTestBinder.java +++ b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractTestBinder.java @@ -16,7 +16,6 @@ package org.springframework.cloud.stream.binder; - import java.util.HashSet; import java.util.Set; @@ -28,34 +27,41 @@ import org.springframework.util.CollectionUtils; /** * Abstract class that adds test support for {@link Binder}. * + * @param binder type + * @param consumer properties type + * @param producer properties type * @author Ilayaperumal Gopinathan * @author Gary Russell * @author Mark Fisher * @author Oleg Zhurakousky */ +// @checkstyle:off public abstract class AbstractTestBinder, CP extends ConsumerProperties, PP extends ProducerProperties> implements Binder { + // @checkstyle:on + protected Set queues = new HashSet(); private C binder; @Override - public Binding bindConsumer(String name, String group, MessageChannel moduleInputChannel, - CP properties) { + public Binding bindConsumer(String name, String group, + MessageChannel moduleInputChannel, CP properties) { this.checkChannelIsConfigured(moduleInputChannel, properties); - queues.add(name); - return binder.bindConsumer(name, group, moduleInputChannel, properties); + this.queues.add(name); + return this.binder.bindConsumer(name, group, moduleInputChannel, properties); } @Override - public Binding bindProducer(String name, MessageChannel moduleOutputChannel, PP properties) { - queues.add(name); - return binder.bindProducer(name, moduleOutputChannel, properties); + public Binding bindProducer(String name, + MessageChannel moduleOutputChannel, PP properties) { + this.queues.add(name); + return this.binder.bindProducer(name, moduleOutputChannel, properties); } public C getCoreBinder() { - return binder; + return this.binder; } public abstract void cleanup(); @@ -76,13 +82,19 @@ public abstract class AbstractTestBinder propertiesToAdd = new HashMap<>(); - propertiesToAdd.put("logging.pattern.console", "%d{ISO8601} %5p %t %c{2}:%L - %m%n"); + propertiesToAdd.put("logging.pattern.console", + "%d{ISO8601} %5p %t %c{2}:%L - %m%n"); propertiesToAdd.put("logging.level.root", "WARN"); - environment.getPropertySources().addLast(new MapPropertySource("binderTestPropertiesConfig", propertiesToAdd)); + environment.getPropertySources().addLast( + new MapPropertySource("binderTestPropertiesConfig", propertiesToAdd)); } + } diff --git a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/BinderTestUtils.java b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/BinderTestUtils.java index e4874f621..0cc9830cc 100644 --- a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/BinderTestUtils.java +++ b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/BinderTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,21 +26,30 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** - * * @author Gary Russell */ public abstract class BinderTestUtils { - public static final AbstractApplicationContext MOCK_AC = mock(AbstractApplicationContext.class); + /** + * Mocked application context. + */ + public static final AbstractApplicationContext MOCK_AC = mock( + AbstractApplicationContext.class); - public static final ConfigurableListableBeanFactory MOCK_BF = mock(ConfigurableListableBeanFactory.class); + /** + * Mocked application bean factory. + */ + public static final ConfigurableListableBeanFactory MOCK_BF = mock( + ConfigurableListableBeanFactory.class); private static final MessageBuilderFactory mbf = new MutableMessageBuilderFactory(); static { - when(MOCK_BF.getBean(IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME, + when(MOCK_BF.getBean( + IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME, MessageBuilderFactory.class)).thenReturn(mbf); - when(MOCK_AC.getBean(IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME, + when(MOCK_AC.getBean( + IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME, MessageBuilderFactory.class)).thenReturn(mbf); when(MOCK_AC.getBeanFactory()).thenReturn(MOCK_BF); } diff --git a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/PartitionCapableBinderTests.java b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/PartitionCapableBinderTests.java index c0b2219c1..cec011d27 100644 --- a/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/PartitionCapableBinderTests.java +++ b/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/PartitionCapableBinderTests.java @@ -46,30 +46,39 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Marius Bogoevici * @author Vinicius Carvalho */ +// @checkstyle:off public abstract class PartitionCapableBinderTests, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties> extends AbstractBinderTests { + // @checkstyle:on + protected static final SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); @Test @SuppressWarnings("unchecked") public void testAnonymousGroup() throws Exception { B binder = getBinder(); - BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties()); + BindingProperties producerBindingProperties = createProducerBindingProperties( + createProducerProperties()); DirectChannel output = createBindableChannel("output", producerBindingProperties); - Binding producerBinding = binder.bindProducer(String.format("defaultGroup%s0", - getDestinationNameDelimiter()), output, (PP) producerBindingProperties.getProducer()); + Binding producerBinding = binder.bindProducer( + String.format("defaultGroup%s0", getDestinationNameDelimiter()), output, + (PP) producerBindingProperties.getProducer()); QueueChannel input1 = new QueueChannel(); - Binding binding1 = binder.bindConsumer(String.format("defaultGroup%s0", - getDestinationNameDelimiter()), null, input1, createConsumerProperties()); + Binding binding1 = binder.bindConsumer( + String.format("defaultGroup%s0", getDestinationNameDelimiter()), null, + input1, createConsumerProperties()); QueueChannel input2 = new QueueChannel(); - Binding binding2 = binder.bindConsumer(String.format("defaultGroup%s0", - getDestinationNameDelimiter()), null, input2, createConsumerProperties()); + Binding binding2 = binder.bindConsumer( + String.format("defaultGroup%s0", getDestinationNameDelimiter()), null, + input2, createConsumerProperties()); String testPayload1 = "foo-" + UUID.randomUUID().toString(); - output.send(MessageBuilder.withPayload(testPayload1).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build()); + output.send(MessageBuilder.withPayload(testPayload1) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); Message receivedMessage1 = (Message) receive(input1); assertThat(receivedMessage1).isNotNull(); @@ -82,12 +91,17 @@ public abstract class PartitionCapableBinderTests) receive(input1); assertThat(receivedMessage1).isNotNull(); @@ -109,23 +123,29 @@ public abstract class PartitionCapableBinderTests producerBinding = binder.bindProducer(testDestination, output, producerProperties); + Binding producerBinding = binder.bindProducer(testDestination, + output, producerProperties); String testPayload = "foo-" + UUID.randomUUID().toString(); - output.send(MessageBuilder.withPayload(testPayload).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build()); + output.send(MessageBuilder.withPayload(testPayload) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); QueueChannel inbound1 = new QueueChannel(); - Binding consumerBinding = binder.bindConsumer(testDestination, "test1", inbound1, - createConsumerProperties()); + Binding consumerBinding = binder.bindConsumer(testDestination, + "test1", inbound1, createConsumerProperties()); Message receivedMessage1 = receive(inbound1); assertThat(receivedMessage1).isNotNull(); - assertThat(new String((byte[]) receivedMessage1.getPayload())).isEqualTo(testPayload); + assertThat(new String((byte[]) receivedMessage1.getPayload())) + .isEqualTo(testPayload); producerBinding.unbind(); consumerBinding.unbind(); @@ -136,29 +156,36 @@ public abstract class PartitionCapableBinderTests producerBinding = binder.bindProducer(testDestination, output, producerProperties); + Binding producerBinding = binder.bindProducer(testDestination, + output, producerProperties); String testPayload = "foo-" + UUID.randomUUID().toString(); - output.send(MessageBuilder.withPayload(testPayload).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build()); + output.send(MessageBuilder.withPayload(testPayload) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); QueueChannel inbound1 = new QueueChannel(); - Binding consumerBinding1 = binder.bindConsumer(testDestination, "test1", inbound1, - createConsumerProperties()); + Binding consumerBinding1 = binder.bindConsumer(testDestination, + "test1", inbound1, createConsumerProperties()); QueueChannel inbound2 = new QueueChannel(); - Binding consumerBinding2 = binder.bindConsumer(testDestination, "test2", inbound2, - createConsumerProperties()); + Binding consumerBinding2 = binder.bindConsumer(testDestination, + "test2", inbound2, createConsumerProperties()); Message receivedMessage1 = receive(inbound1); assertThat(receivedMessage1).isNotNull(); - assertThat(new String((byte[]) receivedMessage1.getPayload())).isEqualTo(testPayload); + assertThat(new String((byte[]) receivedMessage1.getPayload())) + .isEqualTo(testPayload); Message receivedMessage2 = receive(inbound2); assertThat(receivedMessage2).isNotNull(); - assertThat(new String((byte[]) receivedMessage2.getPayload())).isEqualTo(testPayload); + assertThat(new String((byte[]) receivedMessage2.getPayload())) + .isEqualTo(testPayload); consumerBinding1.unbind(); consumerBinding2.unbind(); @@ -176,28 +203,35 @@ public abstract class PartitionCapableBinderTests input0Binding = binder.bindConsumer(String.format("part%s0", - getDestinationNameDelimiter()), "testPartitionedModuleSpEL", input0, consumerProperties); + Binding input0Binding = binder.bindConsumer( + String.format("part%s0", getDestinationNameDelimiter()), + "testPartitionedModuleSpEL", input0, consumerProperties); consumerProperties.setInstanceIndex(1); QueueChannel input1 = new QueueChannel(); input1.setBeanName("test.input1S"); - Binding input1Binding = binder.bindConsumer(String.format("part%s0", - getDestinationNameDelimiter()), "testPartitionedModuleSpEL", input1, consumerProperties); + Binding input1Binding = binder.bindConsumer( + String.format("part%s0", getDestinationNameDelimiter()), + "testPartitionedModuleSpEL", input1, consumerProperties); consumerProperties.setInstanceIndex(2); QueueChannel input2 = new QueueChannel(); input2.setBeanName("test.input2S"); - Binding input2Binding = binder.bindConsumer(String.format("part%s0", - getDestinationNameDelimiter()), "testPartitionedModuleSpEL", input2, consumerProperties); + Binding input2Binding = binder.bindConsumer( + String.format("part%s0", getDestinationNameDelimiter()), + "testPartitionedModuleSpEL", input2, consumerProperties); PP producerProperties = createProducerProperties(); - producerProperties.setPartitionKeyExpression(spelExpressionParser.parseExpression("payload")); - producerProperties.setPartitionSelectorExpression(spelExpressionParser.parseExpression("hashCode()")); + producerProperties.setPartitionKeyExpression( + spelExpressionParser.parseExpression("payload")); + producerProperties.setPartitionSelectorExpression( + spelExpressionParser.parseExpression("hashCode()")); producerProperties.setPartitionCount(3); - DirectChannel output = createBindableChannel("output", createProducerBindingProperties(producerProperties)); + DirectChannel output = createBindableChannel("output", + createProducerBindingProperties(producerProperties)); output.setBeanName("test.output"); - Binding outputBinding = binder.bindProducer(String.format("part%s0", - getDestinationNameDelimiter()), output, producerProperties); + Binding outputBinding = binder.bindProducer( + String.format("part%s0", getDestinationNameDelimiter()), output, + producerProperties); try { Object endpoint = extractEndpoint(outputBinding); checkRkExpressionForPartitionedModuleSpEL(endpoint); @@ -207,12 +241,16 @@ public abstract class PartitionCapableBinderTests message2 = MessageBuilder.withPayload("2") .setHeader(IntegrationMessageHeaderAccessor.CORRELATION_ID, "foo") - .setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.TEXT_PLAIN) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) .setHeader(IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER, 42) .setHeader(IntegrationMessageHeaderAccessor.SEQUENCE_SIZE, 43).build(); output.send(message2); - output.send(MessageBuilder.withPayload("1").setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.TEXT_PLAIN).build()); - output.send(MessageBuilder.withPayload("0").setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.TEXT_PLAIN).build()); + output.send(MessageBuilder.withPayload("1") + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); + output.send(MessageBuilder.withPayload("0") + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); Message receive0 = receive(input0); assertThat(receive0).isNotNull(); @@ -224,8 +262,10 @@ public abstract class PartitionCapableBinderTests> correlationHeadersForPayload2 = new Condition>() { @Override public boolean matches(Message value) { - IntegrationMessageHeaderAccessor accessor = new IntegrationMessageHeaderAccessor(value); - return "foo".equals(accessor.getCorrelationId()) && 42 == accessor.getSequenceNumber() + IntegrationMessageHeaderAccessor accessor = new IntegrationMessageHeaderAccessor( + value); + return "foo".equals(accessor.getCorrelationId()) + && 42 == accessor.getSequenceNumber() && 43 == accessor.getSequenceSize(); } }; @@ -237,8 +277,10 @@ public abstract class PartitionCapableBinderTests> receivedMessages = Arrays.asList(receive0, receive1, receive2); - assertThat(receivedMessages).extracting("payload").containsExactlyInAnyOrder("0".getBytes(), "1".getBytes(), "2".getBytes()); + List> receivedMessages = Arrays.asList(receive0, receive1, + receive2); + assertThat(receivedMessages).extracting("payload").containsExactlyInAnyOrder( + "0".getBytes(), "1".getBytes(), "2".getBytes()); Condition> payloadIs2 = new Condition>() { @Override @@ -246,7 +288,8 @@ public abstract class PartitionCapableBinderTests input0Binding = binder.bindConsumer(String.format("partJ%s0", - getDestinationNameDelimiter()), "testPartitionedModuleJava", input0, consumerProperties); + Binding input0Binding = binder.bindConsumer( + String.format("partJ%s0", getDestinationNameDelimiter()), + "testPartitionedModuleJava", input0, consumerProperties); consumerProperties.setInstanceIndex(1); QueueChannel input1 = new QueueChannel(); input1.setBeanName("test.input1J"); - Binding input1Binding = binder.bindConsumer(String.format("partJ%s0", - getDestinationNameDelimiter()), "testPartitionedModuleJava", input1, consumerProperties); + Binding input1Binding = binder.bindConsumer( + String.format("partJ%s0", getDestinationNameDelimiter()), + "testPartitionedModuleJava", input1, consumerProperties); consumerProperties.setInstanceIndex(2); QueueChannel input2 = new QueueChannel(); input2.setBeanName("test.input2J"); - Binding input2Binding = binder.bindConsumer(String.format("partJ%s0", - getDestinationNameDelimiter()), "testPartitionedModuleJava", input2, consumerProperties); + Binding input2Binding = binder.bindConsumer( + String.format("partJ%s0", getDestinationNameDelimiter()), + "testPartitionedModuleJava", input2, consumerProperties); PP producerProperties = createProducerProperties(); producerProperties.setPartitionKeyExtractorClass(PartitionTestSupport.class); producerProperties.setPartitionSelectorClass(PartitionTestSupport.class); producerProperties.setPartitionCount(3); - DirectChannel output = createBindableChannel("output", createProducerBindingProperties(producerProperties)); + DirectChannel output = createBindableChannel("output", + createProducerBindingProperties(producerProperties)); output.setBeanName("test.output"); - Binding outputBinding = binder.bindProducer("partJ.0", output, producerProperties); + Binding outputBinding = binder.bindProducer("partJ.0", output, + producerProperties); if (usesExplicitRouting()) { Object endpoint = extractEndpoint(outputBinding); - assertThat(getEndpointRouting(endpoint)).contains(getExpectedRoutingBaseDestination( - String.format("partJ%s0", getDestinationNameDelimiter()), "testPartitionedModuleJava") - + "-' + headers['" + BinderHeaders.PARTITION_HEADER + "']"); + assertThat(getEndpointRouting(endpoint)) + .contains(getExpectedRoutingBaseDestination( + String.format("partJ%s0", getDestinationNameDelimiter()), + "testPartitionedModuleJava") + "-' + headers['" + + BinderHeaders.PARTITION_HEADER + "']"); } - output.send(MessageBuilder.withPayload("2").setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.TEXT_PLAIN).build()); - output.send(MessageBuilder.withPayload("1").setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.TEXT_PLAIN).build()); - output.send(MessageBuilder.withPayload("0").setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.TEXT_PLAIN).build()); + output.send(MessageBuilder.withPayload("2") + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); + output.send(MessageBuilder.withPayload("1") + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); + output.send(MessageBuilder.withPayload("0") + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build()); Message receive0 = receive(input0); assertThat(receive0).isNotNull(); @@ -317,8 +374,10 @@ public abstract class PartitionCapableBinderTests> receivedMessages = Arrays.asList(receive0, receive1, receive2); - assertThat(receivedMessages).extracting("payload").containsExactlyInAnyOrder("0".getBytes(), "1".getBytes(), "2".getBytes()); + List> receivedMessages = Arrays.asList(receive0, receive1, + receive2); + assertThat(receivedMessages).extracting("payload").containsExactlyInAnyOrder( + "0".getBytes(), "1".getBytes(), "2".getBytes()); } input0Binding.unbind(); @@ -358,4 +417,5 @@ public abstract class PartitionCapableBinderTests - + 4.0.0 spring-cloud-stream-integration-tests diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/ContentTypeOutboundSourceTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/ContentTypeOutboundSourceTests.java index 2be956abd..2d805c850 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/ContentTypeOutboundSourceTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/ContentTypeOutboundSourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. @@ -53,11 +53,13 @@ public class ContentTypeOutboundSourceTests { @Test @SuppressWarnings("unchecked") public void testMessageHeaderWhenNoExplicitContentTypeOnMessage() throws Exception { - testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build()); - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, - MessageChannel.class)) - .messageCollector().forChannel(testSource.output()).poll(); - assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()).contains("text/plain"); + this.testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}") + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build()); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testSource.output()).poll(); + assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()) + .contains("text/plain"); assertThat("{\"message\":\"Hi\"}").isEqualTo(received.getPayload()); } @@ -67,4 +69,5 @@ public class ContentTypeOutboundSourceTests { public static class TestSource { } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomHeaderPropagationTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomHeaderPropagationTests.java index 83c534368..502ced321 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomHeaderPropagationTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomHeaderPropagationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -42,11 +42,13 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Oleg Zhurakousky */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = CustomHeaderPropagationTests.HeaderPropagationProcessor.class, - webEnvironment = SpringBootTest.WebEnvironment.NONE, - properties = {"spring.cloud.stream.integration.messageHandlerNotPropagatedHeaders=bar,contentType"}) +// @checkstyle:off +@SpringBootTest(classes = CustomHeaderPropagationTests.HeaderPropagationProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = { + "spring.cloud.stream.integration.messageHandlerNotPropagatedHeaders=bar,contentType" }) public class CustomHeaderPropagationTests { + // @checkstyle:on + @Autowired private Processor testProcessor; @@ -55,19 +57,19 @@ public class CustomHeaderPropagationTests { @Test /** - * @since 2.0 The behavior of content type handling has changed. - * All input/output channels have a default content type of application/json - * When a processor or a source returns a String, and if the content type is json it will be quoted + * @since 2.0 The behavior of content type handling has changed. All input/output + * channels have a default content type of application/json When a processor or a + * source returns a String, and if the content type is json it will be quoted */ public void testCustomHeaderPropagation() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}") + this.testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}") .setHeader(MessageHeaders.CONTENT_TYPE, "application/json") - .setHeader("foo", "fooValue") - .setHeader("bar", "barValue") - .build()); + .setHeader("foo", "fooValue").setHeader("bar", "barValue").build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(10, TimeUnit.SECONDS); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(10, TimeUnit.SECONDS); assertThat(received).isNotNull(); assertThat(received.getHeaders()).containsEntry("foo", "fooValue"); assertThat(received.getHeaders()).doesNotContainKey("bar"); @@ -81,9 +83,12 @@ public class CustomHeaderPropagationTests { @ServiceActivator(inputChannel = "input", outputChannel = "output") public Message consume(String data) { - //if we don't force content to be String, it will be quoted on the outbound channel - return MessageBuilder.withPayload(data).setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build(); + // if we don't force content to be String, it will be quoted on the outbound + // channel + return MessageBuilder.withPayload(data) + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build(); } } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomMessageConverterTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomMessageConverterTests.java index bd0bc4f33..b01f714e3 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomMessageConverterTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/CustomMessageConverterTests.java @@ -19,7 +19,6 @@ package org.springframework.cloud.stream.config; import java.util.List; import java.util.concurrent.TimeUnit; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,7 +43,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.MimeType; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.notNullValue; /** * @author Ilayaperumal Gopinathan @@ -66,16 +64,17 @@ public class CustomMessageConverterTests { @Test public void testCustomMessageConverter() throws Exception { - assertThat(customMessageConverters).hasSize(2); - assertThat(customMessageConverters).extracting("class").contains(FooConverter.class, - BarConverter.class); - testSource.output().send(MessageBuilder.withPayload(new Foo("hi")).build()); + assertThat(this.customMessageConverters).hasSize(2); + assertThat(this.customMessageConverters).extracting("class") + .contains(FooConverter.class, BarConverter.class); + this.testSource.output().send(MessageBuilder.withPayload(new Foo("hi")).build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, - MessageChannel.class)) - .messageCollector().forChannel(testSource.output()).poll(1, TimeUnit.SECONDS); - Assert.assertThat(received, notNullValue()); - assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(MimeType.valueOf("test/foo")); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testSource.output()).poll(1, TimeUnit.SECONDS); + assertThat(received).isNotNull(); + assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeType.valueOf("test/foo")); } @EnableBinding(Source.class) @@ -95,6 +94,7 @@ public class CustomMessageConverterTests { public MessageConverter barConverter() { return new BarConverter(); } + } public static class FooConverter extends AbstractMessageConverter { @@ -109,7 +109,8 @@ public class CustomMessageConverterTests { } @Override - protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + protected Object convertToInternal(Object payload, MessageHeaders headers, + Object conversionHint) { Object result = null; try { if (payload instanceof Foo) { @@ -118,11 +119,12 @@ public class CustomMessageConverterTests { } } catch (Exception e) { - logger.error(e.getMessage(), e); + this.logger.error(e.getMessage(), e); return null; } return result; } + } public static class BarConverter extends AbstractMessageConverter { @@ -137,7 +139,8 @@ public class CustomMessageConverterTests { } @Override - protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + protected Object convertToInternal(Object payload, MessageHeaders headers, + Object conversionHint) { Object result = null; try { if (payload instanceof Bar) { @@ -146,11 +149,12 @@ public class CustomMessageConverterTests { } } catch (Exception e) { - logger.error(e.getMessage(), e); + this.logger.error(e.getMessage(), e); return null; } return result; } + } public static class Foo { @@ -170,5 +174,7 @@ public class CustomMessageConverterTests { public Bar(String testing) { this.testing = testing; } + } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationTests.java index 32657c4ff..baab08ae1 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -42,10 +42,11 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Oleg Zhurakousky */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = DefaultHeaderPropagationTests.HeaderPropagationProcessor.class, - webEnvironment = SpringBootTest.WebEnvironment.NONE) +// @checkstyle:off +@SpringBootTest(classes = DefaultHeaderPropagationTests.HeaderPropagationProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) public class DefaultHeaderPropagationTests { + // @checkstyle:on @Autowired private Processor testProcessor; @@ -54,14 +55,14 @@ public class DefaultHeaderPropagationTests { @Test public void testDefaultHeaderPropagation() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}") + this.testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}") .setHeader(MessageHeaders.CONTENT_TYPE, "application/json") - .setHeader("foo", "fooValue") - .setHeader("bar", "barValue") - .build()); + .setHeader("foo", "fooValue").setHeader("bar", "barValue").build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); assertThat(received).isNotNull(); assertThat(received.getHeaders()).containsEntry("foo", "fooValue"); assertThat(received.getHeaders()).containsEntry("bar", "barValue"); @@ -75,8 +76,10 @@ public class DefaultHeaderPropagationTests { @ServiceActivator(inputChannel = "input", outputChannel = "output") public Message consume(String data) { - return MessageBuilder.withPayload(data).setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build(); + return MessageBuilder.withPayload(data) + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build(); } } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationWithApplicationProvidedHeaderTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationWithApplicationProvidedHeaderTests.java index 9cbe974c8..8f6207d3b 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationWithApplicationProvidedHeaderTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DefaultHeaderPropagationWithApplicationProvidedHeaderTests.java @@ -35,17 +35,19 @@ import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHeaders; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Marius Bogoevici * @author Oleg Zhurakousky */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = DefaultHeaderPropagationWithApplicationProvidedHeaderTests.HeaderPropagationProcessor.class, - webEnvironment = SpringBootTest.WebEnvironment.NONE) +// @checkstyle:off +@SpringBootTest(classes = DefaultHeaderPropagationWithApplicationProvidedHeaderTests.HeaderPropagationProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) public class DefaultHeaderPropagationWithApplicationProvidedHeaderTests { + // @checkstyle:on + @Autowired private Processor testProcessor; @@ -54,16 +56,16 @@ public class DefaultHeaderPropagationWithApplicationProvidedHeaderTests { @Test public void testHeaderPropagationIfSetByApplication() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}") + this.testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}") .setHeader(MessageHeaders.CONTENT_TYPE, "application/json") - .setHeader("foo", "fooValue") - .setHeader("bar", "barValue") - .build()); + .setHeader("foo", "fooValue").setHeader("bar", "barValue").build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); - assertEquals("fooValue", received.getHeaders().get("foo")); - assertEquals("barValue", received.getHeaders().get("bar")); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); + assertThat(received.getHeaders().get("foo")).isEqualTo("fooValue"); + assertThat(received.getHeaders().get("bar")).isEqualTo("barValue"); } @EnableBinding(Processor.class) @@ -72,8 +74,10 @@ public class DefaultHeaderPropagationWithApplicationProvidedHeaderTests { @ServiceActivator(inputChannel = "input", outputChannel = "output") public Message consume(String data) { - return MessageBuilder.withPayload(data).setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build(); + return MessageBuilder.withPayload(data) + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build(); } } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DeserializeJSONToJavaTypeTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DeserializeJSONToJavaTypeTests.java index 4ca9e380a..995887775 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DeserializeJSONToJavaTypeTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/DeserializeJSONToJavaTypeTests.java @@ -54,11 +54,13 @@ public class DeserializeJSONToJavaTypeTests { @Test public void testMessageDeserialized() throws Exception { - testProcessor.input().send( - MessageBuilder.withPayload("{\"name\":\"Bar\"}").setHeader("contentType", "application/json").build()); + this.testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}") + .setHeader("contentType", "application/json").build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); assertThat(received).isNotNull(); assertThat(received.getPayload()).isEqualTo("{\"name\":\"Bar\"}"); } @@ -73,6 +75,7 @@ public class DeserializeJSONToJavaTypeTests { public Foo consume(Foo foo) { return foo; } + } public static class Foo { @@ -80,11 +83,13 @@ public class DeserializeJSONToJavaTypeTests { private String name; public String getName() { - return name; + return this.name; } public void setName(String name) { this.name = name; } + } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/InboundJsonToTupleConversionTest.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/InboundJsonToTupleConversionTest.java index 111e4c358..7bfa8719e 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/InboundJsonToTupleConversionTest.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/InboundJsonToTupleConversionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -56,14 +56,17 @@ public class InboundJsonToTupleConversionTest { @Test public void testInboundJsonTupleConversion() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}") - .build()); + this.testProcessor.input() + .send(MessageBuilder.withPayload("{'name':'foo'}").build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); assertThat(received).isNotNull(); String payload = new String(received.getPayload(), StandardCharsets.UTF_8); - assertThat(TupleBuilder.fromString(payload)).isEqualTo(TupleBuilder.tuple().of("name", "foo")); + assertThat(TupleBuilder.fromString(payload)) + .isEqualTo(TupleBuilder.tuple().of("name", "foo")); } @EnableBinding(Processor.class) diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/LegacyContentTypeTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/LegacyContentTypeTests.java index 9b59403c1..def84027c 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/LegacyContentTypeTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/LegacyContentTypeTests.java @@ -43,30 +43,35 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Oleg Zhurakousky */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = { LegacyContentTypeTests.LegacyTestSink.class}) +@SpringBootTest(classes = { LegacyContentTypeTests.LegacyTestSink.class }) public class LegacyContentTypeTests { @Autowired private Sink testSink; @Test - public void testOriginalContentTypeIsRetrievedForLegacyContentHeaderType() throws Exception { + public void testOriginalContentTypeIsRetrievedForLegacyContentHeaderType() + throws Exception { final CountDownLatch latch = new CountDownLatch(1); MessageHandler messageHandler = new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { assertThat(message.getPayload()).isInstanceOf(byte[].class); - assertThat(((byte[])message.getPayload())).isEqualTo("{\"message\":\"Hi\"}".getBytes(StandardCharsets.UTF_8)); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()).isEqualTo("application/json"); + assertThat(((byte[]) message.getPayload())).isEqualTo( + "{\"message\":\"Hi\"}".getBytes(StandardCharsets.UTF_8)); + assertThat( + message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()) + .isEqualTo("application/json"); latch.countDown(); } }; - testSink.input().subscribe(messageHandler); - testSink.input().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}".getBytes()) - .setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, "application/json") - .build()); + this.testSink.input().subscribe(messageHandler); + this.testSink.input().send(MessageBuilder + .withPayload("{\"message\":\"Hi\"}".getBytes()) + .setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, "application/json") + .build()); assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); - testSink.input().unsubscribe(messageHandler); + this.testSink.input().unsubscribe(messageHandler); } @EnableBinding(Sink.class) @@ -74,4 +79,5 @@ public class LegacyContentTypeTests { public static class LegacyTestSink { } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelConfigurerTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelConfigurerTests.java index a7a12f930..f0bb1c299 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelConfigurerTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelConfigurerTests.java @@ -45,7 +45,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.MimeTypeUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNull; /** * @author Ilayaperumal Gopinathan @@ -54,7 +53,8 @@ import static org.junit.Assert.assertNull; */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = { MessageChannelConfigurerTests.TestSink.class, - MessageChannelConfigurerTests.TestSource.class, SpelExpressionConverterConfiguration.class}) + MessageChannelConfigurerTests.TestSource.class, + SpelExpressionConverterConfiguration.class }) public class MessageChannelConfigurerTests { @Autowired @@ -71,8 +71,10 @@ public class MessageChannelConfigurerTests { @Test public void testChannelTypes() throws Exception { - DirectWithAttributesChannel inputChannel = (DirectWithAttributesChannel) testSink.input(); - DirectWithAttributesChannel outputChannel = (DirectWithAttributesChannel) testSource.output(); + DirectWithAttributesChannel inputChannel = (DirectWithAttributesChannel) this.testSink + .input(); + DirectWithAttributesChannel outputChannel = (DirectWithAttributesChannel) this.testSource + .output(); assertThat(inputChannel.getAttribute("type")).isEqualTo(Sink.INPUT); assertThat(outputChannel.getAttribute("type")).isEqualTo(Source.OUTPUT); } @@ -85,42 +87,48 @@ public class MessageChannelConfigurerTests { assertThat(message.getPayload()).isEqualTo("{\"message\":\"Hi\"}".getBytes()); latch.countDown(); }; - testSink.input().subscribe(messageHandler); - testSink.input().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}".getBytes()).build()); + this.testSink.input().subscribe(messageHandler); + this.testSink.input().send( + MessageBuilder.withPayload("{\"message\":\"Hi\"}".getBytes()).build()); assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); - testSink.input().unsubscribe(messageHandler); + this.testSink.input().unsubscribe(messageHandler); } @Test public void testObjectMapperConfig() throws Exception { - CompositeMessageConverter converters = (CompositeMessageConverter) messageConverterFactory + CompositeMessageConverter converters = (CompositeMessageConverter) this.messageConverterFactory .getMessageConverterForType(MimeTypeUtils.APPLICATION_JSON); for (MessageConverter converter : converters.getConverters()) { DirectFieldAccessor converterAccessor = new DirectFieldAccessor(converter); - ObjectMapper objectMapper = (ObjectMapper) converterAccessor.getPropertyValue("objectMapper"); + ObjectMapper objectMapper = (ObjectMapper) converterAccessor + .getPropertyValue("objectMapper"); // assert that the ObjectMapper used by the converters is compliant with the // Boot configuration - assertThat(!objectMapper.getSerializationConfig().isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)) - .withFailMessage("SerializationFeature 'WRITE_DATES_AS_TIMESTAMPS' should be disabled"); + assertThat(!objectMapper.getSerializationConfig().isEnabled( + SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)).withFailMessage( + "SerializationFeature 'WRITE_DATES_AS_TIMESTAMPS' should be disabled"); // assert that the globally set bean is used by the converters } } @Test public void testPartitionHeader() throws Exception { - this.testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").build()); - Message message = this.messageCollector.forChannel(testSource.output()).poll(1, TimeUnit.SECONDS); + this.testSource.output() + .send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").build()); + Message message = this.messageCollector.forChannel(this.testSource.output()) + .poll(1, TimeUnit.SECONDS); assertThat(message.getHeaders().get(BinderHeaders.PARTITION_HEADER).equals(0)); - assertNull(message.getHeaders().get(BinderHeaders.PARTITION_OVERRIDE)); + assertThat(message.getHeaders().get(BinderHeaders.PARTITION_OVERRIDE)).isNull(); } @Test public void testPartitionHeaderWithPartitionOverride() throws Exception { this.testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}") .setHeader(BinderHeaders.PARTITION_OVERRIDE, 123).build()); - Message message = this.messageCollector.forChannel(testSource.output()).poll(1, TimeUnit.SECONDS); + Message message = this.messageCollector.forChannel(this.testSource.output()) + .poll(1, TimeUnit.SECONDS); assertThat(message.getHeaders().get(BinderHeaders.PARTITION_HEADER).equals(123)); - assertNull(message.getHeaders().get(BinderHeaders.PARTITION_OVERRIDE)); + assertThat(message.getHeaders().get(BinderHeaders.PARTITION_OVERRIDE)).isNull(); } @EnableBinding(Sink.class) @@ -136,4 +144,5 @@ public class MessageChannelConfigurerTests { public static class TestSource { } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeDecodingTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeDecodingTests.java index 55d30e651..188f497d1 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeDecodingTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeDecodingTests.java @@ -41,19 +41,21 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Soby Chacko */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = { MessageChannelWithNativeDecodingTests.NativeDecodingSink.class}) +@SpringBootTest(classes = { + MessageChannelWithNativeDecodingTests.NativeDecodingSink.class }) public class MessageChannelWithNativeDecodingTests { @Autowired private Sink nativeDecodingSink; @Test - public void testMessageConverterInterceptorsAreSkippedWhenNativeDecodingIsEnabled() throws Exception { + public void testMessageConverterInterceptorsAreSkippedWhenNativeDecodingIsEnabled() + throws Exception { final CountDownLatch latch = new CountDownLatch(1); byte[] serializedData; ObjectOutput out; - try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { out = new ObjectOutputStream(bos); out.writeObject(123); out.flush(); @@ -61,17 +63,18 @@ public class MessageChannelWithNativeDecodingTests { } MessageHandler messageHandler = message -> { - //ensure that the data is not deserialized becasue of native decoding - //and the content type set in the properties file didn't take any effect + // ensure that the data is not deserialized becasue of native decoding + // and the content type set in the properties file didn't take any effect assertThat(message.getPayload()).isInstanceOf(byte[].class); assertThat(message.getPayload()).isEqualTo(serializedData); latch.countDown(); }; - nativeDecodingSink.input().subscribe(messageHandler); + this.nativeDecodingSink.input().subscribe(messageHandler); - nativeDecodingSink.input().send(MessageBuilder.withPayload(serializedData).build()); + this.nativeDecodingSink.input() + .send(MessageBuilder.withPayload(serializedData).build()); assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); - nativeDecodingSink.input().unsubscribe(messageHandler); + this.nativeDecodingSink.input().unsubscribe(messageHandler); } @EnableBinding(Sink.class) @@ -80,4 +83,5 @@ public class MessageChannelWithNativeDecodingTests { public static class NativeDecodingSink { } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeEncodingTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeEncodingTests.java index 9aa43a3bb..03f914c42 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeEncodingTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/MessageChannelWithNativeEncodingTests.java @@ -39,7 +39,8 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Soby Chacko */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = { MessageChannelWithNativeEncodingTests.NativeEncodingSource.class}) +@SpringBootTest(classes = { + MessageChannelWithNativeEncodingTests.NativeEncodingSource.class }) public class MessageChannelWithNativeEncodingTests { @Autowired @@ -49,11 +50,15 @@ public class MessageChannelWithNativeEncodingTests { private MessageCollector messageCollector; @Test - public void testOutboundContentTypeInterceptorIsSkippedWhenNativeEncodingIsEnabled() throws Exception { - this.nativeEncodingSource.output().send(MessageBuilder.withPayload("hello foobar!").build()); - Message message = this.messageCollector.forChannel(this.nativeEncodingSource.output()).poll(1, TimeUnit.SECONDS); - //should not convert the payload to byte[] even though we set a contentType on the channel. - //This is becasue, we are using native encoding. + public void testOutboundContentTypeInterceptorIsSkippedWhenNativeEncodingIsEnabled() + throws Exception { + this.nativeEncodingSource.output() + .send(MessageBuilder.withPayload("hello foobar!").build()); + Message message = this.messageCollector + .forChannel(this.nativeEncodingSource.output()).poll(1, TimeUnit.SECONDS); + // should not convert the payload to byte[] even though we set a contentType on + // the channel. + // This is becasue, we are using native encoding. assertThat(message.getPayload()).isInstanceOf(String.class); assertThat(message.getPayload()).isEqualTo("hello foobar!"); assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isNull(); @@ -65,4 +70,5 @@ public class MessageChannelWithNativeEncodingTests { public static class NativeEncodingSource { } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotatedMethodArgumentsTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotatedMethodArgumentsTests.java index afef15c37..c5ed31907 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotatedMethodArgumentsTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotatedMethodArgumentsTests.java @@ -44,7 +44,7 @@ import org.springframework.messaging.handler.annotation.support.MethodArgumentNo import org.springframework.util.MimeType; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS; /** @@ -63,33 +63,39 @@ public class StreamListenerAnnotatedMethodArgumentsTests { @Test @SuppressWarnings("unchecked") public void testAnnotatedArguments() { - ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithAnnotatedArguments.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication + .run(TestPojoWithAnnotatedArguments.class, "--server.port=0"); TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context .getBean(TestPojoWithAnnotatedArguments.class); Sink sink = context.getBean(Sink.class); String id = UUID.randomUUID().toString(); - sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", MimeType.valueOf("application/json")).setHeader("testHeader", "testValue").build()); + sink.input() + .send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") + .setHeader("contentType", MimeType.valueOf("application/json")) + .setHeader("testHeader", "testValue").build()); assertThat(testPojoWithAnnotatedArguments.receivedArguments).hasSize(3); assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0)) .isInstanceOf(StreamListenerTestUtils.FooPojo.class); - assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0)).hasFieldOrPropertyWithValue("foo", - "barbar" + id); - assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(1)).isInstanceOf(Map.class); - assertThat((Map) testPojoWithAnnotatedArguments.receivedArguments.get(1)) - .containsEntry(MessageHeaders.CONTENT_TYPE, MimeType.valueOf("application/json")); - assertThat((Map) testPojoWithAnnotatedArguments.receivedArguments.get(1)) - .containsEntry("testHeader", "testValue"); - assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(2)).isEqualTo("application/json"); + assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); + assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(1)) + .isInstanceOf(Map.class); + assertThat((Map) testPojoWithAnnotatedArguments.receivedArguments + .get(1)).containsEntry(MessageHeaders.CONTENT_TYPE, + MimeType.valueOf("application/json")); + assertThat((Map) testPojoWithAnnotatedArguments.receivedArguments + .get(1)).containsEntry("testHeader", "testValue"); + assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(2)) + .isEqualTo("application/json"); context.close(); } @Test public void testInputAnnotationAtMethodParameter() { try { - SpringApplication.run(TestPojoWithInvalidInputAnnotatedArgument.class, "--server.port=0"); + SpringApplication.run(TestPojoWithInvalidInputAnnotatedArgument.class, + "--server.port=0"); fail("Exception expected: " + INVALID_DECLARATIVE_METHOD_PARAMETERS); } catch (IllegalArgumentException e) { @@ -99,30 +105,36 @@ public class StreamListenerAnnotatedMethodArgumentsTests { @Test public void testValidAnnotationAtMethodParameterWithPojoThatPassesValidation() { - ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithValidAnnotationThatPassesValidation.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication.run( + TestPojoWithValidAnnotationThatPassesValidation.class, "--server.port=0"); - TestPojoWithValidAnnotationThatPassesValidation testPojoWithValidAnnotationThatPassesValidation = context.getBean(TestPojoWithValidAnnotationThatPassesValidation.class); + TestPojoWithValidAnnotationThatPassesValidation testPojoWithValidAnnotationThatPassesValidation = context + .getBean(TestPojoWithValidAnnotationThatPassesValidation.class); Sink sink = context.getBean(Sink.class); String id = UUID.randomUUID().toString(); sink.input().send(MessageBuilder.withPayload("{\"foo\":\"" + id + "\"}") .setHeader("contentType", MimeType.valueOf("application/json")).build()); - assertThat(testPojoWithValidAnnotationThatPassesValidation.receivedArguments.get(0)).hasFieldOrPropertyWithValue("foo", id); + assertThat( + testPojoWithValidAnnotationThatPassesValidation.receivedArguments.get(0)) + .hasFieldOrPropertyWithValue("foo", id); context.close(); } @Test public void testValidAnnotationAtMethodParameterWithPojoThatFailsValidation() { - ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithValidAnnotationThatPassesValidation.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication.run( + TestPojoWithValidAnnotationThatPassesValidation.class, "--server.port=0"); Sink sink = context.getBean(Sink.class); try { sink.input().send(MessageBuilder.withPayload("{\"foo\":\"\"}") - .setHeader("contentType", MimeType.valueOf("application/json")).build()); + .setHeader("contentType", MimeType.valueOf("application/json")) + .build()); fail("Exception expected: MethodArgumentNotValidException!"); - } catch(MethodArgumentNotValidException e) { - assertThat(e.getMessage()).contains("default message [foo]]; default message [must not be blank]]"); + } + catch (MethodArgumentNotValidException e) { + assertThat(e.getMessage()).contains( + "default message [foo]]; default message [must not be blank]]"); } context.close(); } @@ -141,6 +153,7 @@ public class StreamListenerAnnotatedMethodArgumentsTests { this.receivedArguments.add(headers); this.receivedArguments.add(contentType); } + } @EnableBinding(Sink.class) @@ -158,6 +171,7 @@ public class StreamListenerAnnotatedMethodArgumentsTests { this.receivedArguments.add(headers); this.receivedArguments.add(contentType); } + } @EnableBinding(Processor.class) @@ -167,9 +181,11 @@ public class StreamListenerAnnotatedMethodArgumentsTests { List receivedArguments = new ArrayList<>(); @StreamListener(Processor.INPUT) - public void receive(@Valid StreamListenerTestUtils.PojoWithValidation pojoWithValidation) { + public void receive( + @Valid StreamListenerTestUtils.PojoWithValidation pojoWithValidation) { this.receivedArguments.add(pojoWithValidation); } + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotationBeanPostProcessorOverrideTest.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotationBeanPostProcessorOverrideTest.java index 4f2796046..abce23528 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotationBeanPostProcessorOverrideTest.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAnnotationBeanPostProcessorOverrideTest.java @@ -49,22 +49,22 @@ public class StreamListenerAnnotationBeanPostProcessorOverrideTest { @Test @SuppressWarnings("unchecked") public void testOverrideStreamListenerAnnotationBeanPostProcessor() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithAnnotatedArguments.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication + .run(TestPojoWithAnnotatedArguments.class, "--server.port=0"); TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context .getBean(TestPojoWithAnnotatedArguments.class); Sink sink = context.getBean(Sink.class); String id = UUID.randomUUID().toString(); sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", "application/json").setHeader("testHeader", "testValue") - .setHeader("type", "foo").build()); + .setHeader("contentType", "application/json") + .setHeader("testHeader", "testValue").setHeader("type", "foo").build()); sink.input().send(MessageBuilder.withPayload("{\"bar\":\"foofoo" + id + "\"}") - .setHeader("contentType", "application/json").setHeader("testHeader", "testValue") - .setHeader("type", "bar").build()); + .setHeader("contentType", "application/json") + .setHeader("testHeader", "testValue").setHeader("type", "bar").build()); assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1); - assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)).hasFieldOrPropertyWithValue("foo", - "barbar" + id); + assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); context.close(); } @@ -82,12 +82,14 @@ public class StreamListenerAnnotationBeanPostProcessorOverrideTest { public static StreamListenerAnnotationBeanPostProcessor streamListenerAnnotationBeanPostProcessor() { return new StreamListenerAnnotationBeanPostProcessor() { @Override - protected StreamListener postProcessAnnotation(StreamListener originalAnnotation, - Method annotatedMethod) { + protected StreamListener postProcessAnnotation( + StreamListener originalAnnotation, Method annotatedMethod) { Map attributes = new HashMap<>( AnnotationUtils.getAnnotationAttributes(originalAnnotation)); - attributes.put("condition", "headers['type']=='" + originalAnnotation.condition() + "'"); - return AnnotationUtils.synthesizeAnnotation(attributes, StreamListener.class, annotatedMethod); + attributes.put("condition", + "headers['type']=='" + originalAnnotation.condition() + "'"); + return AnnotationUtils.synthesizeAnnotation(attributes, + StreamListener.class, annotatedMethod); } }; } @@ -96,5 +98,7 @@ public class StreamListenerAnnotationBeanPostProcessorOverrideTest { public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) { this.receivedFoo.add(fooPojo); } + } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAsMetaAnnotationTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAsMetaAnnotationTests.java index d19e7c684..be67cc7d4 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAsMetaAnnotationTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerAsMetaAnnotationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -46,6 +46,7 @@ import static org.assertj.core.api.Assertions.assertThat; @Documented @StreamListener @interface EventHandler { + /** * The name of the binding target (e.g. channel) that the method subscribes to. * @return the name of the binding target. @@ -76,37 +77,37 @@ public class StreamListenerAsMetaAnnotationTests { @Test public void testCustomAnnotation() { - ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithCustomAnnotatedArguments.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication + .run(TestPojoWithCustomAnnotatedArguments.class, "--server.port=0"); TestPojoWithCustomAnnotatedArguments testPojoWithAnnotatedArguments = context .getBean(TestPojoWithCustomAnnotatedArguments.class); Sink sink = context.getBean(Sink.class); String id = UUID.randomUUID().toString(); sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", "application/json").setHeader("testHeader", "testValue") - .setHeader("type", "foo").build()); + .setHeader("contentType", "application/json") + .setHeader("testHeader", "testValue").setHeader("type", "foo").build()); assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1); - assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)).hasFieldOrPropertyWithValue("foo", - "barbar" + id); + assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); context.close(); } @Test public void testAnnotation() { - ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithAnnotatedArguments.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication + .run(TestPojoWithAnnotatedArguments.class, "--server.port=0"); TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context .getBean(TestPojoWithAnnotatedArguments.class); Sink sink = context.getBean(Sink.class); String id = UUID.randomUUID().toString(); sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", "application/json").setHeader("testHeader", "testValue") - .setHeader("type", "foo").build()); + .setHeader("contentType", "application/json") + .setHeader("testHeader", "testValue").setHeader("type", "foo").build()); assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1); - assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)).hasFieldOrPropertyWithValue("foo", - "barbar" + id); + assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); context.close(); } @@ -122,6 +123,7 @@ public class StreamListenerAsMetaAnnotationTests { public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) { this.receivedFoo.add(fooPojo); } + } @EnableBinding(Sink.class) @@ -136,5 +138,7 @@ public class StreamListenerAsMetaAnnotationTests { public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) { this.receivedFoo.add(fooPojo); } + } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerContentTypeConversionTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerContentTypeConversionTests.java index fc83b9fb0..05dcb1627 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerContentTypeConversionTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerContentTypeConversionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-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. @@ -42,15 +42,15 @@ public class StreamListenerContentTypeConversionTests { @Test public void testContentTypeConversion() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestSinkWithContentTypeConversion.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication + .run(TestSinkWithContentTypeConversion.class, "--server.port=0"); @SuppressWarnings("unchecked") - TestSinkWithContentTypeConversion testSink = context.getBean(TestSinkWithContentTypeConversion.class); + TestSinkWithContentTypeConversion testSink = context + .getBean(TestSinkWithContentTypeConversion.class); Sink sink = context.getBean(Sink.class); String id = UUID.randomUUID().toString(); - sink.input().send( - MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", "application/json").build()); + sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") + .setHeader("contentType", "application/json").build()); assertThat(testSink.latch.await(10, TimeUnit.SECONDS)); assertThat(testSink.receivedArguments).hasSize(1); assertThat(testSink.receivedArguments.get(0)).hasFieldOrPropertyWithValue("foo", @@ -71,6 +71,7 @@ public class StreamListenerContentTypeConversionTests { this.receivedArguments.add(fooPojo); this.latch.countDown(); } + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerDuplicateMappingTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerDuplicateMappingTests.java index dafa2c693..e4878df32 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerDuplicateMappingTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerDuplicateMappingTests.java @@ -31,7 +31,7 @@ import org.springframework.messaging.Message; import org.springframework.messaging.handler.annotation.SendTo; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; /** * @author Marius Bogoevici @@ -44,11 +44,13 @@ public class StreamListenerDuplicateMappingTests { public void testMultipleMappingsWithReturnValue() { ConfigurableApplicationContext context = null; try { - context = SpringApplication.run(TestMultipleMappingsWithReturnValue.class, "--server.port=0"); + context = SpringApplication.run(TestMultipleMappingsWithReturnValue.class, + "--server.port=0"); fail("Exception expected on duplicate mapping"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).startsWith(StreamListenerErrorMessages.MULTIPLE_VALUE_RETURNING_METHODS); + assertThat(e.getMessage()).startsWith( + StreamListenerErrorMessages.MULTIPLE_VALUE_RETURNING_METHODS); } finally { if (context != null) { @@ -61,11 +63,14 @@ public class StreamListenerDuplicateMappingTests { public void testDuplicateMappingFromAbstractMethod() { ConfigurableApplicationContext context = null; try { - context = SpringApplication.run(TestDuplicateMappingFromAbstractMethod.class, "--server.port=0"); + context = SpringApplication.run(TestDuplicateMappingFromAbstractMethod.class, + "--server.port=0"); } catch (BeanCreationException e) { - String errorMessage = e.getCause().getMessage().startsWith("Duplicate @StreamListener mapping") - ? "Duplicate mapping exception is not expected" : "Test failed with exception"; + String errorMessage = e.getCause().getMessage() + .startsWith("Duplicate @StreamListener mapping") + ? "Duplicate mapping exception is not expected" + : "Test failed with exception"; fail(errorMessage + ": " + e.getMessage()); } finally { @@ -76,7 +81,9 @@ public class StreamListenerDuplicateMappingTests { } public interface GenericSink { + void testMethod(T msg); + } public interface Base { @@ -98,16 +105,19 @@ public class StreamListenerDuplicateMappingTests { public String receiveDuplicateMapping(Message fooMessage) { return null; } + } @EnableBinding(Sink.class) @EnableAutoConfiguration - public static class TestDuplicateMappingFromAbstractMethod implements GenericSink { + public static class TestDuplicateMappingFromAbstractMethod + implements GenericSink { @Override @StreamListener(Sink.INPUT) public void testMethod(TestBase msg) { } + } public class TestBase implements Base { diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerBeanTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerBeanTests.java index 1db407b56..b93f2f684 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerBeanTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerBeanTests.java @@ -75,15 +75,15 @@ public class StreamListenerHandlerBeanTests { MessageCollector collector = context.getBean(MessageCollector.class); Processor processor = context.getBean(Processor.class); String id = UUID.randomUUID().toString(); - processor.input().send( - MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") + processor.input() + .send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") .setHeader("contentType", "application/json").build()); HandlerBean handlerBean = context.getBean(HandlerBean.class); Assertions.assertThat(handlerBean.receivedPojos).hasSize(1); - Assertions.assertThat(handlerBean.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", - "barbar" + id); - Message message = (Message) collector.forChannel( - processor.output()).poll(1, TimeUnit.SECONDS); + Assertions.assertThat(handlerBean.receivedPojos.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); + Message message = (Message) collector + .forChannel(processor.output()).poll(1, TimeUnit.SECONDS); assertThat(message).isNotNull(); assertThat(message.getPayload()).isEqualTo("{\"bar\":\"barbar" + id + "\"}"); assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) @@ -99,6 +99,7 @@ public class StreamListenerHandlerBeanTests { public HandlerBeanWithSendTo handlerBean() { return new HandlerBeanWithSendTo(); } + } @EnableBinding(Processor.class) @@ -109,30 +110,35 @@ public class StreamListenerHandlerBeanTests { public HandlerBeanWithOutput handlerBean() { return new HandlerBeanWithOutput(); } + } public static class HandlerBeanWithSendTo extends HandlerBean { @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) - public StreamListenerTestUtils.BarPojo receive(StreamListenerTestUtils.FooPojo fooMessage) { + public StreamListenerTestUtils.BarPojo receive( + StreamListenerTestUtils.FooPojo fooMessage) { this.receivedPojos.add(fooMessage); StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo(); barPojo.setBar(fooMessage.getFoo()); return barPojo; } + } public static class HandlerBeanWithOutput extends HandlerBean { @StreamListener(Processor.INPUT) @Output(Processor.OUTPUT) - public StreamListenerTestUtils.BarPojo receive(StreamListenerTestUtils.FooPojo fooMessage) { + public StreamListenerTestUtils.BarPojo receive( + StreamListenerTestUtils.FooPojo fooMessage) { this.receivedPojos.add(fooMessage); StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo(); barPojo.setBar(fooMessage.getFoo()); return barPojo; } + } public static class HandlerBean { diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerMethodTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerMethodTests.java index 39e8ae9ce..686e54c4e 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerMethodTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerHandlerMethodTests.java @@ -47,7 +47,7 @@ import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.util.Assert; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS; import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INPUT_AT_STREAM_LISTENER; import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS; @@ -82,8 +82,8 @@ public class StreamListenerHandlerMethodTests { @SuppressWarnings("unchecked") @Test public void testMethodWithObjectAsMethodArgument() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithObjectAsMethodArgument.class, - "--server.port=0", + ConfigurableApplicationContext context = SpringApplication.run( + TestMethodWithObjectAsMethodArgument.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.cloud.stream.bindings.output.contentType=text/plain"); @@ -91,7 +91,8 @@ public class StreamListenerHandlerMethodTests { final String testMessage = "testing"; processor.input().send(MessageBuilder.withPayload(testMessage).build()); MessageCollector messageCollector = context.getBean(MessageCollector.class); - Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); + Message result = (Message) messageCollector + .forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); assertThat(result).isNotNull(); assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase()); context.close(); @@ -100,23 +101,24 @@ public class StreamListenerHandlerMethodTests { @SuppressWarnings("unchecked") @Test /** - * @since 2.0 : This test is an example of the new behavior of 2.0 when it comes to contentType handling. - * The default contentType being JSON in order to be able to check a message without quotes the user needs to set the input/output contentType accordingly - * Also, received messages are always of Message now. + * @since 2.0 : This test is an example of the new behavior of 2.0 when it comes to + * contentType handling. The default contentType being JSON in order to be able to + * check a message without quotes the user needs to set the input/output contentType + * accordingly Also, received messages are always of Message now. */ public void testMethodHeadersPropagatged() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestMethodHeadersPropagated.class, - "--server.port=0", + ConfigurableApplicationContext context = SpringApplication.run( + TestMethodHeadersPropagated.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.cloud.stream.bindings.output.contentType=text/plain"); Processor processor = context.getBean(Processor.class); final String testMessage = "testing"; - processor.input().send(MessageBuilder.withPayload(testMessage) - .setHeader("foo", "bar") - .build()); + processor.input().send( + MessageBuilder.withPayload(testMessage).setHeader("foo", "bar").build()); MessageCollector messageCollector = context.getBean(MessageCollector.class); - Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); + Message result = (Message) messageCollector + .forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); assertThat(result).isNotNull(); assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase()); assertThat(result.getHeaders().get("foo")).isEqualTo("bar"); @@ -126,40 +128,40 @@ public class StreamListenerHandlerMethodTests { @SuppressWarnings("unchecked") @Test public void testMethodHeadersNotPropagatged() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestMethodHeadersNotPropagated.class, - "--server.port=0", + ConfigurableApplicationContext context = SpringApplication.run( + TestMethodHeadersNotPropagated.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.cloud.stream.bindings.output.contentType=text/plain"); Processor processor = context.getBean(Processor.class); final String testMessage = "testing"; - processor.input().send(MessageBuilder.withPayload(testMessage) - .setHeader("foo", "bar") - .build()); + processor.input().send( + MessageBuilder.withPayload(testMessage).setHeader("foo", "bar").build()); MessageCollector messageCollector = context.getBean(MessageCollector.class); - Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); + Message result = (Message) messageCollector + .forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); assertThat(result).isNotNull(); assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase()); assertThat(result.getHeaders().get("foo")).isNull(); context.close(); } - - //TODO: Handle dynamic destinations and contentType + // TODO: Handle dynamic destinations and contentType @SuppressWarnings("unchecked") public void testStreamListenerMethodWithTargetBeanFromOutside() throws Exception { - ConfigurableApplicationContext context = SpringApplication - .run(TestStreamListenerMethodWithTargetBeanFromOutside.class, "--server.port=0", - "--spring.jmx.enabled=false", - "--spring.cloud.stream.bindings.input.contentType=text/plain", - "--spring.cloud.stream.bindings.output.contentType=text/plain"); + ConfigurableApplicationContext context = SpringApplication.run( + TestStreamListenerMethodWithTargetBeanFromOutside.class, + "--server.port=0", "--spring.jmx.enabled=false", + "--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.cloud.stream.bindings.output.contentType=text/plain"); Sink sink = context.getBean(Sink.class); final String testMessageToSend = "testing"; sink.input().send(MessageBuilder.withPayload(testMessageToSend).build()); - DirectChannel directChannel = (DirectChannel) context.getBean(testMessageToSend.toUpperCase(), - MessageChannel.class); + DirectChannel directChannel = (DirectChannel) context + .getBean(testMessageToSend.toUpperCase(), MessageChannel.class); MessageCollector messageCollector = context.getBean(MessageCollector.class); - Message result = (Message) messageCollector.forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS); + Message result = (Message) messageCollector + .forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS); sink.input().send(MessageBuilder.withPayload(testMessageToSend).build()); assertThat(result).isNotNull(); assertThat(result.getPayload()).isEqualTo(testMessageToSend.toUpperCase()); @@ -169,8 +171,8 @@ public class StreamListenerHandlerMethodTests { @Test public void testInvalidReturnTypeWithSendToAndOutput() throws Exception { try { - SpringApplication.run(TestReturnTypeWithMultipleOutput.class, "--server.port=0", - "--spring.jmx.enabled=false"); + SpringApplication.run(TestReturnTypeWithMultipleOutput.class, + "--server.port=0", "--spring.jmx.enabled=false"); fail("Exception expected: " + RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED); } catch (IllegalArgumentException e) { @@ -181,8 +183,8 @@ public class StreamListenerHandlerMethodTests { @Test public void testInvalidReturnTypeWithNoOutput() throws Exception { try { - SpringApplication.run(TestInvalidReturnTypeWithNoOutput.class, "--server.port=0", - "--spring.jmx.enabled=false"); + SpringApplication.run(TestInvalidReturnTypeWithNoOutput.class, + "--server.port=0", "--spring.jmx.enabled=false"); fail("Exception expected: " + RETURN_TYPE_NO_OUTBOUND_SPECIFIED); } catch (IllegalArgumentException e) { @@ -193,8 +195,8 @@ public class StreamListenerHandlerMethodTests { @Test public void testInvalidInputAnnotationWithNoValue() throws Exception { try { - SpringApplication.run(TestInvalidInputAnnotationWithNoValue.class, "--server.port=0", - "--spring.jmx.enabled=false"); + SpringApplication.run(TestInvalidInputAnnotationWithNoValue.class, + "--server.port=0", "--spring.jmx.enabled=false"); fail("Exception expected: " + INVALID_INBOUND_NAME); } catch (IllegalArgumentException e) { @@ -205,8 +207,8 @@ public class StreamListenerHandlerMethodTests { @Test public void testInvalidOutputAnnotationWithNoValue() throws Exception { try { - SpringApplication.run(TestInvalidOutputAnnotationWithNoValue.class, "--server.port=0", - "--spring.jmx.enabled=false"); + SpringApplication.run(TestInvalidOutputAnnotationWithNoValue.class, + "--server.port=0", "--spring.jmx.enabled=false"); fail("Exception expected: " + INVALID_OUTBOUND_NAME); } catch (IllegalArgumentException e) { @@ -222,7 +224,8 @@ public class StreamListenerHandlerMethodTests { fail("Exception expected on using invalid inbound name"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); + assertThat(e.getMessage()).contains( + StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); } } @@ -246,7 +249,8 @@ public class StreamListenerHandlerMethodTests { fail("Exception expected: " + AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains(AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS); + assertThat(e.getMessage()) + .contains(AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS); } } @@ -258,15 +262,16 @@ public class StreamListenerHandlerMethodTests { fail("Exception expected:" + AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains(AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS); + assertThat(e.getMessage()) + .contains(AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS); } } @Test public void testMethodWithInputAsMethodAndParameter() throws Exception { try { - SpringApplication.run(TestMethodWithInputAsMethodAndParameter.class, "--server.port=0", - "--spring.jmx.enabled=false"); + SpringApplication.run(TestMethodWithInputAsMethodAndParameter.class, + "--server.port=0", "--spring.jmx.enabled=false"); fail("Exception expected: " + INVALID_DECLARATIVE_METHOD_PARAMETERS); } catch (IllegalArgumentException e) { @@ -277,8 +282,8 @@ public class StreamListenerHandlerMethodTests { @Test public void testMethodWithOutputAsMethodAndParameter() throws Exception { try { - SpringApplication.run(TestMethodWithOutputAsMethodAndParameter.class, "--server.port=0", - "--spring.jmx.enabled=false"); + SpringApplication.run(TestMethodWithOutputAsMethodAndParameter.class, + "--server.port=0", "--spring.jmx.enabled=false"); fail("Exception expected:" + INVALID_OUTPUT_VALUES); } catch (IllegalArgumentException e) { @@ -300,8 +305,8 @@ public class StreamListenerHandlerMethodTests { @Test public void testMethodWithMultipleInputParameters() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleInputParameters.class, - "--server.port=0", + ConfigurableApplicationContext context = SpringApplication.run( + TestMethodWithMultipleInputParameters.class, "--server.port=0", "--spring.jmx.enabled=false"); Processor processor = context.getBean(Processor.class); StreamListenerTestUtils.FooInboundChannel1 inboundChannel2 = context @@ -310,22 +315,26 @@ public class StreamListenerHandlerMethodTests { ((SubscribableChannel) processor.output()).subscribe(new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { - Assert.isTrue(message.getPayload().equals("footesting") || message.getPayload().equals("BARTESTING"), "Assert failed"); + Assert.isTrue( + message.getPayload().equals("footesting") + || message.getPayload().equals("BARTESTING"), + "Assert failed"); latch.countDown(); } }); processor.input().send(MessageBuilder.withPayload("{\"foo\":\"fooTESTing\"}") .setHeader("contentType", "application/json").build()); - inboundChannel2.input().send(MessageBuilder.withPayload("{\"bar\":\"bartestING\"}") - .setHeader("contentType", "application/json").build()); + inboundChannel2.input() + .send(MessageBuilder.withPayload("{\"bar\":\"bartestING\"}") + .setHeader("contentType", "application/json").build()); assertThat(latch.await(1, TimeUnit.SECONDS)); context.close(); } @Test public void testMethodWithMultipleOutputParameters() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleOutputParameters.class, - "--server.port=0", + ConfigurableApplicationContext context = SpringApplication.run( + TestMethodWithMultipleOutputParameters.class, "--server.port=0", "--spring.jmx.enabled=false"); Processor processor = context.getBean(Processor.class); StreamListenerTestUtils.FooOutboundChannel1 source2 = context @@ -335,7 +344,8 @@ public class StreamListenerHandlerMethodTests { @Override public void handleMessage(Message message) throws MessagingException { Assert.isTrue(message.getPayload().equals("testing"), "Assert failed"); - Assert.isTrue(message.getHeaders().get("output").equals("output2"), "Assert failed"); + Assert.isTrue(message.getHeaders().get("output").equals("output2"), + "Assert failed"); latch.countDown(); } }); @@ -343,12 +353,15 @@ public class StreamListenerHandlerMethodTests { @Override public void handleMessage(Message message) throws MessagingException { Assert.isTrue(message.getPayload().equals("TESTING"), "Assert failed"); - Assert.isTrue(message.getHeaders().get("output").equals("output1"), "Assert failed"); + Assert.isTrue(message.getHeaders().get("output").equals("output1"), + "Assert failed"); latch.countDown(); } }); - processor.input().send(MessageBuilder.withPayload("testING").setHeader("output", "output1").build()); - processor.input().send(MessageBuilder.withPayload("TESTing").setHeader("output", "output2").build()); + processor.input().send(MessageBuilder.withPayload("testING") + .setHeader("output", "output1").build()); + processor.input().send(MessageBuilder.withPayload("TESTing") + .setHeader("output", "output2").build()); assertThat(latch.await(1, TimeUnit.SECONDS)); context.close(); } @@ -366,15 +379,20 @@ public class StreamListenerHandlerMethodTests { public void handleMessage(Message message) throws MessagingException { if (message.getHeaders().get("output").equals("output1")) { output1.send(org.springframework.messaging.support.MessageBuilder - .withPayload(message.getPayload().toString().toUpperCase()).build()); + .withPayload( + message.getPayload().toString().toUpperCase()) + .build()); } else if (message.getHeaders().get("output").equals("output2")) { output2.send(org.springframework.messaging.support.MessageBuilder - .withPayload(message.getPayload().toString().toLowerCase()).build()); + .withPayload( + message.getPayload().toString().toLowerCase()) + .build()); } } }); } + } @EnableBinding({ Sink.class }) @@ -384,6 +402,7 @@ public class StreamListenerHandlerMethodTests { @StreamListener public void receive(StreamListenerTestUtils.FooPojo fooPojo) { } + } @EnableBinding({ Processor.class }) @@ -395,6 +414,7 @@ public class StreamListenerHandlerMethodTests { public String receive(Object received) { return received.toString().toUpperCase(); } + } @EnableBinding({ Processor.class }) @@ -430,13 +450,15 @@ public class StreamListenerHandlerMethodTests { @StreamListener(Sink.INPUT) @SendTo(ROUTER_QUEUE) public Message convertMessageBody(Message message) { - return new DefaultMessageBuilderFactory().withPayload(message.getPayload().toUpperCase()).build(); + return new DefaultMessageBuilderFactory() + .withPayload(message.getPayload().toUpperCase()).build(); } @Router(inputChannel = ROUTER_QUEUE) public String route(String message) { return message.toUpperCase(); } + } @EnableBinding({ Sink.class }) @@ -447,6 +469,7 @@ public class StreamListenerHandlerMethodTests { @Input(Sink.INPUT) public void receive(StreamListenerTestUtils.FooPojo fooPojo) { } + } @EnableBinding({ Sink.class }) @@ -454,8 +477,10 @@ public class StreamListenerHandlerMethodTests { public static class TestAmbiguousMethodArguments1 { @StreamListener(Processor.INPUT) - public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo, String value) { + public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo, + String value) { } + } @EnableBinding({ Sink.class }) @@ -466,6 +491,7 @@ public class StreamListenerHandlerMethodTests { public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo, @Payload StreamListenerTestUtils.BarPojo barPojo) { } + } @EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class }) @@ -478,6 +504,7 @@ public class StreamListenerHandlerMethodTests { @Output(StreamListenerTestUtils.FooOutboundChannel1.OUTPUT) MessageChannel output2) { return "foo"; } + } @EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class }) @@ -488,6 +515,7 @@ public class StreamListenerHandlerMethodTests { public String receive(@Input(Processor.INPUT) SubscribableChannel input1) { return "foo"; } + } @EnableBinding({ Processor.class }) @@ -497,6 +525,7 @@ public class StreamListenerHandlerMethodTests { @StreamListener public void receive(@Input SubscribableChannel input) { } + } @EnableBinding({ Processor.class }) @@ -504,8 +533,10 @@ public class StreamListenerHandlerMethodTests { public static class TestInvalidOutputAnnotationWithNoValue { @StreamListener - public void receive(@Input(Processor.OUTPUT) SubscribableChannel input, @Output MessageChannel output) { + public void receive(@Input(Processor.OUTPUT) SubscribableChannel input, + @Output MessageChannel output) { } + } @EnableBinding({ Sink.class }) @@ -515,6 +546,7 @@ public class StreamListenerHandlerMethodTests { @StreamListener public void receive(@Input("invalid") SubscribableChannel input) { } + } @EnableBinding({ Processor.class }) @@ -525,6 +557,7 @@ public class StreamListenerHandlerMethodTests { public void receive(@Input(Processor.INPUT) SubscribableChannel input, @Output("invalid") MessageChannel output) { } + } @EnableBinding({ Sink.class }) @@ -534,6 +567,7 @@ public class StreamListenerHandlerMethodTests { @StreamListener public void receive(@Input(Sink.INPUT) StreamListenerTestUtils.FooPojo fooPojo) { } + } @EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class }) @@ -548,10 +582,12 @@ public class StreamListenerHandlerMethodTests { @Override public void handleMessage(Message message) throws MessagingException { output1.send(org.springframework.messaging.support.MessageBuilder - .withPayload(message.getPayload().toString().toUpperCase()).build()); + .withPayload(message.getPayload().toString().toUpperCase()) + .build()); } }); } + } @EnableBinding({ Processor.class, StreamListenerTestUtils.FooInboundChannel1.class }) @@ -566,17 +602,20 @@ public class StreamListenerHandlerMethodTests { @Override public void handleMessage(Message message) throws MessagingException { output.send(org.springframework.messaging.support.MessageBuilder - .withPayload(message.getPayload().toString().toUpperCase()).build()); + .withPayload(message.getPayload().toString().toUpperCase()) + .build()); } }); input2.subscribe(new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { output.send(org.springframework.messaging.support.MessageBuilder - .withPayload(message.getPayload().toString().toUpperCase()).build()); + .withPayload(message.getPayload().toString().toUpperCase()) + .build()); } }); } + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMessageArgumentTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMessageArgumentTests.java index 6c1a2b9ff..c3efca1ca 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMessageArgumentTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMessageArgumentTests.java @@ -58,14 +58,17 @@ public class StreamListenerMessageArgumentTests { @Parameterized.Parameters public static Collection InputConfigs() { - return Arrays.asList(new Class[] { TestPojoWithMessageArgument1.class, TestPojoWithMessageArgument2.class }); + return Arrays.asList(new Class[] { TestPojoWithMessageArgument1.class, + TestPojoWithMessageArgument2.class }); } @Test @SuppressWarnings("unchecked") public void testMessageArgument() throws Exception { - ConfigurableApplicationContext context = SpringApplication - .run(this.configClass, "--server.port=0", "--spring.cloud.stream.bindings.output.contentType=text/plain","--spring.jmx.enabled=false"); + ConfigurableApplicationContext context = SpringApplication.run(this.configClass, + "--server.port=0", + "--spring.cloud.stream.bindings.output.contentType=text/plain", + "--spring.jmx.enabled=false"); MessageCollector collector = context.getBean(MessageCollector.class); Processor processor = context.getBean(Processor.class); String id = UUID.randomUUID().toString(); @@ -74,7 +77,8 @@ public class StreamListenerMessageArgumentTests { TestPojoWithMessageArgument testPojoWithMessageArgument = context .getBean(TestPojoWithMessageArgument.class); assertThat(testPojoWithMessageArgument.receivedMessages).hasSize(1); - assertThat(testPojoWithMessageArgument.receivedMessages.get(0).getPayload()).isEqualTo("barbar" + id); + assertThat(testPojoWithMessageArgument.receivedMessages.get(0).getPayload()) + .isEqualTo("barbar" + id); Message message = (Message) collector .forChannel(processor.output()).poll(1, TimeUnit.SECONDS); assertThat(message).isNotNull(); @@ -94,6 +98,7 @@ public class StreamListenerMessageArgumentTests { barPojo.setBar(fooMessage.getPayload()); return barPojo; } + } @EnableBinding(Processor.class) @@ -108,10 +113,13 @@ public class StreamListenerMessageArgumentTests { barPojo.setBar(fooMessage.getPayload()); return barPojo; } + } public static class TestPojoWithMessageArgument { + List> receivedMessages = new ArrayList<>(); + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodRegisteredOnlyOnceTest.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodRegisteredOnlyOnceTest.java index 457b077e5..a94888003 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodRegisteredOnlyOnceTest.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodRegisteredOnlyOnceTest.java @@ -52,8 +52,8 @@ public class StreamListenerMethodRegisteredOnlyOnceTest { @Test public void should_handleSomeMessage() { - sink.channel().send(new GenericMessage<>("Payload")); - verify(handler).handleMessage(); //should only be invoked once. + this.sink.channel().send(new GenericMessage<>("Payload")); + verify(this.handler).handleMessage(); // should only be invoked once. } public interface SomeSink { @@ -72,4 +72,5 @@ public class StreamListenerMethodRegisteredOnlyOnceTest { } } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodReturnWithConversionTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodReturnWithConversionTests.java index b40dfe943..d883de010 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodReturnWithConversionTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodReturnWithConversionTests.java @@ -57,12 +57,13 @@ import static org.assertj.core.api.Assertions.assertThat; * */ @RunWith(StreamListenerMethodReturnWithConversionTests.class) -@Suite.SuiteClasses({ StreamListenerMethodReturnWithConversionTests.TestReturnConversion.class, +@Suite.SuiteClasses({ + StreamListenerMethodReturnWithConversionTests.TestReturnConversion.class, StreamListenerMethodReturnWithConversionTests.TestReturnNoConversion.class }) public class StreamListenerMethodReturnWithConversionTests extends Suite { - public StreamListenerMethodReturnWithConversionTests(Class klass, RunnerBuilder builder) - throws InitializationError { + public StreamListenerMethodReturnWithConversionTests(Class klass, + RunnerBuilder builder) throws InitializationError { super(klass, builder); } @@ -77,30 +78,39 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite { @Parameterized.Parameters public static Collection InputConfigs() { - return Arrays.asList(new Class[] { TestPojoWithMimeType1.class, TestPojoWithMimeType2.class }); + return Arrays.asList(new Class[] { TestPojoWithMimeType1.class, + TestPojoWithMimeType2.class }); } @Test @SuppressWarnings("unchecked") public void testReturnConversion() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(this.configClass, - "--spring.cloud.stream.bindings.output.contentType=application/json", "--server.port=0","--spring.jmx.enabled=false"); + ConfigurableApplicationContext context = SpringApplication.run( + this.configClass, + "--spring.cloud.stream.bindings.output.contentType=application/json", + "--server.port=0", "--spring.jmx.enabled=false"); MessageCollector collector = context.getBean(MessageCollector.class); Processor processor = context.getBean(Processor.class); String id = UUID.randomUUID().toString(); - processor.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", "application/json").build()); - TestPojoWithMimeType testPojoWithMimeType = context.getBean(TestPojoWithMimeType.class); + processor.input() + .send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") + .setHeader("contentType", "application/json").build()); + TestPojoWithMimeType testPojoWithMimeType = context + .getBean(TestPojoWithMimeType.class); Assertions.assertThat(testPojoWithMimeType.receivedPojos).hasSize(1); - Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id); - Message message = (Message) collector.forChannel(processor.output()).poll(1, - TimeUnit.SECONDS); + Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); + Message message = (Message) collector + .forChannel(processor.output()).poll(1, TimeUnit.SECONDS); assertThat(message).isNotNull(); - assertThat(new String(message.getPayload())).isEqualTo("{\"bar\":\"barbar" + id + "\"}"); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) - .includes(MimeTypeUtils.APPLICATION_JSON)); + assertThat(new String(message.getPayload())) + .isEqualTo("{\"bar\":\"barbar" + id + "\"}"); + assertThat( + message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) + .includes(MimeTypeUtils.APPLICATION_JSON)); context.close(); } + } @RunWith(Parameterized.class) @@ -116,30 +126,37 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite { @Parameterized.Parameters public static Collection InputConfigs() { - return Arrays.asList(new Class[] { TestPojoWithMimeType1.class, TestPojoWithMimeType2.class }); + return Arrays.asList(new Class[] { TestPojoWithMimeType1.class, + TestPojoWithMimeType2.class }); } @Test @SuppressWarnings("unchecked") public void testReturnNoConversion() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0","--spring.jmx.enabled=false"); + ConfigurableApplicationContext context = SpringApplication.run( + this.configClass, "--server.port=0", "--spring.jmx.enabled=false"); MessageCollector collector = context.getBean(MessageCollector.class); Processor processor = context.getBean(Processor.class); String id = UUID.randomUUID().toString(); - processor.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", "application/json").build()); - TestPojoWithMimeType testPojoWithMimeType = context.getBean(TestPojoWithMimeType.class); + processor.input() + .send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") + .setHeader("contentType", "application/json").build()); + TestPojoWithMimeType testPojoWithMimeType = context + .getBean(TestPojoWithMimeType.class); Assertions.assertThat(testPojoWithMimeType.receivedPojos).hasSize(1); - Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id); + Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); Message message = (Message) collector - .forChannel(processor.output()).poll(1, - TimeUnit.SECONDS); + .forChannel(processor.output()).poll(1, TimeUnit.SECONDS); assertThat(message).isNotNull(); - StreamListenerTestUtils.BarPojo barPojo = mapper.readValue(message.getPayload(),StreamListenerTestUtils.BarPojo.class); + StreamListenerTestUtils.BarPojo barPojo = this.mapper.readValue( + message.getPayload(), StreamListenerTestUtils.BarPojo.class); assertThat(barPojo.getBar()).isEqualTo("barbar" + id); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) != null); + assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, + MimeType.class) != null); context.close(); } + } @EnableBinding(Processor.class) @@ -148,12 +165,14 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite { @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) - public StreamListenerTestUtils.BarPojo receive(StreamListenerTestUtils.FooPojo fooPojo) { + public StreamListenerTestUtils.BarPojo receive( + StreamListenerTestUtils.FooPojo fooPojo) { this.receivedPojos.add(fooPojo); StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo(); barPojo.setBar(fooPojo.getFoo()); return barPojo; } + } @EnableBinding(Processor.class) @@ -162,16 +181,20 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite { @StreamListener(Processor.INPUT) @Output(Processor.OUTPUT) - public StreamListenerTestUtils.BarPojo receive(StreamListenerTestUtils.FooPojo fooPojo) { + public StreamListenerTestUtils.BarPojo receive( + StreamListenerTestUtils.FooPojo fooPojo) { this.receivedPojos.add(fooPojo); StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo(); barPojo.setBar(fooPojo.getFoo()); return barPojo; } + } public static class TestPojoWithMimeType { + List receivedPojos = new ArrayList<>(); + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodSetupOrchestratorTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodSetupOrchestratorTests.java index 9e9198282..0505247d2 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodSetupOrchestratorTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodSetupOrchestratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -69,32 +69,43 @@ public class StreamListenerMethodSetupOrchestratorTests { @Test @SuppressWarnings("unchecked") - public void testCustomStreamListenerOrchestratorAndDefaultTogetherInSameContext() throws Exception { + public void testCustomStreamListenerOrchestratorAndDefaultTogetherInSameContext() + throws Exception { - //Two StreamListener methods, so 2 invocations - verify(customOrchestrator, times(2)).supports(any()); + // Two StreamListener methods, so 2 invocations + verify(this.customOrchestrator, times(2)).supports(any()); - Method method = multipleStreamListenerProcessor.getClass().getMethod("handleMessage"); - StreamListener streamListener = AnnotatedElementUtils.findMergedAnnotation(method, StreamListener.class); - //verify that the invocation happened on the custom Orchestrator - verify(customOrchestrator).orchestrateStreamListenerSetupMethod(streamListener, method, multipleStreamListenerProcessor); + Method method = this.multipleStreamListenerProcessor.getClass() + .getMethod("handleMessage"); + StreamListener streamListener = AnnotatedElementUtils.findMergedAnnotation(method, + StreamListener.class); + // verify that the invocation happened on the custom Orchestrator + verify(this.customOrchestrator).orchestrateStreamListenerSetupMethod( + streamListener, method, this.multipleStreamListenerProcessor); - Method method1 = multipleStreamListenerProcessor.getClass().getMethod("produceString"); - StreamListener streamListener1 = AnnotatedElementUtils.findMergedAnnotation(method, StreamListener.class); + Method method1 = this.multipleStreamListenerProcessor.getClass() + .getMethod("produceString"); + StreamListener streamListener1 = AnnotatedElementUtils + .findMergedAnnotation(method, StreamListener.class); - //Verify that the invocation did not happen on the custom orchestrator - verify(customOrchestrator, never()).orchestrateStreamListenerSetupMethod(streamListener1, method1, multipleStreamListenerProcessor); + // Verify that the invocation did not happen on the custom orchestrator + verify(this.customOrchestrator, never()).orchestrateStreamListenerSetupMethod( + streamListener1, method1, this.multipleStreamListenerProcessor); - Field field = ReflectionUtils.findField(streamListenerAnnotationBeanPostProcessor.getClass(), "streamListenerSetupMethodOrchestrators"); + Field field = ReflectionUtils.findField( + this.streamListenerAnnotationBeanPostProcessor.getClass(), + "streamListenerSetupMethodOrchestrators"); ReflectionUtils.makeAccessible(field); - Set field1 = - (LinkedHashSet)ReflectionUtils.getField(field, streamListenerAnnotationBeanPostProcessor); + Set field1; + field1 = (LinkedHashSet) ReflectionUtils + .getField(field, this.streamListenerAnnotationBeanPostProcessor); List list = new ArrayList<>(field1); - //Ensure that the custom orchestrator did not support this request + // Ensure that the custom orchestrator did not support this request assertThat(list.get(0).supports(method1)).isEqualTo(false); - //Ensure that we are using the default Orchestrator in StreamListenerAnnoatationBeanPostProcessor + // Ensure that we are using the default Orchestrator in + // StreamListenerAnnoatationBeanPostProcessor assertThat(list.get(1).supports(method1)).isEqualTo(true); } @@ -121,7 +132,7 @@ public class StreamListenerMethodSetupOrchestratorTests { @StreamListener("foobar") @SendTo("output") - public String produceString(){ + public String produceString() { return "foobar"; } @@ -140,8 +151,11 @@ public class StreamListenerMethodSetupOrchestratorTests { } @Override - public void orchestrateStreamListenerSetupMethod(StreamListener streamListener, Method method, Object bean) { - //stub method + public void orchestrateStreamListenerSetupMethod(StreamListener streamListener, + Method method, Object bean) { + // stub method } + } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnMessageTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnMessageTests.java index 74e33c764..e5a91cbe4 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnMessageTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnMessageTests.java @@ -59,14 +59,15 @@ public class StreamListenerMethodWithReturnMessageTests { @Parameterized.Parameters public static Collection InputConfigs() { - return Arrays.asList(new Class[] { TestPojoWithMessageReturn1.class, TestPojoWithMessageReturn2.class }); + return Arrays.asList(new Class[] { TestPojoWithMessageReturn1.class, + TestPojoWithMessageReturn2.class }); } @Test @SuppressWarnings("unchecked") public void testReturnMessage() throws Exception { - ConfigurableApplicationContext context = SpringApplication - .run(this.configClass, "--server.port=0","--spring.jmx.enabled=false"); + ConfigurableApplicationContext context = SpringApplication.run(this.configClass, + "--server.port=0", "--spring.jmx.enabled=false"); MessageCollector collector = context.getBean(MessageCollector.class); Processor processor = context.getBean(Processor.class); String id = UUID.randomUUID().toString(); @@ -76,7 +77,8 @@ public class StreamListenerMethodWithReturnMessageTests { TestPojoWithMessageReturn testPojoWithMessageReturn = context .getBean(TestPojoWithMessageReturn.class); Assertions.assertThat(testPojoWithMessageReturn.receivedPojos).hasSize(1); - Assertions.assertThat(testPojoWithMessageReturn.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id); + Assertions.assertThat(testPojoWithMessageReturn.receivedPojos.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); Message message = (Message) collector .forChannel(processor.output()).poll(1, TimeUnit.SECONDS); assertThat(message).isNotNull(); @@ -96,6 +98,7 @@ public class StreamListenerMethodWithReturnMessageTests { barPojo.setBar(fooPojo.getFoo()); return MessageBuilder.withPayload(barPojo).setHeader("foo", "bar").build(); } + } @EnableBinding(Processor.class) @@ -110,10 +113,13 @@ public class StreamListenerMethodWithReturnMessageTests { bazPojo.setBar(fooPojo.getFoo()); return MessageBuilder.withPayload(bazPojo).setHeader("foo", "bar").build(); } + } public static class TestPojoWithMessageReturn { + List receivedPojos = new ArrayList<>(); + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnValueTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnValueTests.java index 0c622f363..74a254db6 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnValueTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerMethodWithReturnValueTests.java @@ -58,14 +58,15 @@ public class StreamListenerMethodWithReturnValueTests { @Parameterized.Parameters public static Collection InputConfigs() { - return Arrays.asList(new Class[] { TestStringProcessor1.class, TestStringProcessor2.class }); + return Arrays.asList( + new Class[] { TestStringProcessor1.class, TestStringProcessor2.class }); } @Test @SuppressWarnings("unchecked") public void testReturn() throws Exception { - ConfigurableApplicationContext context = SpringApplication - .run(this.configClass, "--server.port=0","--spring.jmx.enabled=false"); + ConfigurableApplicationContext context = SpringApplication.run(this.configClass, + "--server.port=0", "--spring.jmx.enabled=false"); MessageCollector collector = context.getBean(MessageCollector.class); Processor processor = context.getBean(Processor.class); String id = UUID.randomUUID().toString(); @@ -77,7 +78,8 @@ public class StreamListenerMethodWithReturnValueTests { TestStringProcessor testStringProcessor = context .getBean(TestStringProcessor.class); Assertions.assertThat(testStringProcessor.receivedPojos).hasSize(1); - Assertions.assertThat(testStringProcessor.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id); + Assertions.assertThat(testStringProcessor.receivedPojos.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); assertThat(message).isNotNull(); assertThat(message.getPayload()).contains("barbar" + id); context.close(); @@ -93,6 +95,7 @@ public class StreamListenerMethodWithReturnValueTests { this.receivedPojos.add(fooPojo); return fooPojo.getFoo(); } + } @EnableBinding(Processor.class) @@ -105,10 +108,13 @@ public class StreamListenerMethodWithReturnValueTests { this.receivedPojos.add(fooPojo); return fooPojo.getFoo(); } + } public static class TestStringProcessor { + List receivedPojos = new ArrayList<>(); + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerTestUtils.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerTestUtils.java index a5f5d2fc7..1574fd510 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerTestUtils.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-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. @@ -23,8 +23,6 @@ import org.springframework.cloud.stream.annotation.Output; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.SubscribableChannel; - - /** * @author Ilayaperumal Gopinathan */ @@ -63,10 +61,11 @@ public class StreamListenerTestUtils { @Override public String toString() { final StringBuffer sb = new StringBuffer("FooPojo{"); - sb.append("foo='").append(foo).append('\''); + sb.append("foo='").append(this.foo).append('\''); sb.append('}'); return sb.toString(); } + } public static class BarPojo { @@ -84,10 +83,11 @@ public class StreamListenerTestUtils { @Override public String toString() { final StringBuffer sb = new StringBuffer("BarPojo{"); - sb.append("bar='").append(bar).append('\''); + sb.append("bar='").append(this.bar).append('\''); sb.append('}'); return sb.toString(); } + } public static class PojoWithValidation { @@ -95,9 +95,13 @@ public class StreamListenerTestUtils { @NotBlank private String foo; - public String getFoo() { return this.foo; } + public String getFoo() { + return this.foo; + } - public void setFoo(String foo) { this.foo = foo; } + public void setFoo(String foo) { + this.foo = foo; + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithAnnotatedInputOutputArgsTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithAnnotatedInputOutputArgsTests.java index 88bcca9cc..97e6d27c5 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithAnnotatedInputOutputArgsTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithAnnotatedInputOutputArgsTests.java @@ -51,14 +51,18 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests { @Test public void testInputOutputArgs() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestInputOutputArgs.class, "--server.port=0", "--spring.cloud.stream.bindings.output.contentType=text/plain", "--spring.jmx.enabled=false"); + ConfigurableApplicationContext context = SpringApplication.run( + TestInputOutputArgs.class, "--server.port=0", + "--spring.cloud.stream.bindings.output.contentType=text/plain", + "--spring.jmx.enabled=false"); sendMessageAndValidate(context); } @Test public void testInputOutputArgsWithMoreParameters() { try { - SpringApplication.run(TestInputOutputArgsWithMoreParameters.class, "--server.port=0"); + SpringApplication.run(TestInputOutputArgsWithMoreParameters.class, + "--server.port=0"); fail("Expected exception: " + INVALID_DECLARATIVE_METHOD_PARAMETERS); } catch (IllegalArgumentException e) { @@ -69,27 +73,34 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests { @Test public void testInputOutputArgsWithInvalidBindableTarget() { try { - SpringApplication.run(TestInputOutputArgsWithInvalidBindableTarget.class, "--server.port=0","--spring.jmx.enabled=false"); + SpringApplication.run(TestInputOutputArgsWithInvalidBindableTarget.class, + "--server.port=0", "--spring.jmx.enabled=false"); fail("Exception expected on using invalid bindable target as method parameter"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); + assertThat(e.getMessage()).contains( + StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); } } @Test public void testInputOutputArgsWithParameterOrderChanged() throws Exception { - ConfigurableApplicationContext context = SpringApplication - .run(TestInputOutputArgsWithParameterOrderChanged.class, "--server.port=0", "--spring.cloud.stream.bindings.output.contentType=text/plain","--spring.jmx.enabled=false"); + ConfigurableApplicationContext context = SpringApplication.run( + TestInputOutputArgsWithParameterOrderChanged.class, "--server.port=0", + "--spring.cloud.stream.bindings.output.contentType=text/plain", + "--spring.jmx.enabled=false"); sendMessageAndValidate(context); } @SuppressWarnings("unchecked") - private void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException { + private void sendMessageAndValidate(ConfigurableApplicationContext context) + throws InterruptedException { Processor processor = context.getBean(Processor.class); - processor.input().send(MessageBuilder.withPayload("hello").setHeader("contentType", "text/plain").build()); + processor.input().send(MessageBuilder.withPayload("hello") + .setHeader("contentType", "text/plain").build()); MessageCollector messageCollector = context.getBean(MessageCollector.class); - Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); + Message result = (Message) messageCollector + .forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); assertThat(result).isNotNull(); assertThat(result.getPayload()).isEqualTo("HELLO"); context.close(); @@ -105,10 +116,13 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests { input.subscribe(new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { - output.send(MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build()); + output.send(MessageBuilder + .withPayload(message.getPayload().toString().toUpperCase()) + .build()); } }); } + } @EnableBinding(Processor.class) @@ -117,15 +131,17 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests { @StreamListener public void receive(@Input(Processor.INPUT) SubscribableChannel input, - @Output(Processor.OUTPUT) final MessageChannel output, - String someArg) { + @Output(Processor.OUTPUT) final MessageChannel output, String someArg) { input.subscribe(new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { - output.send(MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build()); + output.send(MessageBuilder + .withPayload(message.getPayload().toString().toUpperCase()) + .build()); } }); } + } @EnableBinding(Processor.class) @@ -138,10 +154,13 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests { input.subscribe(new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { - output.send(MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build()); + output.send(MessageBuilder + .withPayload(message.getPayload().toString().toUpperCase()) + .build()); } }); } + } @EnableBinding(Processor.class) @@ -154,10 +173,13 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests { input.subscribe(new MessageHandler() { @Override public void handleMessage(Message message) throws MessagingException { - output.send(MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build()); + output.send(MessageBuilder + .withPayload(message.getPayload().toString().toUpperCase()) + .build()); } }); } + } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithConditionsTest.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithConditionsTest.java index d47efd038..e82436862 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithConditionsTest.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/StreamListenerWithConditionsTest.java @@ -44,28 +44,28 @@ public class StreamListenerWithConditionsTest { @Test public void testAnnotatedArgumentsWithConditionalClass() throws Exception { - ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithAnnotatedArguments.class, - "--server.port=0"); + ConfigurableApplicationContext context = SpringApplication + .run(TestPojoWithAnnotatedArguments.class, "--server.port=0"); TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context .getBean(TestPojoWithAnnotatedArguments.class); Sink sink = context.getBean(Sink.class); String id = UUID.randomUUID().toString(); sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}") - .setHeader("contentType", "application/json").setHeader("testHeader", "testValue") - .setHeader("type", "foo").build()); + .setHeader("contentType", "application/json") + .setHeader("testHeader", "testValue").setHeader("type", "foo").build()); sink.input().send(MessageBuilder.withPayload("{\"bar\":\"foofoo" + id + "\"}") - .setHeader("contentType", "application/json").setHeader("testHeader", "testValue") - .setHeader("type", "bar").build()); + .setHeader("contentType", "application/json") + .setHeader("testHeader", "testValue").setHeader("type", "bar").build()); sink.input().send(MessageBuilder.withPayload("{\"bar\":\"foofoo" + id + "\"}") - .setHeader("contentType", "application/json").setHeader("testHeader", "testValue") - .setHeader("type", "qux").build()); + .setHeader("contentType", "application/json") + .setHeader("testHeader", "testValue").setHeader("type", "qux").build()); assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1); - assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)).hasFieldOrPropertyWithValue("foo", - "barbar" + id); + assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0)) + .hasFieldOrPropertyWithValue("foo", "barbar" + id); assertThat(testPojoWithAnnotatedArguments.receivedBar).hasSize(1); - assertThat(testPojoWithAnnotatedArguments.receivedBar.get(0)).hasFieldOrPropertyWithValue("bar", - "foofoo" + id); + assertThat(testPojoWithAnnotatedArguments.receivedBar.get(0)) + .hasFieldOrPropertyWithValue("bar", "foofoo" + id); context.close(); } @@ -73,13 +73,13 @@ public class StreamListenerWithConditionsTest { public void testConditionalFailsWithReturnValue() throws Exception { try { ConfigurableApplicationContext context = SpringApplication.run( - TestConditionalOnMethodWithReturnValueFails.class, - "--server.port=0"); + TestConditionalOnMethodWithReturnValueFails.class, "--server.port=0"); context.close(); fail("Context creation failure expected"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains(StreamListenerErrorMessages.CONDITION_ON_METHOD_RETURNING_VALUE); + assertThat(e.getMessage()).contains( + StreamListenerErrorMessages.CONDITION_ON_METHOD_RETURNING_VALUE); } } @@ -87,13 +87,13 @@ public class StreamListenerWithConditionsTest { public void testConditionalFailsWithDeclarativeMethod() throws Exception { try { ConfigurableApplicationContext context = SpringApplication.run( - TestConditionalOnDeclarativeMethodFails.class, - "--server.port=0"); + TestConditionalOnDeclarativeMethodFails.class, "--server.port=0"); context.close(); fail("Context creation failure expected"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains(StreamListenerErrorMessages.CONDITION_ON_DECLARATIVE_METHOD); + assertThat(e.getMessage()).contains( + StreamListenerErrorMessages.CONDITION_ON_DECLARATIVE_METHOD); } } @@ -125,6 +125,7 @@ public class StreamListenerWithConditionsTest { public void receive(@Input("input") MessageChannel input) { // do nothing } + } @EnableBinding(Sink.class) @@ -135,5 +136,7 @@ public class StreamListenerWithConditionsTest { public String receive(String value) { return null; } + } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainConversionTest.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainConversionTest.java index e9438646d..1f604130a 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainConversionTest.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainConversionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,12 +40,12 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Marius Bogoevici * @author Oleg Zhurakousky - * * @since 1.2 */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TextPlainConversionTest.FooProcessor.class, - webEnvironment = SpringBootTest.WebEnvironment.NONE) +// @checkstyle:off +@SpringBootTest(classes = TextPlainConversionTest.FooProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) +// @checkstyle:on public class TextPlainConversionTest { @Autowired @@ -56,30 +56,38 @@ public class TextPlainConversionTest { @Test public void testTextPlainConversionOnOutput() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload("Bar").build()); + this.testProcessor.input().send(MessageBuilder.withPayload("Bar").build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); assertThat(received).isNotNull(); assertThat(received.getPayload()).isEqualTo("Foo{name='Bar'}"); } @Test public void testByteArrayConversionOnOutput() throws Exception { - testProcessor.output().send(MessageBuilder.withPayload("Bar".getBytes()).build()); + this.testProcessor.output() + .send(MessageBuilder.withPayload("Bar".getBytes()).build()); @SuppressWarnings("unchecked") - Message received = (Message)((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); assertThat(received).isNotNull(); assertThat(received.getPayload()).isEqualTo("Bar"); } @Test public void testTextPlainConversionOnInputAndOutput() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload(new Foo("Bar")).build()); + this.testProcessor.input() + .send(MessageBuilder.withPayload(new Foo("Bar")).build()); @SuppressWarnings("unchecked") - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); assertThat(received).isNotNull(); assertThat(received.getPayload()).isEqualTo("Foo{name='Foo{name='Bar'}'}"); } @@ -105,7 +113,7 @@ public class TextPlainConversionTest { } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -114,7 +122,7 @@ public class TextPlainConversionTest { @Override public String toString() { - return "Foo{name='" + name + "'}"; + return "Foo{name='" + this.name + "'}"; } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainToJsonConversionTest.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainToJsonConversionTest.java index 258479bf8..2aa9b997b 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainToJsonConversionTest.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/TextPlainToJsonConversionTest.java @@ -47,9 +47,9 @@ import static org.assertj.core.api.Assertions.assertThat; * @since 1.2 */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TextPlainToJsonConversionTest.FooProcessor.class, - webEnvironment = SpringBootTest.WebEnvironment.NONE -) +// @checkstyle:off +@SpringBootTest(classes = TextPlainToJsonConversionTest.FooProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) +// @checkstyle:on public class TextPlainToJsonConversionTest { @Autowired @@ -63,21 +63,24 @@ public class TextPlainToJsonConversionTest { @SuppressWarnings("unchecked") @Test public void testNoContentTypeToJsonConversionOnInput() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").build()); - Message received = (Message) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)) - .messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS); + this.testProcessor.input() + .send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").build()); + Message received = (Message) ((TestSupportBinder) this.binderFactory + .getBinder(null, MessageChannel.class)).messageCollector() + .forChannel(this.testProcessor.output()) + .poll(1, TimeUnit.SECONDS); assertThat(received).isNotNull(); - Foo foo = mapper.readValue(received.getPayload(),Foo.class); + Foo foo = this.mapper.readValue(received.getPayload(), Foo.class); assertThat(foo.getName()).isEqualTo("transformed-Bar"); } /** - * @since 2.0: Conversion from text/plain -> json is no longer supported. Strict contentType only. - * @throws Exception + * @since 2.0: Conversion from text/plain -> json is no longer supported. Strict + * contentType only. */ @Test(expected = MessagingException.class) - public void testTextPlainToJsonConversionOnInput() throws Exception { - testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}") + public void testTextPlainToJsonConversionOnInput() { + this.testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}") .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build()); } @@ -103,7 +106,7 @@ public class TextPlainToJsonConversionTest { } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -112,7 +115,7 @@ public class TextPlainToJsonConversionTest { @Override public String toString() { - return "Foo{name='" + name + "'}"; + return "Foo{name='" + this.name + "'}"; } } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/AggregateApplicationTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/AggregateApplicationTests.java index ad85a1fb6..e46f4e4af 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/AggregateApplicationTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/AggregateApplicationTests.java @@ -18,7 +18,6 @@ package org.springframework.cloud.stream.config.aggregate; import java.util.concurrent.TimeUnit; -import org.junit.Assert; import org.junit.Test; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -32,7 +31,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; -import static org.hamcrest.Matchers.notNullValue; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Ilayaperumal Gopinathan @@ -44,14 +43,15 @@ public class AggregateApplicationTests { @SuppressWarnings("unchecked") public void testAggregateApplication() throws Exception { ConfigurableApplicationContext context = new AggregateApplicationBuilder( - AggregateApplicationTestConfig.class).web(false).from(TestSource.class).to(TestProcessor.class).run(); - TestSupportBinder testSupportBinder = (TestSupportBinder) context.getBean(BinderFactory.class).getBinder(null, - MessageChannel.class); + AggregateApplicationTestConfig.class).web(false).from(TestSource.class) + .to(TestProcessor.class).run(); + TestSupportBinder testSupportBinder = (TestSupportBinder) context + .getBean(BinderFactory.class).getBinder(null, MessageChannel.class); MessageChannel processorOutput = testSupportBinder.getChannelForName("output"); - Message received = (Message) (testSupportBinder.messageCollector().forChannel(processorOutput) - .poll(5, TimeUnit.SECONDS)); - Assert.assertThat(received, notNullValue()); - Assert.assertTrue(received.getPayload().endsWith("processed")); + Message received = (Message) (testSupportBinder.messageCollector() + .forChannel(processorOutput).poll(5, TimeUnit.SECONDS)); + assertThat(received).isNotNull(); + assertThat(received.getPayload().endsWith("processed")).isTrue(); context.close(); } @@ -61,4 +61,5 @@ public class AggregateApplicationTests { static class AggregateApplicationTestConfig { } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/processor/TestProcessor.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/processor/TestProcessor.java index fbf9af5cf..886a48682 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/processor/TestProcessor.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/processor/TestProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -37,6 +37,8 @@ public class TestProcessor { @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Message process(String message) { - return MessageBuilder.withPayload(message + " processed").setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build(); + return MessageBuilder.withPayload(message + " processed") + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build(); } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/source/TestSource.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/source/TestSource.java index bd1cda8eb..5f45e09a2 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/source/TestSource.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/aggregate/source/TestSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,8 +44,11 @@ public class TestSource { return new MessageSource() { @Override public Message receive() { - return MessageBuilder.withPayload(new SimpleDateFormat("DDMMMYYYY").format(new Date())).setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build(); + return MessageBuilder + .withPayload(new SimpleDateFormat("DDMMMYYYY").format(new Date())) + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build(); } }; } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/ContentTypeTests.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/ContentTypeTests.java index 37725a42a..9e0277312 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/ContentTypeTests.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/ContentTypeTests.java @@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Output; import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.Ignore; import org.junit.Test; @@ -72,7 +71,7 @@ public class ContentTypeTests { source.output().send(MessageBuilder.withPayload(user).build()); Message message = (Message) collector .forChannel(source.output()).poll(1, TimeUnit.SECONDS); - User received = mapper.readValue(message.getPayload(), User.class); + User received = this.mapper.readValue(message.getPayload(), User.class); assertThat( message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) .includes(MimeTypeUtils.APPLICATION_JSON)); @@ -88,7 +87,7 @@ public class ContentTypeTests { MessageCollector collector = context.getBean(MessageCollector.class); Source source = context.getBean(Source.class); User user = new User("Alice"); - String json = mapper.writeValueAsString(user); + String json = this.mapper.writeValueAsString(user); source.output().send(MessageBuilder.withPayload(user).build()); Message message = (Message) collector .forChannel(source.output()).poll(1, TimeUnit.SECONDS); @@ -100,7 +99,7 @@ public class ContentTypeTests { } @Test - public void testSendJsonString() throws Exception{ + public void testSendJsonString() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) { @@ -125,7 +124,11 @@ public class ContentTypeTests { MessageCollector collector = context.getBean(MessageCollector.class); Source source = context.getBean(Source.class); byte[] data = new byte[] { 0, 1, 2, 3 }; - source.output().send(MessageBuilder.withPayload(data).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_OCTET_STREAM).build()); + source.output() + .send(MessageBuilder.withPayload(data) + .setHeader(MessageHeaders.CONTENT_TYPE, + MimeTypeUtils.APPLICATION_OCTET_STREAM) + .build()); Message message = (Message) collector .forChannel(source.output()).poll(1, TimeUnit.SECONDS); assertThat( @@ -138,14 +141,12 @@ public class ContentTypeTests { @Test public void testSendBinaryDataWithContentType() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( - SourceApplication.class, "--server.port=0", - "--spring.jmx.enabled=false", + SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.output.contentType=image/jpeg")) { MessageCollector collector = context.getBean(MessageCollector.class); Source source = context.getBean(Source.class); byte[] data = new byte[] { 0, 1, 2, 3 }; - source.output().send(MessageBuilder.withPayload(data) - .build()); + source.output().send(MessageBuilder.withPayload(data).build()); Message message = (Message) collector .forChannel(source.output()).poll(1, TimeUnit.SECONDS); assertThat(message.getPayload()).isEqualTo(data); @@ -161,12 +162,13 @@ public class ContentTypeTests { Source source = context.getBean(Source.class); byte[] data = new byte[] { 0, 1, 2, 3 }; source.output().send(MessageBuilder.withPayload(data) - .setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.IMAGE_JPEG) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_JPEG) .build()); Message message = (Message) collector .forChannel(source.output()).poll(1, TimeUnit.SECONDS); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) - .includes(MimeTypeUtils.IMAGE_JPEG)); + assertThat( + message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) + .includes(MimeTypeUtils.IMAGE_JPEG)); assertThat(message.getPayload()).isEqualTo(data); } } @@ -174,17 +176,17 @@ public class ContentTypeTests { @Test public void testSendJavaSerializable() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( - SourceApplication.class, "--server.port=0", - "--spring.jmx.enabled=false", + SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.output.contentType=application/x-java-serialized-object")) { MessageCollector collector = context.getBean(MessageCollector.class); Source source = context.getBean(Source.class); User user = new User("Alice"); source.output().send(MessageBuilder.withPayload(user).build()); - Message message = (Message) collector - .forChannel(source.output()).poll(1, TimeUnit.SECONDS); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) - .includes(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT)); + Message message = (Message) collector.forChannel(source.output()) + .poll(1, TimeUnit.SECONDS); + assertThat( + message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) + .includes(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT)); User received = message.getPayload(); assertThat(user.getName()).isEqualTo(received.getName()); } @@ -193,17 +195,17 @@ public class ContentTypeTests { @Test public void testSendKryoSerialized() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( - SourceApplication.class, "--server.port=0", - "--spring.jmx.enabled=false", + SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.output.contentType=application/x-java-object")) { MessageCollector collector = context.getBean(MessageCollector.class); Source source = context.getBean(Source.class); User user = new User("Alice"); source.output().send(MessageBuilder.withPayload(user).build()); - Message message = (Message) collector - .forChannel(source.output()).poll(1, TimeUnit.SECONDS); + Message message = (Message) collector.forChannel(source.output()) + .poll(1, TimeUnit.SECONDS); User received = message.getPayload(); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) + assertThat(message.getHeaders() + .get(MessageHeaders.CONTENT_TYPE, MimeType.class) .includes(MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE))); assertThat(user.getName()).isEqualTo(received.getName()); @@ -211,10 +213,9 @@ public class ContentTypeTests { } @Test - public void testSendStringType() throws Exception{ + public void testSendStringType() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( - SourceApplication.class, "--server.port=0", - "--spring.jmx.enabled=false", + SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.output.contentType=text/plain")) { MessageCollector collector = context.getBean(MessageCollector.class); Source source = context.getBean(Source.class); @@ -222,8 +223,9 @@ public class ContentTypeTests { source.output().send(MessageBuilder.withPayload(user).build()); Message message = (Message) collector .forChannel(source.output()).poll(1, TimeUnit.SECONDS); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) - .includes(MimeTypeUtils.TEXT_PLAIN)); + assertThat( + message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) + .includes(MimeTypeUtils.TEXT_PLAIN)); assertThat(message.getPayload()).isEqualTo(user.toString()); } } @@ -231,34 +233,35 @@ public class ContentTypeTests { @Test public void testSendTuple() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( - SourceApplication.class, "--server.port=0", - "--spring.jmx.enabled=false", + SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.output.contentType=application/x-spring-tuple")) { MessageCollector collector = context.getBean(MessageCollector.class); Source source = context.getBean(Source.class); - Tuple tuple = TupleBuilder.tuple().of("foo","bar"); + Tuple tuple = TupleBuilder.tuple().of("foo", "bar"); source.output().send(MessageBuilder.withPayload(tuple).build()); Message message = (Message) collector .forChannel(source.output()).poll(1, TimeUnit.SECONDS); - assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) - .includes(MessageConverterUtils.X_SPRING_TUPLE)); - assertThat(TupleBuilder.fromString(new String(message.getPayload()))).isEqualTo(tuple); + assertThat( + message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) + .includes(MessageConverterUtils.X_SPRING_TUPLE)); + assertThat(TupleBuilder.fromString(new String(message.getPayload()))) + .isEqualTo(tuple); } } @Test public void testReceiveWithDefaults() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( - SinkApplication.class, "--server.port=0", - "--spring.jmx.enabled=false")) { + SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) { TestSink testSink = context.getBean(TestSink.class); SinkApplication sourceApp = context.getBean(SinkApplication.class); User user = new User("Alice"); - testSink.pojo().send(MessageBuilder.withPayload(mapper.writeValueAsBytes(user)).build()); - Map headers = (Map) sourceApp.arguments.pop(); - User received = (User)sourceApp.arguments.pop(); - assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE)) - .includes(MimeTypeUtils.APPLICATION_JSON)); + testSink.pojo().send(MessageBuilder + .withPayload(this.mapper.writeValueAsBytes(user)).build()); + Map headers = (Map) sourceApp.arguments.pop(); + User received = (User) sourceApp.arguments.pop(); + assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE)) + .includes(MimeTypeUtils.APPLICATION_JSON)); assertThat(user.getName()).isEqualTo(received.getName()); } } @@ -266,23 +269,22 @@ public class ContentTypeTests { @Test public void testReceiveRawWithDifferentContentTypes() { try (ConfigurableApplicationContext context = SpringApplication.run( - SinkApplication.class, "--server.port=0", - "--spring.jmx.enabled=false")) { + SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) { TestSink testSink = context.getBean(TestSink.class); SinkApplication sourceApp = context.getBean(SinkApplication.class); testSink.raw().send(MessageBuilder.withPayload(new byte[4]) - .setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.IMAGE_JPEG) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_JPEG) .build()); testSink.raw().send(MessageBuilder.withPayload(new byte[4]) - .setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.IMAGE_GIF) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_GIF) .build()); - Map headers = (Map) sourceApp.arguments.pop(); + Map headers = (Map) sourceApp.arguments.pop(); sourceApp.arguments.pop(); - assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE)) + assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE)) .includes(MimeTypeUtils.IMAGE_GIF)); headers = (Map) sourceApp.arguments.pop(); sourceApp.arguments.pop(); - assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE)) + assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE)) .includes(MimeTypeUtils.IMAGE_JPEG)); } } @@ -293,20 +295,20 @@ public class ContentTypeTests { try (ConfigurableApplicationContext context = SpringApplication.run( SinkApplication.class, "--server.port=0", "--debug", "--spring.jmx.enabled=false", - "--spring.cloud.stream.bindings.pojo_input.contentType=application/x-java-object;type=org.springframework.cloud.stream.config.contentType.User" - )) { + "--spring.cloud.stream.bindings.pojo_input.contentType=" + + "application/x-java-object;type=org.springframework.cloud.stream.config.contentType.User")) { TestSink testSink = context.getBean(TestSink.class); SinkApplication sourceApp = context.getBean(SinkApplication.class); Kryo kryo = new Kryo(); User user = new User("Alice"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Output output = new Output(baos); - kryo.writeObject(output,user); + kryo.writeObject(output, user); output.close(); testSink.pojo().send(MessageBuilder.withPayload(baos.toByteArray()).build()); - Map headers = (Map) sourceApp.arguments.pop(); - User received = (User)sourceApp.arguments.pop(); - assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE)) + Map headers = (Map) sourceApp.arguments.pop(); + User received = (User) sourceApp.arguments.pop(); + assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE)) .includes(MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE))); assertThat(user.getName()).isEqualTo(received.getName()); } @@ -316,23 +318,23 @@ public class ContentTypeTests { @SuppressWarnings("deprecation") public void testReceiveKryoWithHeadersOverridingDefault() { try (ConfigurableApplicationContext context = SpringApplication.run( - SinkApplication.class, "--server.port=0", - "--spring.jmx.enabled=false" - )) { + SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) { TestSink testSink = context.getBean(TestSink.class); SinkApplication sourceApp = context.getBean(SinkApplication.class); Kryo kryo = new Kryo(); User user = new User("Alice"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Output output = new Output(baos); - kryo.writeObject(output,user); + kryo.writeObject(output, user); output.close(); - testSink.pojo().send(MessageBuilder.withPayload(baos.toByteArray()) - .setHeader(MessageHeaders.CONTENT_TYPE, MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE)) - .build()); - Map headers = (Map) sourceApp.arguments.pop(); - User received = (User)sourceApp.arguments.pop(); - assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE)) + testSink.pojo() + .send(MessageBuilder.withPayload(baos.toByteArray()) + .setHeader(MessageHeaders.CONTENT_TYPE, + MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE)) + .build()); + Map headers = (Map) sourceApp.arguments.pop(); + User received = (User) sourceApp.arguments.pop(); + assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE)) .includes(MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE))); assertThat(user.getName()).isEqualTo(received.getName()); } @@ -342,58 +344,23 @@ public class ContentTypeTests { @Ignore public void testReceiveJavaSerializable() throws Exception { try (ConfigurableApplicationContext context = SpringApplication.run( - SinkApplication.class, "--server.port=0", - "--spring.jmx.enabled=false", - "--spring.cloud.stream.bindings.pojo_input.contentType=application/x-java-serialized-object" - )) { + SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false", + "--spring.cloud.stream.bindings.pojo_input.contentType=application/x-java-serialized-object")) { TestSink testSink = context.getBean(TestSink.class); SinkApplication sourceApp = context.getBean(SinkApplication.class); User user = new User("Alice"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); new ObjectOutputStream(baos).writeObject(user); testSink.pojo().send(MessageBuilder.withPayload(baos.toByteArray()).build()); - Map headers = (Map) sourceApp.arguments.pop(); - User received = (User)sourceApp.arguments.pop(); - assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE)) + Map headers = (Map) sourceApp.arguments.pop(); + User received = (User) sourceApp.arguments.pop(); + assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE)) .includes(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT)); assertThat(user.getName()).isEqualTo(received.getName()); } } - @EnableBinding(Source.class) - @SpringBootApplication - public static class SourceApplication { - } - - @EnableBinding(TestSink.class) - @SpringBootApplication - public static class SinkApplication { - - public LinkedList arguments = new LinkedList<>(); - - @StreamListener("POJO_INPUT") - public void receive(User user, @Headers Map headers){ - arguments.push(user); - arguments.push(headers); - } - - @StreamListener("TUPLE_INPUT") - public void receive(Tuple tuple){ - } - - @StreamListener("STRING_INPUT") - public void receive(String string){ - } - - @StreamListener("RAW_INPUT") - public void receive(byte[] data, @Headers Map headers){ - arguments.push(data); - arguments.push(headers); - } - - } - public interface TestSink { @Input("POJO_INPUT") @@ -409,4 +376,39 @@ public class ContentTypeTests { SubscribableChannel raw(); } + + @EnableBinding(Source.class) + @SpringBootApplication + public static class SourceApplication { + + } + + @EnableBinding(TestSink.class) + @SpringBootApplication + public static class SinkApplication { + + public LinkedList arguments = new LinkedList<>(); + + @StreamListener("POJO_INPUT") + public void receive(User user, @Headers Map headers) { + this.arguments.push(user); + this.arguments.push(headers); + } + + @StreamListener("TUPLE_INPUT") + public void receive(Tuple tuple) { + } + + @StreamListener("STRING_INPUT") + public void receive(String string) { + } + + @StreamListener("RAW_INPUT") + public void receive(byte[] data, @Headers Map headers) { + this.arguments.push(data); + this.arguments.push(headers); + } + + } + } diff --git a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/User.java b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/User.java index bfadca1c3..b14135697 100644 --- a/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/User.java +++ b/spring-cloud-stream-integration-tests/src/test/java/org/springframework/cloud/stream/config/contentType/User.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ public class User implements Serializable { private String name; - public User(){} + public User() { + } @JsonCreator public User(@JsonProperty("name") String name) { @@ -38,7 +39,7 @@ public class User implements Serializable { } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -48,8 +49,9 @@ public class User implements Serializable { @Override public String toString() { final StringBuffer sb = new StringBuffer("User{"); - sb.append("name='").append(name).append('\''); + sb.append("name='").append(this.name).append('\''); sb.append('}'); return sb.toString(); } + } diff --git a/spring-cloud-stream-reactive/pom.xml b/spring-cloud-stream-reactive/pom.xml index afdd00844..b0fd9df5d 100644 --- a/spring-cloud-stream-reactive/pom.xml +++ b/spring-cloud-stream-reactive/pom.xml @@ -1,5 +1,7 @@ - + org.springframework.cloud spring-cloud-stream-parent diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/DefaultFluxSender.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/DefaultFluxSender.java index 2eb453c07..f08f891fb 100644 --- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/DefaultFluxSender.java +++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/DefaultFluxSender.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,17 +33,16 @@ import org.springframework.util.Assert; * {@link reactor.core.publisher.Flux}. * * @author Soby Chacko - * * @since 1.3.0 */ class DefaultFluxSender implements FluxSender { + private final Consumer consumer; + private Log log = LogFactory.getLog(DefaultFluxSender.class); private volatile Disposable disposable; - private final Consumer consumer; - DefaultFluxSender(Consumer consumer) { Assert.notNull(consumer, "Consumer must not be null"); this.consumer = consumer; @@ -54,12 +53,8 @@ class DefaultFluxSender implements FluxSender { MonoProcessor sendResult = MonoProcessor.create(); // add error handling and reconnect in the event of an error this.disposable = flux - .doOnError(e -> this.log.error("Error during processing: ", e)) - .retry() - .subscribe( - this.consumer, - sendResult::onError, - sendResult::onComplete); + .doOnError(e -> this.log.error("Error during processing: ", e)).retry() + .subscribe(this.consumer, sendResult::onError, sendResult::onComplete); return sendResult; } diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/FluxSender.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/FluxSender.java index d70052ab0..84486460f 100644 --- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/FluxSender.java +++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/FluxSender.java @@ -22,12 +22,11 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; /** - * Used for {@link org.springframework.cloud.stream.annotation.StreamListener} - * and {@link org.springframework.cloud.stream.reactive.StreamEmitter} arguments - * annotated with {@link org.springframework.cloud.stream.annotation.Output}. + * Used for {@link org.springframework.cloud.stream.annotation.StreamListener} and + * {@link org.springframework.cloud.stream.reactive.StreamEmitter} arguments annotated + * with {@link org.springframework.cloud.stream.annotation.Output}. * * @author Marius Bogoevici - * * @see reactor.core.Disposable */ public interface FluxSender extends Closeable { diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToFluxSenderParameterAdapter.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToFluxSenderParameterAdapter.java index c71303127..ab7c4c4f2 100644 --- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToFluxSenderParameterAdapter.java +++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToFluxSenderParameterAdapter.java @@ -42,9 +42,8 @@ public class MessageChannelToFluxSenderParameterAdapter @Override public FluxSender adapt(MessageChannel bindingTarget, MethodParameter parameter) { - return new DefaultFluxSender(result -> - bindingTarget.send(result instanceof Message - ? (Message) result + return new DefaultFluxSender(result -> bindingTarget + .send(result instanceof Message ? (Message) result : MessageBuilder.withPayload(result).build())); } diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapter.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapter.java index d809a985f..311fea923 100644 --- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapter.java +++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import org.springframework.util.Assert; /** * Adapts an {@link org.springframework.cloud.stream.annotation.Input} annotated * {@link MessageChannel} to a {@link Flux}. + * * @author Marius Bogoevici * @author Ilayaperumal Gopinathan * @author Vinicius Carvalho @@ -41,7 +42,8 @@ public class MessageChannelToInputFluxParameterAdapter private final CompositeMessageConverter messageConverter; - public MessageChannelToInputFluxParameterAdapter(CompositeMessageConverter messageConverter) { + public MessageChannelToInputFluxParameterAdapter( + CompositeMessageConverter messageConverter) { Assert.notNull(messageConverter, "cannot not be null"); this.messageConverter = messageConverter; } @@ -53,19 +55,22 @@ public class MessageChannelToInputFluxParameterAdapter } @Override - public Flux adapt(final SubscribableChannel bindingTarget, MethodParameter parameter) { - final ResolvableType fluxResolvableType = ResolvableType.forMethodParameter(parameter); + public Flux adapt(final SubscribableChannel bindingTarget, + MethodParameter parameter) { + final ResolvableType fluxResolvableType = ResolvableType + .forMethodParameter(parameter); final ResolvableType fluxTypeParameter = fluxResolvableType.getGeneric(0); final Class fluxTypeParameterRawClass = fluxTypeParameter.getRawClass(); - final Class fluxTypeParameterClass = (fluxTypeParameterRawClass != null) ? fluxTypeParameterRawClass - : Object.class; + final Class fluxTypeParameterClass = (fluxTypeParameterRawClass != null) + ? fluxTypeParameterRawClass : Object.class; final Object monitor = new Object(); if (Message.class.isAssignableFrom(fluxTypeParameterClass)) { final ResolvableType payloadTypeParameter = fluxTypeParameter.getGeneric(0); - final Class payloadTypeParameterRawClass = payloadTypeParameter.getRawClass(); + final Class payloadTypeParameterRawClass = payloadTypeParameter + .getRawClass(); final Class payloadTypeParameterClass = (payloadTypeParameterRawClass != null) ? payloadTypeParameterRawClass : Object.class; @@ -73,12 +78,14 @@ public class MessageChannelToInputFluxParameterAdapter MessageHandler messageHandler = message -> { synchronized (monitor) { - if (payloadTypeParameterClass.isAssignableFrom(message.getPayload().getClass())) { + if (payloadTypeParameterClass + .isAssignableFrom(message.getPayload().getClass())) { emitter.next(message); } else { emitter.next(MessageBuilder.createMessage( - this.messageConverter.fromMessage(message, payloadTypeParameterClass), + this.messageConverter.fromMessage(message, + payloadTypeParameterClass), message.getHeaders())); } } @@ -91,11 +98,13 @@ public class MessageChannelToInputFluxParameterAdapter return Flux.create(emitter -> { MessageHandler messageHandler = message -> { synchronized (monitor) { - if (fluxTypeParameterClass.isAssignableFrom(message.getPayload().getClass())) { + if (fluxTypeParameterClass + .isAssignableFrom(message.getPayload().getClass())) { emitter.next(message.getPayload()); } else { - emitter.next(this.messageConverter.fromMessage(message, fluxTypeParameterClass)); + emitter.next(this.messageConverter.fromMessage(message, + fluxTypeParameterClass)); } } }; @@ -104,4 +113,5 @@ public class MessageChannelToInputFluxParameterAdapter }).publish().autoConnect(); } } + } diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/PublisherToMessageChannelResultAdapter.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/PublisherToMessageChannelResultAdapter.java index 9f143346d..c9c4b5744 100644 --- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/PublisherToMessageChannelResultAdapter.java +++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/PublisherToMessageChannelResultAdapter.java @@ -21,7 +21,6 @@ import java.io.Closeable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.reactivestreams.Publisher; - import reactor.core.Disposable; import reactor.core.publisher.Flux; @@ -49,15 +48,14 @@ public class PublisherToMessageChannelResultAdapter && MessageChannel.class.isAssignableFrom(bindingTarget); } - public Closeable adapt(Publisher streamListenerResult, MessageChannel bindingTarget) { + public Closeable adapt(Publisher streamListenerResult, + MessageChannel bindingTarget) { Disposable disposable = Flux.from(streamListenerResult) .doOnError(e -> this.log.error("Error while processing result", e)) .retry() - .subscribe( - result -> - bindingTarget.send(result instanceof Message - ? (Message) result - : MessageBuilder.withPayload(result).build())); + .subscribe(result -> bindingTarget + .send(result instanceof Message ? (Message) result + : MessageBuilder.withPayload(result).build())); return disposable::dispose; } diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/ReactiveSupportAutoConfiguration.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/ReactiveSupportAutoConfiguration.java index 81f9c005c..2ac2b5d60 100644 --- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/ReactiveSupportAutoConfiguration.java +++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/ReactiveSupportAutoConfiguration.java @@ -30,6 +30,11 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnBean(BindingService.class) public class ReactiveSupportAutoConfiguration { + @Bean + public static StreamEmitterAnnotationBeanPostProcessor streamEmitterAnnotationBeanPostProcessor() { + return new StreamEmitterAnnotationBeanPostProcessor(); + } + @Bean @ConditionalOnMissingBean(MessageChannelToInputFluxParameterAdapter.class) public MessageChannelToInputFluxParameterAdapter messageChannelToInputFluxArgumentAdapter( @@ -50,8 +55,4 @@ public class ReactiveSupportAutoConfiguration { return new PublisherToMessageChannelResultAdapter(); } - @Bean - public static StreamEmitterAnnotationBeanPostProcessor streamEmitterAnnotationBeanPostProcessor() { - return new StreamEmitterAnnotationBeanPostProcessor(); - } } diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitter.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitter.java index 16202d9f4..793eb146b 100644 --- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitter.java +++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,12 +30,13 @@ import org.springframework.cloud.stream.annotation.Output; * Method level annotation that marks a method to be an emitter to outputs declared via * {@link EnableBinding} (e.g. channels). * - * This annotation is intended to be used in a Spring Cloud Stream application that requires - * a source to write to one or more {@link Output}s using the reactive paradigm. + * This annotation is intended to be used in a Spring Cloud Stream application that + * requires a source to write to one or more {@link Output}s using the reactive paradigm. * * No {@link Input}s are allowed on a method that is annotated with StreamEmitter. * - * Depending on how the method is structured, there are some flexibility in how the {@link Output} may be used. + * Depending on how the method is structured, there are some flexibility in how the + * {@link Output} may be used. * * Here are some supported usage patterns: * @@ -44,14 +45,14 @@ import org.springframework.cloud.stream.annotation.Output; *
  * @StreamEmitter
  * @Output(Source.OUTPUT)
- * public Flux emit() {
+ * public Flux<String> emit() {
  * 	return Flux.intervalMillis(1000)
  * 		.map(l -> "Hello World!!");
  * }
  * 
* - * The following examples show how a void return type can be used on a method with StreamEmitter and how the - * method signatures could be used in a flexible manner. + * The following examples show how a void return type can be used on a method with + * StreamEmitter and how the method signatures could be used in a flexible manner. * *
  * @StreamEmitter
@@ -91,4 +92,6 @@ import org.springframework.cloud.stream.annotation.Output;
 @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
-public @interface StreamEmitter {}
+public @interface StreamEmitter {
+
+}
diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterAnnotationBeanPostProcessor.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterAnnotationBeanPostProcessor.java
index 231eeed3b..20bbaaedd 100644
--- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterAnnotationBeanPostProcessor.java
+++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterAnnotationBeanPostProcessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-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.
@@ -54,17 +54,22 @@ import org.springframework.util.ReflectionUtils;
 import org.springframework.util.StringUtils;
 
 /**
- * {@link BeanPostProcessor} that handles {@link StreamEmitter} annotations found on bean methods.
+ * {@link BeanPostProcessor} that handles {@link StreamEmitter} annotations found on bean
+ * methods.
  *
  * @author Soby Chacko
  * @author Artem Bilan
- *
  * @since 1.3.0
  */
-public class StreamEmitterAnnotationBeanPostProcessor
-		implements BeanPostProcessor, SmartInitializingSingleton, ApplicationContextAware, SmartLifecycle {
+public class StreamEmitterAnnotationBeanPostProcessor implements BeanPostProcessor,
+		SmartInitializingSingleton, ApplicationContextAware, SmartLifecycle {
 
-	private static final Log log = LogFactory.getLog(StreamEmitterAnnotationBeanPostProcessor.class);
+	private static final Log log = LogFactory
+			.getLog(StreamEmitterAnnotationBeanPostProcessor.class);
+
+	private final List closeableFluxResources = new ArrayList<>();
+
+	private final Lock lock = new ReentrantLock();
 
 	@SuppressWarnings("rawtypes")
 	private Collection parameterAdapters;
@@ -72,148 +77,39 @@ public class StreamEmitterAnnotationBeanPostProcessor
 	@SuppressWarnings("rawtypes")
 	private Collection resultAdapters;
 
-	private final List closeableFluxResources = new ArrayList<>();
-
 	private ConfigurableApplicationContext applicationContext;
 
 	private MultiValueMap mappedStreamEmitterMethods = new LinkedMultiValueMap<>();
 
 	private volatile boolean running;
 
-	private final Lock lock = new ReentrantLock();
-
-	@Override
-	public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext,
-				"ConfigurableApplicationContext is required");
-		this.applicationContext = (ConfigurableApplicationContext) applicationContext;
-	}
-
-	@Override
-	public void afterSingletonsInstantiated() {
-		this.parameterAdapters = this.applicationContext.getBeansOfType(StreamListenerParameterAdapter.class).values();
-		this.resultAdapters = new ArrayList<>(this.applicationContext.getBeansOfType(StreamListenerResultAdapter.class).values());
-		this.resultAdapters.add(new MessageChannelStreamListenerResultAdapter());
-	}
-
-	@Override
-	public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
-		Class targetClass = AopUtils.getTargetClass(bean);
-		ReflectionUtils.doWithMethods(targetClass,
-				method -> {
-					if (AnnotatedElementUtils.isAnnotated(method, StreamEmitter.class)) {
-						mappedStreamEmitterMethods.add(bean, method);
-					}
-				}, ReflectionUtils.USER_DECLARED_METHODS);
-		return bean;
-	}
-
-	@Override
-	public void start() {
-		try {
-			lock.lock();
-			if (!running) {
-				mappedStreamEmitterMethods.forEach((k, v) -> v.forEach(item -> {
-							Assert.isTrue(item.getAnnotation(Input.class) == null,
-									StreamEmitterErrorMessages.INPUT_ANNOTATIONS_ARE_NOT_ALLOWED);
-							String methodAnnotatedOutboundName =
-									StreamAnnotationCommonMethodUtils.getOutboundBindingTargetName(item);
-							int outputAnnotationCount = StreamAnnotationCommonMethodUtils.outputAnnotationCount(item);
-							validateStreamEmitterMethod(item, outputAnnotationCount, methodAnnotatedOutboundName);
-							invokeSetupMethodOnToTargetChannel(item, k, methodAnnotatedOutboundName);
-						}
-				));
-				this.running = true;
-			}
-		}
-		finally {
-			lock.unlock();
-		}
-	}
-
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private void invokeSetupMethodOnToTargetChannel(Method method, Object bean, String outboundName) {
-		Object[] arguments = new Object[method.getParameterCount()];
-		Object targetBean = null;
-		for (int parameterIndex = 0; parameterIndex < arguments.length; parameterIndex++) {
-			MethodParameter methodParameter = new SynthesizingMethodParameter(method, parameterIndex);
-			Class parameterType = methodParameter.getParameterType();
-			Object targetReferenceValue = null;
-			if (methodParameter.hasParameterAnnotation(Output.class)) {
-				targetReferenceValue = AnnotationUtils.getValue(methodParameter.getParameterAnnotation(Output.class));
-			}
-			else if (arguments.length == 1 && StringUtils.hasText(outboundName)) {
-				targetReferenceValue = outboundName;
-			}
-			if (targetReferenceValue != null) {
-				targetBean = this.applicationContext.getBean((String) targetReferenceValue);
-				for (StreamListenerParameterAdapter streamListenerParameterAdapter : this.parameterAdapters) {
-					if (streamListenerParameterAdapter.supports(targetBean.getClass(), methodParameter)) {
-						arguments[parameterIndex] = streamListenerParameterAdapter.adapt(targetBean,
-								methodParameter);
-						if (arguments[parameterIndex] instanceof FluxSender) {
-							closeableFluxResources.add((FluxSender) arguments[parameterIndex]);
-						}
-						break;
-					}
-				}
-				Assert.notNull(arguments[parameterIndex], "Cannot convert argument " + parameterIndex + " of " + method
-						+ "from " + targetBean.getClass() + " to " + parameterType);
-			}
-			else {
-				throw new IllegalStateException(StreamEmitterErrorMessages.ATLEAST_ONE_OUTPUT);
-			}
-		}
-		Object result;
-		try {
-			result = method.invoke(bean, arguments);
-		}
-		catch (Exception e) {
-			throw new BeanInitializationException("Cannot setup StreamEmitter for " + method, e);
-		}
-
-		if (!Void.TYPE.equals(method.getReturnType())) {
-			if (targetBean == null) {
-				targetBean = this.applicationContext.getBean(outboundName);
-			}
-			boolean streamListenerResultAdapterFound = false;
-			for (StreamListenerResultAdapter streamListenerResultAdapter : this.resultAdapters) {
-				if (streamListenerResultAdapter.supports(result.getClass(), targetBean.getClass())) {
-					Closeable fluxDisposable = streamListenerResultAdapter.adapt(result, targetBean);
-					closeableFluxResources.add(fluxDisposable);
-					streamListenerResultAdapterFound = true;
-					break;
-				}
-			}
-			Assert.state(streamListenerResultAdapterFound,
-					StreamEmitterErrorMessages.CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS);
-		}
-	}
-
-	private static void validateStreamEmitterMethod(Method method, int outputAnnotationCount,
-			String methodAnnotatedOutboundName) {
+	private static void validateStreamEmitterMethod(Method method,
+			int outputAnnotationCount, String methodAnnotatedOutboundName) {
 
 		if (StringUtils.hasText(methodAnnotatedOutboundName)) {
 			Assert.isTrue(outputAnnotationCount == 0,
 					StreamEmitterErrorMessages.INVALID_OUTPUT_METHOD_PARAMETERS);
 		}
 		else {
-			Assert.isTrue(outputAnnotationCount > 0, StreamEmitterErrorMessages.NO_OUTPUT_SPECIFIED);
+			Assert.isTrue(outputAnnotationCount > 0,
+					StreamEmitterErrorMessages.NO_OUTPUT_SPECIFIED);
 		}
 
 		if (!method.getReturnType().equals(Void.TYPE)) {
 			Assert.isTrue(StringUtils.hasText(methodAnnotatedOutboundName),
 					StreamEmitterErrorMessages.RETURN_TYPE_NO_OUTBOUND_SPECIFIED);
-			Assert.isTrue(method.getParameterCount() == 0, StreamEmitterErrorMessages.RETURN_TYPE_METHOD_ARGUMENTS);
+			Assert.isTrue(method.getParameterCount() == 0,
+					StreamEmitterErrorMessages.RETURN_TYPE_METHOD_ARGUMENTS);
 		}
 		else {
 			if (!StringUtils.hasText(methodAnnotatedOutboundName)) {
 				int methodArgumentsLength = method.getParameterTypes().length;
 				for (int parameterIndex = 0; parameterIndex < methodArgumentsLength; parameterIndex++) {
-					MethodParameter methodParameter = new MethodParameter(method, parameterIndex);
+					MethodParameter methodParameter = new MethodParameter(method,
+							parameterIndex);
 					if (methodParameter.hasParameterAnnotation(Output.class)) {
-						String outboundName = (String) AnnotationUtils
-								.getValue(methodParameter.getParameterAnnotation(Output.class));
+						String outboundName = (String) AnnotationUtils.getValue(
+								methodParameter.getParameterAnnotation(Output.class));
 						Assert.isTrue(StringUtils.hasText(outboundName),
 								StreamEmitterErrorMessages.INVALID_OUTBOUND_NAME);
 					}
@@ -226,6 +122,131 @@ public class StreamEmitterAnnotationBeanPostProcessor
 		}
 	}
 
+	@Override
+	public final void setApplicationContext(ApplicationContext applicationContext)
+			throws BeansException {
+		Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext,
+				"ConfigurableApplicationContext is required");
+		this.applicationContext = (ConfigurableApplicationContext) applicationContext;
+	}
+
+	@Override
+	public void afterSingletonsInstantiated() {
+		this.parameterAdapters = this.applicationContext
+				.getBeansOfType(StreamListenerParameterAdapter.class).values();
+		this.resultAdapters = new ArrayList<>(this.applicationContext
+				.getBeansOfType(StreamListenerResultAdapter.class).values());
+		this.resultAdapters.add(new MessageChannelStreamListenerResultAdapter());
+	}
+
+	@Override
+	public Object postProcessAfterInitialization(final Object bean, final String beanName)
+			throws BeansException {
+		Class targetClass = AopUtils.getTargetClass(bean);
+		ReflectionUtils.doWithMethods(targetClass, method -> {
+			if (AnnotatedElementUtils.isAnnotated(method, StreamEmitter.class)) {
+				this.mappedStreamEmitterMethods.add(bean, method);
+			}
+		}, ReflectionUtils.USER_DECLARED_METHODS);
+		return bean;
+	}
+
+	@Override
+	public void start() {
+		try {
+			this.lock.lock();
+			if (!this.running) {
+				this.mappedStreamEmitterMethods.forEach((k, v) -> v.forEach(item -> {
+					Assert.isTrue(item.getAnnotation(Input.class) == null,
+							StreamEmitterErrorMessages.INPUT_ANNOTATIONS_ARE_NOT_ALLOWED);
+					String methodAnnotatedOutboundName = StreamAnnotationCommonMethodUtils
+							.getOutboundBindingTargetName(item);
+					int outputAnnotationCount = StreamAnnotationCommonMethodUtils
+							.outputAnnotationCount(item);
+					validateStreamEmitterMethod(item, outputAnnotationCount,
+							methodAnnotatedOutboundName);
+					invokeSetupMethodOnToTargetChannel(item, k,
+							methodAnnotatedOutboundName);
+				}));
+				this.running = true;
+			}
+		}
+		finally {
+			this.lock.unlock();
+		}
+	}
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private void invokeSetupMethodOnToTargetChannel(Method method, Object bean,
+			String outboundName) {
+		Object[] arguments = new Object[method.getParameterCount()];
+		Object targetBean = null;
+		for (int parameterIndex = 0; parameterIndex < arguments.length; parameterIndex++) {
+			MethodParameter methodParameter = new SynthesizingMethodParameter(method,
+					parameterIndex);
+			Class parameterType = methodParameter.getParameterType();
+			Object targetReferenceValue = null;
+			if (methodParameter.hasParameterAnnotation(Output.class)) {
+				targetReferenceValue = AnnotationUtils
+						.getValue(methodParameter.getParameterAnnotation(Output.class));
+			}
+			else if (arguments.length == 1 && StringUtils.hasText(outboundName)) {
+				targetReferenceValue = outboundName;
+			}
+			if (targetReferenceValue != null) {
+				targetBean = this.applicationContext
+						.getBean((String) targetReferenceValue);
+				for (StreamListenerParameterAdapter streamListenerParameterAdapter : this.parameterAdapters) {
+					if (streamListenerParameterAdapter.supports(targetBean.getClass(),
+							methodParameter)) {
+						arguments[parameterIndex] = streamListenerParameterAdapter
+								.adapt(targetBean, methodParameter);
+						if (arguments[parameterIndex] instanceof FluxSender) {
+							this.closeableFluxResources
+									.add((FluxSender) arguments[parameterIndex]);
+						}
+						break;
+					}
+				}
+				Assert.notNull(arguments[parameterIndex],
+						"Cannot convert argument " + parameterIndex + " of " + method
+								+ "from " + targetBean.getClass() + " to "
+								+ parameterType);
+			}
+			else {
+				throw new IllegalStateException(
+						StreamEmitterErrorMessages.ATLEAST_ONE_OUTPUT);
+			}
+		}
+		Object result;
+		try {
+			result = method.invoke(bean, arguments);
+		}
+		catch (Exception e) {
+			throw new BeanInitializationException(
+					"Cannot setup StreamEmitter for " + method, e);
+		}
+
+		if (!Void.TYPE.equals(method.getReturnType())) {
+			if (targetBean == null) {
+				targetBean = this.applicationContext.getBean(outboundName);
+			}
+			boolean streamListenerResultAdapterFound = false;
+			for (StreamListenerResultAdapter streamListenerResultAdapter : this.resultAdapters) {
+				if (streamListenerResultAdapter.supports(result.getClass(),
+						targetBean.getClass())) {
+					Closeable fluxDisposable = streamListenerResultAdapter.adapt(result,
+							targetBean);
+					this.closeableFluxResources.add(fluxDisposable);
+					streamListenerResultAdapterFound = true;
+					break;
+				}
+			}
+			Assert.state(streamListenerResultAdapterFound,
+					StreamEmitterErrorMessages.CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS);
+		}
+	}
+
 	@Override
 	public boolean isAutoStartup() {
 		return true;
@@ -244,7 +265,7 @@ public class StreamEmitterAnnotationBeanPostProcessor
 		try {
 			this.lock.lock();
 			if (this.running) {
-				for (Closeable closeable : closeableFluxResources) {
+				for (Closeable closeable : this.closeableFluxResources) {
 					try {
 						closeable.close();
 					}
diff --git a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterErrorMessages.java b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterErrorMessages.java
index 35965426f..7f297978b 100644
--- a/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterErrorMessages.java
+++ b/spring-cloud-stream-reactive/src/main/java/org/springframework/cloud/stream/reactive/StreamEmitterErrorMessages.java
@@ -24,27 +24,24 @@ import org.springframework.cloud.stream.binding.StreamAnnotationErrorMessages;
  */
 abstract class StreamEmitterErrorMessages extends StreamAnnotationErrorMessages {
 
-	private static final String PREFIX = "A method annotated with @StreamEmitter ";
-
-	static final String RETURN_TYPE_NO_OUTBOUND_SPECIFIED = PREFIX
-			+ "having a return type should also have an outbound target specified at the method level.";
-
-	static final String RETURN_TYPE_METHOD_ARGUMENTS = PREFIX
-			+ "having a return type should not have any method arguments";
-
 	static final String INVALID_OUTPUT_METHOD_PARAMETERS = "@Output annotations are not permitted on "
 			+ "method parameters while using the @StreamEmitter and a method-level output specification";
-
 	static final String NO_OUTPUT_SPECIFIED = "No method level or parameter level @Output annotations are detected. "
 			+ "@StreamEmitter requires a method or parameter level @Output annotation.";
 
+	// @checkstyle:off
+	static final String CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS = "No suitable adapters are found that can convert the return type";
+
+	// @checkstyle:on
+
+	private static final String PREFIX = "A method annotated with @StreamEmitter ";
+	static final String RETURN_TYPE_NO_OUTBOUND_SPECIFIED = PREFIX
+			+ "having a return type should also have an outbound target specified at the method level.";
+	static final String RETURN_TYPE_METHOD_ARGUMENTS = PREFIX
+			+ "having a return type should not have any method arguments";
 	static final String OUTPUT_ANNOTATION_MISSING_ON_METHOD_PARAMETERS_VOID_RETURN_TYPE = PREFIX
 			+ "and void return type without method level @Output annotation requires @Output on each of the method parameter";
-
 	static final String INPUT_ANNOTATIONS_ARE_NOT_ALLOWED = PREFIX
 			+ "cannot contain @Input annotations";
 
-	static final String CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS =
-			"No suitable adapters are found that can convert the return type";
-
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapterTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapterTests.java
index 504a2bce3..2c1a0899d 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapterTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/MessageChannelToInputFluxParameterAdapterTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -46,7 +46,8 @@ public class MessageChannelToInputFluxParameterAdapterTests {
 	public void testWrapperFluxSupportsMultipleSubscriptions() throws Exception {
 		List results = Collections.synchronizedList(new ArrayList<>());
 		CountDownLatch latch = new CountDownLatch(4);
-		final MessageChannelToInputFluxParameterAdapter messageChannelToInputFluxParameterAdapter = new MessageChannelToInputFluxParameterAdapter(
+		final MessageChannelToInputFluxParameterAdapter messageChannelToInputFluxParameterAdapter;
+		messageChannelToInputFluxParameterAdapter = new MessageChannelToInputFluxParameterAdapter(
 				new CompositeMessageConverter(
 						Collections.singleton(new MappingJackson2MessageConverter())));
 		final Method processMethod = ReflectionUtils.findMethod(
@@ -79,4 +80,5 @@ public class MessageChannelToInputFluxParameterAdapterTests {
 	public void process(Flux> message) {
 		// do nothing - we just reference this method from the test
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterBasicTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterBasicTests.java
index a62b1ffa1..b8d48f6a7 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterBasicTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterBasicTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
 
 package org.springframework.cloud.stream.reactive;
 
-
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.List;
@@ -51,10 +50,87 @@ import static org.assertj.core.api.Assertions.assertThat;
  */
 public class StreamEmitterBasicTests {
 
+	private static void receiveAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
+		Source source = context.getBean(Source.class);
+		MessageCollector messageCollector = context.getBean(MessageCollector.class);
+		List messages = new ArrayList<>();
+		for (int i = 0; i < 1000; i++) {
+			messages.add((String) messageCollector.forChannel(source.output())
+					.poll(5000, TimeUnit.MILLISECONDS).getPayload());
+		}
+		for (int i = 0; i < 1000; i++) {
+			assertThat(new String(messages.get(i))).isEqualTo("HELLO WORLD!!" + i);
+		}
+	}
+
+	private static void receiveAndValidateMultipleOutputs(
+			ConfigurableApplicationContext context) throws InterruptedException {
+		TestMultiOutboundChannels source = context
+				.getBean(TestMultiOutboundChannels.class);
+		MessageCollector messageCollector = context.getBean(MessageCollector.class);
+		List messages = new ArrayList<>();
+		assertMessages(source.output1(), messageCollector, messages);
+		messages.clear();
+		assertMessages(source.output2(), messageCollector, messages);
+		messages.clear();
+		assertMessages(source.output3(), messageCollector, messages);
+		messages.clear();
+	}
+
+	private static void receiveAndValidateMultiStreamEmittersInSameContext(
+			ConfigurableApplicationContext context1) throws InterruptedException {
+		TestMultiOutboundChannels source1 = context1
+				.getBean(TestMultiOutboundChannels.class);
+		MessageCollector messageCollector = context1.getBean(MessageCollector.class);
+
+		List messages = new ArrayList<>();
+		assertMessagesX(source1.output1(), messageCollector, messages);
+		messages.clear();
+		assertMessagesY(source1.output2(), messageCollector, messages);
+		messages.clear();
+	}
+
+	private static void assertMessages(MessageChannel channel,
+			MessageCollector messageCollector, List messages)
+			throws InterruptedException {
+		for (int i = 0; i < 1000; i++) {
+			messages.add((String) messageCollector.forChannel(channel)
+					.poll(5000, TimeUnit.MILLISECONDS).getPayload());
+		}
+		for (int i = 0; i < 1000; i++) {
+			assertThat(new String(messages.get(i))).isEqualTo("Hello World!!" + i);
+		}
+	}
+
+	private static void assertMessagesX(MessageChannel channel,
+			MessageCollector messageCollector, List messages)
+			throws InterruptedException {
+		for (int i = 0; i < 1000; i++) {
+			messages.add((String) messageCollector.forChannel(channel)
+					.poll(5000, TimeUnit.MILLISECONDS).getPayload());
+		}
+		for (int i = 0; i < 1000; i++) {
+			assertThat(new String(messages.get(i))).isEqualTo("Hello World!!" + i);
+		}
+	}
+
+	private static void assertMessagesY(MessageChannel channel,
+			MessageCollector messageCollector, List messages)
+			throws InterruptedException {
+		for (int i = 0; i < 1000; i++) {
+			messages.add((String) messageCollector.forChannel(channel)
+					.poll(5000, TimeUnit.MILLISECONDS).getPayload());
+		}
+		for (int i = 0; i < 1000; i++) {
+			assertThat(new String(messages.get(i))).isEqualTo("Hello FooBar!!" + i);
+		}
+	}
+
 	@Test
 	public void testFluxReturnAndOutputMethodLevel() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(TestFluxReturnAndOutputMethodLevel.class,
-				"--server.port=0",
+		ConfigurableApplicationContext context = SpringApplication.run(
+				TestFluxReturnAndOutputMethodLevel.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
@@ -64,8 +140,8 @@ public class StreamEmitterBasicTests {
 
 	@Test
 	public void testVoidReturnAndOutputMethodParameter() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(TestVoidReturnAndOutputMethodParameter.class,
-				"--server.port=0",
+		ConfigurableApplicationContext context = SpringApplication.run(
+				TestVoidReturnAndOutputMethodParameter.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
@@ -75,8 +151,8 @@ public class StreamEmitterBasicTests {
 
 	@Test
 	public void testVoidReturnAndOutputAtMethodLevel() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(TestVoidReturnAndOutputAtMethodLevel.class,
-				"--server.port=0",
+		ConfigurableApplicationContext context = SpringApplication.run(
+				TestVoidReturnAndOutputAtMethodLevel.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
@@ -86,8 +162,8 @@ public class StreamEmitterBasicTests {
 
 	@Test
 	public void testVoidReturnAndMultipleOutputMethodParameters() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(TestVoidReturnAndMultipleOutputMethodParameters.class,
-				"--server.port=0",
+		ConfigurableApplicationContext context = SpringApplication.run(
+				TestVoidReturnAndMultipleOutputMethodParameters.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain",
@@ -100,8 +176,8 @@ public class StreamEmitterBasicTests {
 
 	@Test
 	public void testMultipleStreamEmitterMethods() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(TestMultipleStreamEmitterMethods.class,
-				"--server.port=0",
+		ConfigurableApplicationContext context = SpringApplication.run(
+				TestMultipleStreamEmitterMethods.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain",
@@ -114,8 +190,8 @@ public class StreamEmitterBasicTests {
 
 	@Test
 	public void testSameAppContextWithMultipleStreamEmitters() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(TestSameAppContextWithMultipleStreamEmitters.class,
-				"--server.port=0",
+		ConfigurableApplicationContext context = SpringApplication.run(
+				TestSameAppContextWithMultipleStreamEmitters.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain",
@@ -126,66 +202,23 @@ public class StreamEmitterBasicTests {
 		context.close();
 	}
 
-	private static void receiveAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
-		Source source = context.getBean(Source.class);
-		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		List messages = new ArrayList<>();
-		for (int i = 0; i < 1000; i++) {
-			messages.add((String) messageCollector.forChannel(source.output()).poll(5000, TimeUnit.MILLISECONDS).getPayload());
-		}
-		for (int i = 0; i < 1000; i++) {
-			assertThat(new String(messages.get(i))).isEqualTo("HELLO WORLD!!" + i);
-		}
-	}
+	interface TestMultiOutboundChannels {
 
-	private static void receiveAndValidateMultipleOutputs(ConfigurableApplicationContext context) throws InterruptedException {
-		TestMultiOutboundChannels source = context.getBean(TestMultiOutboundChannels.class);
-		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		List messages = new ArrayList<>();
-		assertMessages(source.output1(), messageCollector, messages);
-		messages.clear();
-		assertMessages(source.output2(), messageCollector, messages);
-		messages.clear();
-		assertMessages(source.output3(), messageCollector, messages);
-		messages.clear();
-	}
+		String OUTPUT1 = "output1";
 
-	private static void receiveAndValidateMultiStreamEmittersInSameContext(ConfigurableApplicationContext context1) throws InterruptedException {
-		TestMultiOutboundChannels source1 = context1.getBean(TestMultiOutboundChannels.class);
-		MessageCollector messageCollector = context1.getBean(MessageCollector.class);
+		String OUTPUT2 = "output2";
 
-		List messages = new ArrayList<>();
-		assertMessagesX(source1.output1(), messageCollector, messages);
-		messages.clear();
-		assertMessagesY(source1.output2(), messageCollector, messages);
-		messages.clear();
-	}
+		String OUTPUT3 = "output3";
 
-	private static void assertMessages(MessageChannel channel, MessageCollector messageCollector, List messages) throws InterruptedException {
-		for (int i = 0; i < 1000; i++) {
-			messages.add((String) messageCollector.forChannel(channel).poll(5000, TimeUnit.MILLISECONDS).getPayload());
-		}
-		for (int i = 0; i < 1000; i++) {
-			assertThat(new String(messages.get(i))).isEqualTo("Hello World!!" + i);
-		}
-	}
+		@Output(TestMultiOutboundChannels.OUTPUT1)
+		MessageChannel output1();
 
-	private static void assertMessagesX(MessageChannel channel, MessageCollector messageCollector, List messages) throws InterruptedException {
-		for (int i = 0; i < 1000; i++) {
-			messages.add((String) messageCollector.forChannel(channel).poll(5000, TimeUnit.MILLISECONDS).getPayload());
-		}
-		for (int i = 0; i < 1000; i++) {
-			assertThat(new String(messages.get(i))).isEqualTo("Hello World!!" + i);
-		}
-	}
+		@Output(TestMultiOutboundChannels.OUTPUT2)
+		MessageChannel output2();
+
+		@Output(TestMultiOutboundChannels.OUTPUT3)
+		MessageChannel output3();
 
-	private static void assertMessagesY(MessageChannel channel, MessageCollector messageCollector, List messages) throws InterruptedException {
-		for (int i = 0; i < 1000; i++) {
-			messages.add((String) messageCollector.forChannel(channel).poll(5000, TimeUnit.MILLISECONDS).getPayload());
-		}
-		for (int i = 0; i < 1000; i++) {
-			assertThat(new String(messages.get(i))).isEqualTo("Hello FooBar!!" + i);
-		}
 	}
 
 	@EnableBinding(Processor.class)
@@ -197,11 +230,11 @@ public class StreamEmitterBasicTests {
 		@Bean
 		public Publisher> emit() {
 			AtomicInteger atomicInteger = new AtomicInteger();
-			return IntegrationFlows.from(() ->
-							new GenericMessage<>("Hello World!!" + atomicInteger.getAndIncrement()),
-					e -> e.poller(p -> p.fixedDelay(1)))
-					.transform(String::toUpperCase)
-					.toReactivePublisher();
+			return IntegrationFlows
+					.from(() -> new GenericMessage<>(
+							"Hello World!!" + atomicInteger.getAndIncrement()),
+							e -> e.poller(p -> p.fixedDelay(1)))
+					.transform(String::toUpperCase).toReactivePublisher();
 		}
 
 	}
@@ -212,10 +245,10 @@ public class StreamEmitterBasicTests {
 
 		@StreamEmitter
 		public void emit(@Output(Source.OUTPUT) FluxSender output) {
-			output.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l)
+			output.send(Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l)
 					.map(String::toUpperCase));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -225,10 +258,10 @@ public class StreamEmitterBasicTests {
 		@StreamEmitter
 		@Output(Source.OUTPUT)
 		public void emit(FluxSender output) {
-			output.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l)
+			output.send(Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l)
 					.map(String::toUpperCase));
 		}
+
 	}
 
 	@EnableBinding(TestMultiOutboundChannels.class)
@@ -239,13 +272,14 @@ public class StreamEmitterBasicTests {
 		public void emit(@Output(TestMultiOutboundChannels.OUTPUT1) FluxSender output1,
 				@Output(TestMultiOutboundChannels.OUTPUT2) FluxSender output2,
 				@Output(TestMultiOutboundChannels.OUTPUT3) FluxSender output3) {
-			output1.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
-			output2.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
-			output3.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
+			output1.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
+			output2.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
+			output3.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
 		}
+
 	}
 
 	@EnableBinding(TestMultiOutboundChannels.class)
@@ -255,22 +289,21 @@ public class StreamEmitterBasicTests {
 		@StreamEmitter
 		@Output(TestMultiOutboundChannels.OUTPUT1)
 		public Flux emit1() {
-			return Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l);
+			return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l);
 		}
 
 		@StreamEmitter
 		@Output(TestMultiOutboundChannels.OUTPUT2)
 		public Flux emit2() {
-			return Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l);
+			return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l);
 		}
 
 		@StreamEmitter
 		public void emit3(@Output(TestMultiOutboundChannels.OUTPUT3) FluxSender outputX) {
-			outputX.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
+			outputX.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
 		}
+
 	}
 
 	@EnableBinding(TestMultiOutboundChannels.class)
@@ -292,9 +325,9 @@ public class StreamEmitterBasicTests {
 			@StreamEmitter
 			@Output(TestMultiOutboundChannels.OUTPUT1)
 			public Flux emit1() {
-				return Flux.interval(Duration.ofMillis(1))
-						.map(l -> "Hello World!!" + l);
+				return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l);
 			}
+
 		}
 
 		static class Bar {
@@ -302,28 +335,11 @@ public class StreamEmitterBasicTests {
 			@StreamEmitter
 			@Output(TestMultiOutboundChannels.OUTPUT2)
 			public Flux emit2() {
-				return Flux.interval(Duration.ofMillis(1))
-						.map(l -> "Hello FooBar!!" + l);
+				return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello FooBar!!" + l);
 			}
+
 		}
-	}
-
-	interface TestMultiOutboundChannels {
-
-		String OUTPUT1 = "output1";
-
-		String OUTPUT2 = "output2";
-
-		String OUTPUT3 = "output3";
-
-		@Output(TestMultiOutboundChannels.OUTPUT1)
-		MessageChannel output1();
-
-		@Output(TestMultiOutboundChannels.OUTPUT2)
-		MessageChannel output2();
-
-		@Output(TestMultiOutboundChannels.OUTPUT3)
-		MessageChannel output3();
 
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterValidationTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterValidationTests.java
index 0d50e6500..c3e65915b 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterValidationTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamEmitterValidationTests.java
@@ -121,13 +121,16 @@ public class StreamEmitterValidationTests {
 	public void testVoidReturnTypeMultipleMethodParametersWithOneMissingOutput() {
 		try {
 			AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
-			context.register(TestVoidReturnTypeMultipleMethodParametersWithOneMissingOutput.class);
+			context.register(
+					TestVoidReturnTypeMultipleMethodParametersWithOneMissingOutput.class);
 			context.refresh();
 			context.close();
-			fail("Expected exception: " + OUTPUT_ANNOTATION_MISSING_ON_METHOD_PARAMETERS_VOID_RETURN_TYPE);
+			fail("Expected exception: "
+					+ OUTPUT_ANNOTATION_MISSING_ON_METHOD_PARAMETERS_VOID_RETURN_TYPE);
 		}
 		catch (Exception e) {
-			assertThat(e.getMessage()).contains(OUTPUT_ANNOTATION_MISSING_ON_METHOD_PARAMETERS_VOID_RETURN_TYPE);
+			assertThat(e.getMessage()).contains(
+					OUTPUT_ANNOTATION_MISSING_ON_METHOD_PARAMETERS_VOID_RETURN_TYPE);
 		}
 	}
 
@@ -180,10 +183,12 @@ public class StreamEmitterValidationTests {
 			context.register(TestReturnTypeNotSupported.class);
 			context.refresh();
 			context.close();
-			fail("Expected exception: " + CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS);
+			fail("Expected exception: "
+					+ CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS);
 		}
 		catch (Exception e) {
-			assertThat(e.getMessage()).contains(CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS);
+			assertThat(e.getMessage()).contains(
+					CANNOT_CONVERT_RETURN_TYPE_TO_ANY_AVAILABLE_RESULT_ADAPTERS);
 		}
 	}
 
@@ -194,9 +199,10 @@ public class StreamEmitterValidationTests {
 		@StreamEmitter
 		@Output(Source.OUTPUT)
 		public void receive(@Output(Source.OUTPUT) FluxSender output) {
-			output.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
+			output.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -205,9 +211,9 @@ public class StreamEmitterValidationTests {
 
 		@StreamEmitter
 		public Flux emit() {
-			return Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l);
+			return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l);
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -216,9 +222,10 @@ public class StreamEmitterValidationTests {
 
 		@StreamEmitter
 		public void emit(FluxSender output) {
-			output.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
+			output.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -227,9 +234,9 @@ public class StreamEmitterValidationTests {
 
 		@StreamEmitter
 		public Flux emit(@Output(Source.OUTPUT) FluxSender output) {
-			return Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l);
+			return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l);
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -239,9 +246,9 @@ public class StreamEmitterValidationTests {
 		@StreamEmitter
 		@Output(Source.OUTPUT)
 		public Flux receive(FluxSender output) {
-			return Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l);
+			return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l);
 		}
+
 	}
 
 	@EnableBinding(StreamEmitterBasicTests.TestMultiOutboundChannels.class)
@@ -249,16 +256,18 @@ public class StreamEmitterValidationTests {
 	public static class TestVoidReturnTypeMultipleMethodParametersWithOneMissingOutput {
 
 		@StreamEmitter
-		public void emit(@Output(StreamEmitterBasicTests.TestMultiOutboundChannels.OUTPUT1) FluxSender output1,
-						@Output(StreamEmitterBasicTests.TestMultiOutboundChannels.OUTPUT2) FluxSender output2,
-						FluxSender output3) {
-			output1.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
-			output2.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
-			output3.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
+		public void emit(
+				@Output(StreamEmitterBasicTests.TestMultiOutboundChannels.OUTPUT1) FluxSender output1,
+				@Output(StreamEmitterBasicTests.TestMultiOutboundChannels.OUTPUT2) FluxSender output2,
+				FluxSender output3) {
+			output1.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
+			output2.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
+			output3.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -268,9 +277,10 @@ public class StreamEmitterValidationTests {
 		@StreamEmitter
 		@Output("")
 		public void receive(FluxSender output) {
-			output.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
+			output.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
 		}
+
 	}
 
 	@EnableBinding(StreamEmitterBasicTests.TestMultiOutboundChannels.class)
@@ -279,9 +289,10 @@ public class StreamEmitterValidationTests {
 
 		@StreamEmitter
 		public void emit(@Output("") FluxSender output1) {
-			output1.send(Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l));
+			output1.send(
+					Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -292,9 +303,9 @@ public class StreamEmitterValidationTests {
 		@Output(Source.OUTPUT)
 		@Input(Processor.INPUT)
 		public Flux emit() {
-			return Flux.interval(Duration.ofMillis(1))
-					.map(l -> "Hello World!!" + l);
+			return Flux.interval(Duration.ofMillis(1)).map(l -> "Hello World!!" + l);
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -306,5 +317,7 @@ public class StreamEmitterValidationTests {
 		public String emit() {
 			return "hello";
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerGenericFluxInputOutputArgsWithMessageTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerGenericFluxInputOutputArgsWithMessageTests.java
index 77ea29594..fa44160e5 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerGenericFluxInputOutputArgsWithMessageTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerGenericFluxInputOutputArgsWithMessageTests.java
@@ -53,8 +53,8 @@ public class StreamListenerGenericFluxInputOutputArgsWithMessageTests {
 		processor.input().send(MessageBuilder.withPayload(sentPayload)
 				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
@@ -88,10 +88,12 @@ public class StreamListenerGenericFluxInputOutputArgsWithMessageTests {
 
 	public static class TestGenericStringFluxInputOutputArgsWithMessageImpl1
 			extends TestGenericFluxInputOutputArgsWithMessage1 {
+
 	}
 
 	public static class TestGenericStringFluxInputOutputArgsWithMessageImpl2
 			extends TestGenericFluxInputOutputArgsWithMessage2 {
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -104,6 +106,7 @@ public class StreamListenerGenericFluxInputOutputArgsWithMessageTests {
 			output.send(input.map(m -> MessageBuilder
 					.withPayload((A) m.toString().toUpperCase()).build()));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -115,5 +118,7 @@ public class StreamListenerGenericFluxInputOutputArgsWithMessageTests {
 			output.send(input.map(m -> MessageBuilder
 					.withPayload((A) m.toString().toUpperCase()).build()));
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerInterruptionTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerInterruptionTests.java
index 57d782e72..93e29d2b2 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerInterruptionTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerInterruptionTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,8 +44,8 @@ public class StreamListenerInterruptionTests {
 
 	@Test
 	public void testSubscribersNotInterrupted() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(TestTimeWindows.class,
-				"--server.port=0");
+		ConfigurableApplicationContext context = SpringApplication
+				.run(TestTimeWindows.class, "--server.port=0");
 		Sink sink = context.getBean(Sink.class);
 		TestTimeWindows testTimeWindows = context.getBean(TestTimeWindows.class);
 		sink.input().send(MessageBuilder.withPayload("hello1").build());
@@ -68,11 +68,12 @@ public class StreamListenerInterruptionTests {
 		@StreamListener
 		public void receive(@Input(Sink.INPUT) Flux input) {
 			input.window(Duration.ofMillis(500), Duration.ofMillis(100))
-					.flatMap(w -> w.reduce("", (x, y) -> x + y))
-					.subscribe(x -> {
-						interruptionState = Thread.currentThread().isInterrupted();
-						latch.countDown();
+					.flatMap(w -> w.reduce("", (x, y) -> x + y)).subscribe(x -> {
+						this.interruptionState = Thread.currentThread().isInterrupted();
+						this.latch.countDown();
 					});
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsTests.java
index 9e9a4456f..b7ff8f03a 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsTests.java
@@ -60,20 +60,23 @@ public class StreamListenerReactiveInputOutputArgsTests {
 	}
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
 
 	@Test
 	public void testInputOutputArgs() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0",
-				"--spring.jmx.enabled=false",
+		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
+				"--server.port=0", "--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		sendMessageAndValidate(context);
@@ -85,8 +88,11 @@ public class StreamListenerReactiveInputOutputArgsTests {
 	public static class ReactorTestInputOutputArgs {
 
 		@StreamListener
-		public void receive(@Input(Processor.INPUT) Flux input, @Output(Processor.OUTPUT) FluxSender output) {
+		public void receive(@Input(Processor.INPUT) Flux input,
+				@Output(Processor.OUTPUT) FluxSender output) {
 			output.send(input.map(m -> m.toUpperCase()));
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithMessageTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithMessageTests.java
index afe86006c..d77d51f0f 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithMessageTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithMessageTests.java
@@ -38,7 +38,6 @@ import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.messaging.Message;
 import org.springframework.messaging.support.MessageBuilder;
 
-
 import static org.assertj.core.api.Assertions.assertThat;
 
 /**
@@ -61,20 +60,23 @@ public class StreamListenerReactiveInputOutputArgsWithMessageTests {
 	}
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
 
 	@Test
 	public void testInputOutputArgs() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0",
-				"--spring.jmx.enabled=false",
+		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
+				"--server.port=0", "--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		sendMessageAndValidate(context);
@@ -91,5 +93,7 @@ public class StreamListenerReactiveInputOutputArgsWithMessageTests {
 			output.send(input.map(m -> MessageBuilder
 					.withPayload(m.getPayload().toString().toUpperCase()).build()));
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests.java
index a51516adc..d80c421a5 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests.java
@@ -38,7 +38,6 @@ import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.messaging.Message;
 import org.springframework.messaging.support.MessageBuilder;
 
-
 import static org.assertj.core.api.Assertions.assertThat;
 
 /**
@@ -51,35 +50,42 @@ public class StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests {
 
 	private Class configClass;
 
-	public StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests(Class configClass) {
+	public StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests(
+			Class configClass) {
 		this.configClass = configClass;
 	}
 
 	@Parameterized.Parameters
 	public static Collection InputConfigs() {
-		return Collections.singletonList(TestInputOutputArgsWithFluxSenderAndFailure.class);
+		return Collections
+				.singletonList(TestInputOutputArgsWithFluxSenderAndFailure.class);
 	}
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
 
-	private static void sendFailingMessage(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendFailingMessage(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
-		processor.input().send(MessageBuilder.withPayload("fail").setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload("fail")
+				.setHeader("contentType", "text/plain").build());
 	}
 
 	@Test
 	public void testInputOutputArgsWithFluxSenderAndFailure() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0",
-				"--spring.jmx.enabled=false",
+		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
+				"--server.port=0", "--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		sendMessageAndValidate(context);
@@ -91,20 +97,20 @@ public class StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests {
 	@EnableBinding(Processor.class)
 	@EnableAutoConfiguration
 	public static class TestInputOutputArgsWithFluxSenderAndFailure {
+
 		@StreamListener
 		public void receive(@Input(Processor.INPUT) Flux> input,
 				@Output(Processor.OUTPUT) FluxSender output) {
-			output.send(input
-					.map(m -> m.getPayload().toString())
-					.map(m -> {
-						if (!m.equals("fail")) {
-							return m.toUpperCase();
-						}
-						else {
-							throw new RuntimeException();
-						}
-					})
-					.map(o -> MessageBuilder.withPayload(o).build()));
+			output.send(input.map(m -> m.getPayload().toString()).map(m -> {
+				if (!m.equals("fail")) {
+					return m.toUpperCase();
+				}
+				else {
+					throw new RuntimeException();
+				}
+			}).map(o -> MessageBuilder.withPayload(o).build()));
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderTests.java
index 6d5fe6fdf..09d24e315 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveInputOutputArgsWithSenderTests.java
@@ -60,12 +60,15 @@ public class StreamListenerReactiveInputOutputArgsWithSenderTests {
 	}
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
@@ -73,8 +76,7 @@ public class StreamListenerReactiveInputOutputArgsWithSenderTests {
 	@Test
 	public void testInputOutputArgsWithFluxSender() throws Exception {
 		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
-				"--server.port=0",
-				"--spring.jmx.enabled=false",
+				"--server.port=0", "--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		// send multiple message
@@ -87,12 +89,14 @@ public class StreamListenerReactiveInputOutputArgsWithSenderTests {
 	@EnableBinding(Processor.class)
 	@EnableAutoConfiguration
 	public static class ReactorTestInputOutputArgsWithFluxSender {
+
 		@StreamListener
 		public void receive(@Input(Processor.INPUT) Flux> input,
 				@Output(Processor.OUTPUT) FluxSender output) {
-			output.send(input
-					.map(m -> m.getPayload().toString().toUpperCase())
+			output.send(input.map(m -> m.getPayload().toString().toUpperCase())
 					.map(o -> MessageBuilder.withPayload(o).build()));
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodTests.java
index 956517b95..5cc8a75dd 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,7 +44,8 @@ public class StreamListenerReactiveMethodTests {
 			fail("IllegalArgumentException should have been thrown");
 		}
 		catch (Exception e) {
-			assertThat(e.getMessage()).contains(INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM);
+			assertThat(e.getMessage())
+					.contains(INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM);
 		}
 	}
 
@@ -67,9 +68,11 @@ public class StreamListenerReactiveMethodTests {
 	public static class ReactorTestInputOutputArgs {
 
 		@StreamListener(Processor.INPUT)
-		public void receive(Flux input, @Output(Processor.OUTPUT) FluxSender output) {
+		public void receive(Flux input,
+				@Output(Processor.OUTPUT) FluxSender output) {
 			output.send(input.map(m -> m.toUpperCase()));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -80,5 +83,7 @@ public class StreamListenerReactiveMethodTests {
 		public Flux receive(@Input(Processor.INPUT) Flux input) {
 			return input.map(m -> m.toUpperCase());
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodWithReturnTypeTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodWithReturnTypeTests.java
index 79e744b3c..ca81a0ba5 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodWithReturnTypeTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveMethodWithReturnTypeTests.java
@@ -57,25 +57,28 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
 
 	@Parameterized.Parameters
 	public static Collection InputConfigs() {
-		return Arrays.asList(ReactorTestReturn1.class, ReactorTestReturn2.class, ReactorTestReturn3.class,
-				ReactorTestReturn4.class);
+		return Arrays.asList(ReactorTestReturn1.class, ReactorTestReturn2.class,
+				ReactorTestReturn3.class, ReactorTestReturn4.class);
 	}
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
 
 	@Test
 	public void testReturn() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0",
-				"--spring.jmx.enabled=false",
+		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
+				"--server.port=0", "--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		sendMessageAndValidate(context);
@@ -89,9 +92,11 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
 	public static class ReactorTestReturn1 {
 
 		@StreamListener
-		public @Output(Processor.OUTPUT) Flux receive(@Input(Processor.INPUT) Flux input) {
+		public @Output(Processor.OUTPUT) Flux receive(
+				@Input(Processor.INPUT) Flux input) {
 			return input.map(m -> m.toUpperCase());
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -103,6 +108,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
 		public Flux receive(Flux input) {
 			return input.map(m -> m.toUpperCase());
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -114,6 +120,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
 		public Flux receive(Flux input) {
 			return input.map(m -> m.toUpperCase());
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -125,5 +132,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
 		public Flux receive(@Input(Processor.INPUT) Flux input) {
 			return input.map(m -> m.toUpperCase());
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithFailureTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithFailureTests.java
index 073bd525c..812a666d5 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithFailureTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithFailureTests.java
@@ -57,30 +57,35 @@ public class StreamListenerReactiveReturnWithFailureTests {
 
 	@Parameterized.Parameters
 	public static Collection InputConfigs() {
-		return Arrays.asList(ReactorTestReturnWithFailure1.class, ReactorTestReturnWithFailure2.class,
-				ReactorTestReturnWithFailure3.class, ReactorTestReturnWithFailure4.class);
+		return Arrays.asList(ReactorTestReturnWithFailure1.class,
+				ReactorTestReturnWithFailure2.class, ReactorTestReturnWithFailure3.class,
+				ReactorTestReturnWithFailure4.class);
 	}
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
 
 	private static void sendFailingMessage(ConfigurableApplicationContext context) {
 		Processor processor = context.getBean(Processor.class);
-		processor.input().send(MessageBuilder.withPayload("fail").setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload("fail")
+				.setHeader("contentType", "text/plain").build());
 	}
 
 	@Test
 	public void testReturnWithFailure() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0",
-				"--spring.jmx.enabled=false",
+		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
+				"--server.port=0", "--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		sendMessageAndValidate(context);
@@ -96,16 +101,18 @@ public class StreamListenerReactiveReturnWithFailureTests {
 	public static class ReactorTestReturnWithFailure1 {
 
 		@StreamListener
-		public @Output(Processor.OUTPUT)
-		Flux receive(@Input(Processor.INPUT) Flux input) {
+		public @Output(Processor.OUTPUT) Flux receive(
+				@Input(Processor.INPUT) Flux input) {
 			return input.map(m -> {
 				if (!m.equals("fail")) {
 					return m.toUpperCase();
-				} else {
+				}
+				else {
 					throw new RuntimeException();
 				}
 			});
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -113,16 +120,17 @@ public class StreamListenerReactiveReturnWithFailureTests {
 	public static class ReactorTestReturnWithFailure2 {
 
 		@StreamListener(Processor.INPUT)
-		public @Output(Processor.OUTPUT)
-		Flux receive(Flux input) {
+		public @Output(Processor.OUTPUT) Flux receive(Flux input) {
 			return input.map(m -> {
 				if (!m.equals("fail")) {
 					return m.toUpperCase();
-				} else {
+				}
+				else {
 					throw new RuntimeException();
 				}
 			});
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -130,16 +138,17 @@ public class StreamListenerReactiveReturnWithFailureTests {
 	public static class ReactorTestReturnWithFailure3 {
 
 		@StreamListener(Processor.INPUT)
-		public @SendTo(Processor.OUTPUT)
-		Flux receive(Flux input) {
+		public @SendTo(Processor.OUTPUT) Flux receive(Flux input) {
 			return input.map(m -> {
 				if (!m.equals("fail")) {
 					return m.toUpperCase();
-				} else {
+				}
+				else {
 					throw new RuntimeException();
 				}
 			});
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -147,15 +156,18 @@ public class StreamListenerReactiveReturnWithFailureTests {
 	public static class ReactorTestReturnWithFailure4 {
 
 		@StreamListener
-		public @SendTo(Processor.OUTPUT)
-		Flux receive(@Input(Processor.INPUT) Flux input) {
+		public @SendTo(Processor.OUTPUT) Flux receive(
+				@Input(Processor.INPUT) Flux input) {
 			return input.map(m -> {
 				if (!m.equals("fail")) {
 					return m.toUpperCase();
-				} else {
+				}
+				else {
 					throw new RuntimeException();
 				}
 			});
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithMessageTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithMessageTests.java
index cf5bb5a20..482f48426 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithMessageTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithMessageTests.java
@@ -57,25 +57,29 @@ public class StreamListenerReactiveReturnWithMessageTests {
 
 	@Parameterized.Parameters
 	public static Collection InputConfigs() {
-		return Arrays.asList(ReactorTestReturnWithMessage1.class, ReactorTestReturnWithMessage2.class,
-				ReactorTestReturnWithMessage3.class, ReactorTestReturnWithMessage4.class);
+		return Arrays.asList(ReactorTestReturnWithMessage1.class,
+				ReactorTestReturnWithMessage2.class, ReactorTestReturnWithMessage3.class,
+				ReactorTestReturnWithMessage4.class);
 	}
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
 
 	@Test
 	public void testReturnWithMessage() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0",
-				"--spring.jmx.enabled=false",
+		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
+				"--server.port=0", "--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.input.contentType=text/plain",
 				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		sendMessageAndValidate(context);
@@ -87,9 +91,11 @@ public class StreamListenerReactiveReturnWithMessageTests {
 	public static class ReactorTestReturnWithMessage1 {
 
 		@StreamListener
-		public @Output(Processor.OUTPUT) Flux receive(@Input(Processor.INPUT) Flux> input) {
+		public @Output(Processor.OUTPUT) Flux receive(
+				@Input(Processor.INPUT) Flux> input) {
 			return input.map(m -> m.getPayload().toUpperCase());
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -97,9 +103,11 @@ public class StreamListenerReactiveReturnWithMessageTests {
 	public static class ReactorTestReturnWithMessage2 {
 
 		@StreamListener(Processor.INPUT)
-		public @Output(Processor.OUTPUT) Flux receive(Flux> input) {
+		public @Output(Processor.OUTPUT) Flux receive(
+				Flux> input) {
 			return input.map(m -> m.getPayload().toUpperCase());
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -107,9 +115,11 @@ public class StreamListenerReactiveReturnWithMessageTests {
 	public static class ReactorTestReturnWithMessage3 {
 
 		@StreamListener(Processor.INPUT)
-		public @SendTo(Processor.OUTPUT) Flux receive(Flux> input) {
+		public @SendTo(Processor.OUTPUT) Flux receive(
+				Flux> input) {
 			return input.map(m -> m.getPayload().toUpperCase());
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -117,8 +127,11 @@ public class StreamListenerReactiveReturnWithMessageTests {
 	public static class ReactorTestReturnWithMessage4 {
 
 		@StreamListener
-		public @SendTo(Processor.OUTPUT) Flux receive(@Input(Processor.INPUT) Flux> input) {
+		public @SendTo(Processor.OUTPUT) Flux receive(
+				@Input(Processor.INPUT) Flux> input) {
 			return input.map(m -> m.getPayload().toUpperCase());
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithPojoTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithPojoTests.java
index 94d010863..9cd9e9c6b 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithPojoTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerReactiveReturnWithPojoTests.java
@@ -61,22 +61,24 @@ public class StreamListenerReactiveReturnWithPojoTests {
 
 	@Parameterized.Parameters
 	public static Collection InputConfigs() {
-		return Arrays.asList(ReactorTestReturnWithPojo1.class, ReactorTestReturnWithPojo2.class,
-				ReactorTestReturnWithPojo3.class, ReactorTestReturnWithPojo4.class);
+		return Arrays.asList(ReactorTestReturnWithPojo1.class,
+				ReactorTestReturnWithPojo2.class, ReactorTestReturnWithPojo3.class,
+				ReactorTestReturnWithPojo4.class);
 	}
 
 	@Test
 	@SuppressWarnings("unchecked")
 	public void testReturnWithPojo() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0",
-				"--spring.jmx.enabled=false");
+		ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
+				"--server.port=0", "--spring.jmx.enabled=false");
 		Processor processor = context.getBean(Processor.class);
 		processor.input().send(MessageBuilder.withPayload("{\"message\":\"helloPojo\"}")
 				.setHeader("contentType", "application/json").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
-		BarPojo barPojo = mapper.readValue(result.getPayload(),BarPojo.class);
+		BarPojo barPojo = this.mapper.readValue(result.getPayload(), BarPojo.class);
 		assertThat(barPojo.getBarMessage()).isEqualTo("helloPojo");
 		context.close();
 	}
@@ -86,9 +88,11 @@ public class StreamListenerReactiveReturnWithPojoTests {
 	public static class ReactorTestReturnWithPojo1 {
 
 		@StreamListener
-		public @Output(Processor.OUTPUT) Flux receive(@Input(Processor.INPUT) Flux input) {
+		public @Output(Processor.OUTPUT) Flux receive(
+				@Input(Processor.INPUT) Flux input) {
 			return input.map(m -> new BarPojo(m.getMessage()));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -99,6 +103,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
 		public @Output(Processor.OUTPUT) Flux receive(Flux input) {
 			return input.map(m -> new BarPojo(m.getMessage()));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -109,6 +114,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
 		public @SendTo(Processor.OUTPUT) Flux receive(Flux input) {
 			return input.map(m -> new BarPojo(m.getMessage()));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -116,9 +122,11 @@ public class StreamListenerReactiveReturnWithPojoTests {
 	public static class ReactorTestReturnWithPojo4 {
 
 		@StreamListener
-		public @SendTo(Processor.OUTPUT) Flux receive(@Input(Processor.INPUT) Flux input) {
+		public @SendTo(Processor.OUTPUT) Flux receive(
+				@Input(Processor.INPUT) Flux input) {
 			return input.map(m -> new BarPojo(m.getMessage()));
 		}
+
 	}
 
 	public static class FooPojo {
@@ -126,12 +134,13 @@ public class StreamListenerReactiveReturnWithPojoTests {
 		private String message;
 
 		public String getMessage() {
-			return message;
+			return this.message;
 		}
 
 		public void setMessage(String message) {
 			this.message = message;
 		}
+
 	}
 
 	public static class BarPojo {
@@ -144,11 +153,13 @@ public class StreamListenerReactiveReturnWithPojoTests {
 		}
 
 		public String getBarMessage() {
-			return barMessage;
+			return this.barMessage;
 		}
 
 		public void setBarMessage(String barMessage) {
 			this.barMessage = barMessage;
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerWildCardFluxInputOutputArgsWithMessageTests.java b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerWildCardFluxInputOutputArgsWithMessageTests.java
index f0a813994..a578922f5 100644
--- a/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerWildCardFluxInputOutputArgsWithMessageTests.java
+++ b/spring-cloud-stream-reactive/src/test/java/org/springframework/cloud/stream/reactive/StreamListenerWildCardFluxInputOutputArgsWithMessageTests.java
@@ -47,20 +47,24 @@ import static org.springframework.cloud.stream.binding.StreamListenerErrorMessag
 public class StreamListenerWildCardFluxInputOutputArgsWithMessageTests {
 
 	@SuppressWarnings("unchecked")
-	private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
+	private static void sendMessageAndValidate(ConfigurableApplicationContext context)
+			throws InterruptedException {
 		Processor processor = context.getBean(Processor.class);
 		String sentPayload = "hello " + UUID.randomUUID().toString();
-		processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
+		processor.input().send(MessageBuilder.withPayload(sentPayload)
+				.setHeader("contentType", "text/plain").build());
 		MessageCollector messageCollector = context.getBean(MessageCollector.class);
-		Message result = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
+		Message result = (Message) messageCollector
+				.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
 		assertThat(result).isNotNull();
 		assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
 	}
 
 	@Test
 	public void testWildCardFluxInputOutputArgsWithMessage() throws Exception {
-		ConfigurableApplicationContext context = SpringApplication
-				.run(TestWildCardFluxInputOutputArgsWithMessage1.class, "--server.port=0","--spring.cloud.stream.bindings.output.contentType=text/plain");
+		ConfigurableApplicationContext context = SpringApplication.run(
+				TestWildCardFluxInputOutputArgsWithMessage1.class, "--server.port=0",
+				"--spring.cloud.stream.bindings.output.contentType=text/plain");
 		sendMessageAndValidate(context);
 		context.close();
 	}
@@ -68,18 +72,21 @@ public class StreamListenerWildCardFluxInputOutputArgsWithMessageTests {
 	@Test
 	public void testInputAsStreamListenerAndOutputAsParameterUsage() {
 		try {
-			SpringApplication.run(TestWildCardFluxInputOutputArgsWithMessage2.class, "--server.port=0");
+			SpringApplication.run(TestWildCardFluxInputOutputArgsWithMessage2.class,
+					"--server.port=0");
 			fail("Expected exception: " + INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM);
 		}
 		catch (Exception e) {
-			assertThat(e.getMessage()).contains(INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM);
+			assertThat(e.getMessage())
+					.contains(INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM);
 		}
 	}
 
 	@Test
 	public void testIncorrectUsage1() throws Exception {
 		try {
-			SpringApplication.run(TestWildCardFluxInputOutputArgsWithMessage3.class, "--server.port=0");
+			SpringApplication.run(TestWildCardFluxInputOutputArgsWithMessage3.class,
+					"--server.port=0");
 			fail("Expected exception: " + INVALID_DECLARATIVE_METHOD_PARAMETERS);
 		}
 		catch (Exception e) {
@@ -94,8 +101,10 @@ public class StreamListenerWildCardFluxInputOutputArgsWithMessageTests {
 		@StreamListener
 		public void receive(@Input(Processor.INPUT) Flux input,
 				@Output(Processor.OUTPUT) FluxSender output) {
-			output.send(input.map(m -> MessageBuilder.withPayload(m.toString().toUpperCase()).build()));
+			output.send(input.map(
+					m -> MessageBuilder.withPayload(m.toString().toUpperCase()).build()));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -104,8 +113,10 @@ public class StreamListenerWildCardFluxInputOutputArgsWithMessageTests {
 
 		@StreamListener(Processor.INPUT)
 		public void receive(Flux input, @Output(Processor.OUTPUT) FluxSender output) {
-			output.send(input.map(m -> MessageBuilder.withPayload(m.toString().toUpperCase()).build()));
+			output.send(input.map(
+					m -> MessageBuilder.withPayload(m.toString().toUpperCase()).build()));
 		}
+
 	}
 
 	@EnableBinding(Processor.class)
@@ -115,7 +126,10 @@ public class StreamListenerWildCardFluxInputOutputArgsWithMessageTests {
 		@StreamListener(Processor.INPUT)
 		@SendTo(Processor.OUTPUT)
 		public void receive(Flux input, FluxSender output) {
-			output.send(input.map(m -> MessageBuilder.withPayload(m.toString().toUpperCase()).build()));
+			output.send(input.map(
+					m -> MessageBuilder.withPayload(m.toString().toUpperCase()).build()));
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/pom.xml b/spring-cloud-stream-schema-server/pom.xml
index 2ea6df343..919dde135 100644
--- a/spring-cloud-stream-schema-server/pom.xml
+++ b/spring-cloud-stream-schema-server/pom.xml
@@ -1,5 +1,6 @@
 
-
 	4.0.0
 	spring-cloud-stream-schema-server
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/EnableSchemaRegistryServer.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/EnableSchemaRegistryServer.java
index f46fa5e92..a184716e1 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/EnableSchemaRegistryServer.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/EnableSchemaRegistryServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -35,4 +35,5 @@ import org.springframework.context.annotation.Import;
 @Documented
 @Import(SchemaServerConfiguration.class)
 public @interface EnableSchemaRegistryServer {
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerApplication.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerApplication.java
index 76b084281..c6b520fea 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerApplication.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerApplication.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,10 +22,14 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 /**
  * @author Vinicius Carvalho
  */
+// @checkstyle:off
 @SpringBootApplication
 @EnableSchemaRegistryServer
 public class SchemaRegistryServerApplication {
+
 	public static void main(String[] args) {
 		SpringApplication.run(SchemaRegistryServerApplication.class, args);
 	}
+
 }
+// @checkstyle:on
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerConfiguration.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerConfiguration.java
index 8532583bd..6a2bcef3a 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerConfiguration.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerConfiguration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -51,10 +51,12 @@ public class SchemaServerConfiguration {
 		return new BeanFactoryPostProcessor() {
 
 			@Override
-			public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+			public void postProcessBeanFactory(
+					ConfigurableListableBeanFactory beanFactory) throws BeansException {
 				if (beanFactory instanceof BeanDefinitionRegistry) {
 					EntityScanPackages.register((BeanDefinitionRegistry) beanFactory,
-							Collections.singletonList(Schema.class.getPackage().getName()));
+							Collections
+									.singletonList(Schema.class.getPackage().getName()));
 				}
 			}
 		};
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerProperties.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerProperties.java
index 8b60b885b..d8cf35e7c 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerProperties.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/config/SchemaServerProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -46,10 +46,11 @@ public class SchemaServerProperties {
 	}
 
 	public boolean isAllowSchemaDeletion() {
-		return allowSchemaDeletion;
+		return this.allowSchemaDeletion;
 	}
 
 	public void setAllowSchemaDeletion(boolean allowSchemaDeletion) {
 		this.allowSchemaDeletion = allowSchemaDeletion;
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/controllers/ServerController.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/controllers/ServerController.java
index 114891fc6..f1df72f97 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/controllers/ServerController.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/controllers/ServerController.java
@@ -72,9 +72,9 @@ public class ServerController {
 		SchemaValidator validator = this.validators.get(schema.getFormat());
 
 		if (validator == null) {
-			throw new UnsupportedFormatException(String.format(
-					"Invalid format, supported types are: %s",
-					StringUtils.collectionToCommaDelimitedString(this.validators.keySet())));
+			throw new UnsupportedFormatException(
+					String.format("Invalid format, supported types are: %s", StringUtils
+							.collectionToCommaDelimitedString(this.validators.keySet())));
 		}
 
 		if (!validator.isValid(schema.getDefinition())) {
@@ -82,8 +82,9 @@ public class ServerController {
 		}
 
 		Schema result;
-		List registeredEntities = this.repository.findBySubjectAndFormatOrderByVersion(
-				schema.getSubject(), schema.getFormat());
+		List registeredEntities = this.repository
+				.findBySubjectAndFormatOrderByVersion(schema.getSubject(),
+						schema.getFormat());
 		if (registeredEntities == null || registeredEntities.size() == 0) {
 			schema.setVersion(1);
 			result = this.repository.save(schema);
@@ -116,8 +117,8 @@ public class ServerController {
 	public ResponseEntity findOne(@PathVariable("subject") String subject,
 			@PathVariable("format") String format,
 			@PathVariable("version") Integer version) {
-		Schema schema = this.repository.findOneBySubjectAndFormatAndVersion(subject, format,
-				version);
+		Schema schema = this.repository.findOneBySubjectAndFormatAndVersion(subject,
+				format, version);
 		if (schema == null) {
 			throw new SchemaNotFoundException("Could not find Schema");
 		}
@@ -134,12 +135,14 @@ public class ServerController {
 	}
 
 	@RequestMapping(method = RequestMethod.GET, produces = "application/json", path = "/{subject}/{format}")
-	public ResponseEntity> findBySubjectAndVersion(@PathVariable("subject") String subject,
+	public ResponseEntity> findBySubjectAndVersion(
+			@PathVariable("subject") String subject,
 			@PathVariable("format") String format) {
-		List schemas = repository.findBySubjectAndFormatOrderByVersion(subject, format);
+		List schemas = this.repository
+				.findBySubjectAndFormatOrderByVersion(subject, format);
 		if (schemas == null || schemas.size() == 0) {
-			throw new SchemaNotFoundException(
-					String.format("No schemas found for subject %s and format %s", subject, format));
+			throw new SchemaNotFoundException(String.format(
+					"No schemas found for subject %s and format %s", subject, format));
 		}
 		return new ResponseEntity>(schemas, HttpStatus.OK);
 	}
@@ -149,8 +152,8 @@ public class ServerController {
 			@PathVariable("format") String format,
 			@PathVariable("version") Integer version) {
 		if (this.schemaServerProperties.isAllowSchemaDeletion()) {
-			Schema schema = this.repository.findOneBySubjectAndFormatAndVersion(subject, format,
-					version);
+			Schema schema = this.repository.findOneBySubjectAndFormatAndVersion(subject,
+					format, version);
 			deleteSchema(schema);
 		}
 		else {
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Compatibility.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Compatibility.java
index 29fec1fd4..211e1d50f 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Compatibility.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Compatibility.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,8 +20,25 @@ package org.springframework.cloud.stream.schema.server.model;
  * @author Vinicius Carvalho
  */
 public enum Compatibility {
+
+	/**
+	 * Backward compatibiltity.
+	 */
 	BACKWARD,
+
+	/**
+	 * Forward compatibility.
+	 */
 	FORWARD,
+
+	/**
+	 * Full compatibility.
+	 */
 	FULL,
+
+	/**
+	 * Lack of compatibility.
+	 */
 	INCOMPATIBLE;
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Schema.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Schema.java
index c8c74e262..ffcdd4cf9 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Schema.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/model/Schema.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -51,7 +51,7 @@ public class Schema {
 	private String definition;
 
 	public Integer getId() {
-		return id;
+		return this.id;
 	}
 
 	public void setId(Integer id) {
@@ -59,7 +59,7 @@ public class Schema {
 	}
 
 	public Integer getVersion() {
-		return version;
+		return this.version;
 	}
 
 	public void setVersion(Integer version) {
@@ -67,7 +67,7 @@ public class Schema {
 	}
 
 	public String getSubject() {
-		return subject;
+		return this.subject;
 	}
 
 	public void setSubject(String subject) {
@@ -75,7 +75,7 @@ public class Schema {
 	}
 
 	public String getFormat() {
-		return format;
+		return this.format;
 	}
 
 	public void setFormat(String format) {
@@ -83,10 +83,11 @@ public class Schema {
 	}
 
 	public String getDefinition() {
-		return definition;
+		return this.definition;
 	}
 
 	public void setDefinition(String definition) {
 		this.definition = definition;
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/repository/SchemaRepository.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/repository/SchemaRepository.java
index 88cff4060..cd0393d24 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/repository/SchemaRepository.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/repository/SchemaRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,10 +28,10 @@ import org.springframework.transaction.annotation.Transactional;
 public interface SchemaRepository extends PagingAndSortingRepository {
 
 	@Transactional
-	List findBySubjectAndFormatOrderByVersion(String subject,
-			String format);
+	List findBySubjectAndFormatOrderByVersion(String subject, String format);
 
 	@Transactional
 	Schema findOneBySubjectAndFormatAndVersion(String subject, String format,
 			Integer version);
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/AvroSchemaValidator.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/AvroSchemaValidator.java
index 9da3ed3a9..4fa1fdec2 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/AvroSchemaValidator.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/AvroSchemaValidator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -65,4 +65,5 @@ public class AvroSchemaValidator implements SchemaValidator {
 	public String getFormat() {
 		return "avro";
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/InvalidSchemaException.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/InvalidSchemaException.java
index 098f9f8d0..46539e522 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/InvalidSchemaException.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/InvalidSchemaException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@ package org.springframework.cloud.stream.schema.server.support;
  * @author Vinicius Carvalho
  */
 public class InvalidSchemaException extends RuntimeException {
+
 	public InvalidSchemaException(String message) {
 		super(message);
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaDeletionNotAllowedException.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaDeletionNotAllowedException.java
index 73d17f9d5..d61f2e095 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaDeletionNotAllowedException.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaDeletionNotAllowedException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ package org.springframework.cloud.stream.schema.server.support;
  * @author Ilayaperumal Gopinathan
  */
 public class SchemaDeletionNotAllowedException extends RuntimeException {
+
 	public SchemaDeletionNotAllowedException(String message) {
 		super(message);
 	}
@@ -27,4 +28,5 @@ public class SchemaDeletionNotAllowedException extends RuntimeException {
 	public SchemaDeletionNotAllowedException() {
 		super("Schema Deletion Not Allowed");
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaNotFoundException.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaNotFoundException.java
index b62620915..76edd5bd5 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaNotFoundException.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaNotFoundException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@ package org.springframework.cloud.stream.schema.server.support;
  * @author Vinicius Carvalho
  */
 public class SchemaNotFoundException extends RuntimeException {
+
 	public SchemaNotFoundException(String message) {
 		super(message);
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaValidator.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaValidator.java
index 70970bc56..e98b45718 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaValidator.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/SchemaValidator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import org.springframework.cloud.stream.schema.server.model.Schema;
 public interface SchemaValidator {
 
 	/**
-	 * Verifies if a definition is a valid schema
+	 * Verifies if a definition is a valid schema.
 	 * @param definition - The textual representation of the schema file
 	 * @return true if valid, false otherwise
 	 */
@@ -38,7 +38,7 @@ public interface SchemaValidator {
 
 	/**
 	 * Checks for compatibility between two schemas @see Compatibility class for types
-	 * This method may not be supported for certain formats
+	 * This method may not be supported for certain formats.
 	 * @param source - The textual representation of the schema to tested
 	 * @param other - The textual representation of the other schema to tested
 	 * @return {@link Compatibility}
diff --git a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/UnsupportedFormatException.java b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/UnsupportedFormatException.java
index af0c12887..448598e0f 100644
--- a/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/UnsupportedFormatException.java
+++ b/spring-cloud-stream-schema-server/src/main/java/org/springframework/cloud/stream/schema/server/support/UnsupportedFormatException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,4 +24,5 @@ public class UnsupportedFormatException extends RuntimeException {
 	public UnsupportedFormatException(String message) {
 		super(message);
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/main/resources/META-INF/spring.factories b/spring-cloud-stream-schema-server/src/main/resources/META-INF/spring.factories
index e69de29bb..8b1378917 100644
--- a/spring-cloud-stream-schema-server/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-stream-schema-server/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+
diff --git a/spring-cloud-stream-schema-server/src/main/resources/application.yml b/spring-cloud-stream-schema-server/src/main/resources/application.yml
index 7961552db..a5aad28b1 100644
--- a/spring-cloud-stream-schema-server/src/main/resources/application.yml
+++ b/spring-cloud-stream-schema-server/src/main/resources/application.yml
@@ -2,4 +2,5 @@ spring:
   application:
     name: SchemaRegistryServer
 server:
-  port: 8990
\ No newline at end of file
+  port: 8990
+
diff --git a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerAvroTests.java b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerAvroTests.java
index b69f8573c..736f331ea 100644
--- a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerAvroTests.java
+++ b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/SchemaRegistryServerAvroTests.java
@@ -18,7 +18,6 @@ package org.springframework.cloud.stream.schema.server;
 
 import java.util.List;
 
-import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -44,8 +43,9 @@ import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER
  * @author Ilayaperumal Gopinathan
  */
 @RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
-				properties = "spring.main.allow-bean-definition-overriding=true")
+// @checkstyle:off
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = "spring.main.allow-bean-definition-overriding=true")
+// @checkstyle:on
 @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
 public class SchemaRegistryServerAvroTests {
 
@@ -76,9 +76,9 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema = new Schema();
 		schema.setFormat("spring");
 		schema.setSubject("boot");
-		ResponseEntity response = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+		ResponseEntity response = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
 	}
 
 	@Test
@@ -87,9 +87,9 @@ public class SchemaRegistryServerAvroTests {
 		schema.setFormat("avro");
 		schema.setSubject("boot");
 		schema.setDefinition("{}");
-		ResponseEntity response = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+		ResponseEntity response = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
 	}
 
 	@Test
@@ -97,17 +97,17 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema = new Schema();
 		schema.setFormat("avro");
 		schema.setSubject("org.springframework.cloud.stream.schema.User");
-		schema.setDefinition(USER_SCHEMA_V1);
-		ResponseEntity response = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
-		Assert.assertEquals(new Integer(1), response.getBody().getVersion());
+		schema.setDefinition(this.USER_SCHEMA_V1);
+		ResponseEntity response = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
+		assertThat(response.getBody().getVersion()).isEqualTo(new Integer(1));
 		List location = response.getHeaders().get(HttpHeaders.LOCATION);
-		Assert.assertNotNull(location);
-		ResponseEntity persistedSchema = client.getForEntity(location.get(0),
+		assertThat(location).isNotNull();
+		ResponseEntity persistedSchema = this.client.getForEntity(location.get(0),
 				Schema.class);
-		Assert.assertEquals(response.getBody().getId(),
-				persistedSchema.getBody().getId());
+		assertThat(persistedSchema.getBody().getId())
+				.isEqualTo(response.getBody().getId());
 
 	}
 
@@ -116,26 +116,26 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema = new Schema();
 		schema.setFormat("avro");
 		schema.setSubject("org.springframework.cloud.stream.schema.User");
-		schema.setDefinition(USER_SCHEMA_V1);
+		schema.setDefinition(this.USER_SCHEMA_V1);
 
 		Schema schema2 = new Schema();
 		schema2.setFormat("avro");
 		schema2.setSubject("org.springframework.cloud.stream.schema.User");
-		schema2.setDefinition(USER_SCHEMA_V2);
+		schema2.setDefinition(this.USER_SCHEMA_V2);
 
-		ResponseEntity response = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
-		Assert.assertEquals(new Integer(1), response.getBody().getVersion());
+		ResponseEntity response = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
+		assertThat(response.getBody().getVersion()).isEqualTo(new Integer(1));
 		List location = response.getHeaders().get(HttpHeaders.LOCATION);
-		Assert.assertNotNull(location);
+		assertThat(location).isNotNull();
 
-		ResponseEntity response2 = client.postForEntity("http://localhost:8990/",
-				schema2, Schema.class);
-		Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
-		Assert.assertEquals(new Integer(2), response2.getBody().getVersion());
+		ResponseEntity response2 = this.client
+				.postForEntity("http://localhost:8990/", schema2, Schema.class);
+		assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
+		assertThat(response2.getBody().getVersion()).isEqualTo(new Integer(2));
 		List location2 = response2.getHeaders().get(HttpHeaders.LOCATION);
-		Assert.assertNotNull(location2);
+		assertThat(location2).isNotNull();
 
 	}
 
@@ -144,24 +144,24 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema = new Schema();
 		schema.setFormat("avro");
 		schema.setSubject("org.springframework.cloud.stream.schema.User");
-		schema.setDefinition(USER_SCHEMA_V1);
-		ResponseEntity response = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
-		Assert.assertEquals(new Integer(1), response.getBody().getVersion());
+		schema.setDefinition(this.USER_SCHEMA_V1);
+		ResponseEntity response = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
+		assertThat(response.getBody().getVersion()).isEqualTo(new Integer(1));
 		List location = response.getHeaders().get(HttpHeaders.LOCATION);
-		Assert.assertNotNull(location);
-		ResponseEntity response2 = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertEquals(response.getBody().getId(), response2.getBody().getId());
+		assertThat(location).isNotNull();
+		ResponseEntity response2 = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response2.getBody().getId()).isEqualTo(response.getBody().getId());
 
 	}
 
 	@Test
 	public void testSchemaNotfound() throws Exception {
-		ResponseEntity response = client
+		ResponseEntity response = this.client
 				.getForEntity("http://localhost:8990/foo/avro/v42", Schema.class);
-		Assert.assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
+		assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
 	}
 
 	@Test
@@ -169,15 +169,15 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema = new Schema();
 		schema.setFormat("avro");
 		schema.setSubject("test");
-		schema.setDefinition(USER_SCHEMA_V1);
-		ResponseEntity response1 = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
-		schemaServerProperties.setAllowSchemaDeletion(true);
-		client.delete("http://localhost:8990/test/avro/v1");
-		ResponseEntity response2 = client
+		schema.setDefinition(this.USER_SCHEMA_V1);
+		ResponseEntity response1 = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response1.getStatusCode().is2xxSuccessful()).isTrue();
+		this.schemaServerProperties.setAllowSchemaDeletion(true);
+		this.client.delete("http://localhost:8990/test/avro/v1");
+		ResponseEntity response2 = this.client
 				.getForEntity("http://localhost:8990/test/avro/v1", Schema.class);
-		Assert.assertEquals(HttpStatus.NOT_FOUND, response2.getStatusCode());
+		assertThat(response2.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
 	}
 
 	@Test
@@ -185,18 +185,18 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema = new Schema();
 		schema.setFormat("avro");
 		schema.setSubject("test");
-		schema.setDefinition(USER_SCHEMA_V1);
-		ResponseEntity response1 = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
-		ResponseEntity response2 = client
+		schema.setDefinition(this.USER_SCHEMA_V1);
+		ResponseEntity response1 = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response1.getStatusCode().is2xxSuccessful()).isTrue();
+		ResponseEntity response2 = this.client
 				.getForEntity("http://localhost:8990/test/avro/v1", Schema.class);
-		Assert.assertEquals(HttpStatus.OK, response2.getStatusCode());
-		schemaServerProperties.setAllowSchemaDeletion(true);
-		client.delete("http://localhost:8990/schemas/1");
-		ResponseEntity response3 = client
+		assertThat(response2.getStatusCode()).isEqualTo(HttpStatus.OK);
+		this.schemaServerProperties.setAllowSchemaDeletion(true);
+		this.client.delete("http://localhost:8990/schemas/1");
+		ResponseEntity response3 = this.client
 				.getForEntity("http://localhost:8990/test/avro/1", Schema.class);
-		Assert.assertEquals(HttpStatus.NOT_FOUND, response3.getStatusCode());
+		assertThat(response3.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
 	}
 
 	@Test
@@ -204,30 +204,32 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema1 = new Schema();
 		schema1.setFormat("avro");
 		schema1.setSubject("test");
-		schema1.setDefinition(USER_SCHEMA_V1);
-		ResponseEntity response1 = client.postForEntity("http://localhost:8990/",
-				schema1, Schema.class);
-		Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
-		Assert.assertEquals(HttpStatus.OK,
-				client.getForEntity("http://localhost:8990/test/avro/v1", Schema.class).getStatusCode());
-		client.getForEntity("http://localhost:8990/test/avro/1", Schema.class);
+		schema1.setDefinition(this.USER_SCHEMA_V1);
+		ResponseEntity response1 = this.client
+				.postForEntity("http://localhost:8990/", schema1, Schema.class);
+		assertThat(response1.getStatusCode().is2xxSuccessful()).isTrue();
+		assertThat(this.client
+				.getForEntity("http://localhost:8990/test/avro/v1", Schema.class)
+				.getStatusCode()).isEqualTo(HttpStatus.OK);
+		this.client.getForEntity("http://localhost:8990/test/avro/1", Schema.class);
 		Schema schema2 = new Schema();
 		schema2.setFormat("avro");
 		schema2.setSubject("test");
-		schema2.setDefinition(USER_SCHEMA_V2);
-		ResponseEntity response2 = client.postForEntity("http://localhost:8990/",
-				schema2, Schema.class);
-		Assert.assertTrue(response2.getStatusCode().is2xxSuccessful());
-		Assert.assertEquals(HttpStatus.OK,
-				client.getForEntity("http://localhost:8990/test/avro/v2", Schema.class).getStatusCode());
-		schemaServerProperties.setAllowSchemaDeletion(true);
-		client.delete("http://localhost:8990/test");
-		ResponseEntity response4 = client
+		schema2.setDefinition(this.USER_SCHEMA_V2);
+		ResponseEntity response2 = this.client
+				.postForEntity("http://localhost:8990/", schema2, Schema.class);
+		assertThat(response2.getStatusCode().is2xxSuccessful()).isTrue();
+		assertThat(this.client
+				.getForEntity("http://localhost:8990/test/avro/v2", Schema.class)
+				.getStatusCode()).isEqualTo(HttpStatus.OK);
+		this.schemaServerProperties.setAllowSchemaDeletion(true);
+		this.client.delete("http://localhost:8990/test");
+		ResponseEntity response4 = this.client
 				.getForEntity("http://localhost:8990/test/avro/v1", Schema.class);
-		Assert.assertEquals(HttpStatus.NOT_FOUND, response4.getStatusCode());
-		ResponseEntity response5 = client
+		assertThat(response4.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
+		ResponseEntity response5 = this.client
 				.getForEntity("http://localhost:8990/test/avro/v2", Schema.class);
-		Assert.assertEquals(HttpStatus.NOT_FOUND, response5.getStatusCode());
+		assertThat(response5.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
 	}
 
 	@Test
@@ -235,19 +237,21 @@ public class SchemaRegistryServerAvroTests {
 		Schema schema = new Schema();
 		schema.setFormat("avro");
 		schema.setSubject("test");
-		schema.setDefinition(USER_SCHEMA_V1);
-		ResponseEntity response1 = client.postForEntity("http://localhost:8990/",
-				schema, Schema.class);
-		Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
-		ResponseEntity deleteBySubjectFormatVersion = client.exchange("http://localhost:8990/test/avro/v1",
-				HttpMethod.DELETE,
-				null, Object.class);
-		assertThat(deleteBySubjectFormatVersion.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
-		ResponseEntity deleteBySubject = client.exchange("http://localhost:8990/test", HttpMethod.DELETE,
-				null, Object.class);
-		assertThat(deleteBySubject.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
-		ResponseEntity deleteById = client.exchange("http://localhost:8990/schemas/1", HttpMethod.DELETE,
-				null, Object.class);
+		schema.setDefinition(this.USER_SCHEMA_V1);
+		ResponseEntity response1 = this.client
+				.postForEntity("http://localhost:8990/", schema, Schema.class);
+		assertThat(response1.getStatusCode().is2xxSuccessful()).isTrue();
+		ResponseEntity deleteBySubjectFormatVersion = this.client.exchange(
+				"http://localhost:8990/test/avro/v1", HttpMethod.DELETE, null,
+				Object.class);
+		assertThat(deleteBySubjectFormatVersion.getStatusCode())
+				.isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
+		ResponseEntity deleteBySubject = this.client.exchange(
+				"http://localhost:8990/test", HttpMethod.DELETE, null, Object.class);
+		assertThat(deleteBySubject.getStatusCode())
+				.isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
+		ResponseEntity deleteById = this.client.exchange(
+				"http://localhost:8990/schemas/1", HttpMethod.DELETE, null, Object.class);
 		assertThat(deleteById.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
 	}
 
@@ -256,26 +260,27 @@ public class SchemaRegistryServerAvroTests {
 		Schema v1 = new Schema();
 		v1.setFormat("avro");
 		v1.setSubject("test");
-		v1.setDefinition(USER_SCHEMA_V1);
-		ResponseEntity response1 = client.postForEntity("http://localhost:8990/",
-				v1, Schema.class);
-		Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
+		v1.setDefinition(this.USER_SCHEMA_V1);
+		ResponseEntity response1 = this.client
+				.postForEntity("http://localhost:8990/", v1, Schema.class);
+		assertThat(response1.getStatusCode().is2xxSuccessful()).isTrue();
 
 		Schema v2 = new Schema();
 		v2.setFormat("avro");
 		v2.setSubject("test");
-		v2.setDefinition(USER_SCHEMA_V2);
+		v2.setDefinition(this.USER_SCHEMA_V2);
 
-		ResponseEntity response2 = client.postForEntity("http://localhost:8990/",
-				v2, Schema.class);
-		Assert.assertTrue(response2.getStatusCode().is2xxSuccessful());
+		ResponseEntity response2 = this.client
+				.postForEntity("http://localhost:8990/", v2, Schema.class);
+		assertThat(response2.getStatusCode().is2xxSuccessful()).isTrue();
 
-		ResponseEntity> schemaResponse = client.exchange("http://localhost:8990/test/avro", HttpMethod.GET,
-				null, new ParameterizedTypeReference>() {
+		ResponseEntity> schemaResponse = this.client.exchange(
+				"http://localhost:8990/test/avro", HttpMethod.GET, null,
+				new ParameterizedTypeReference>() {
 				});
 
-		Assert.assertTrue(schemaResponse.getStatusCode().is2xxSuccessful());
-		Assert.assertEquals(2, schemaResponse.getBody().size());
+		assertThat(schemaResponse.getStatusCode().is2xxSuccessful()).isTrue();
+		assertThat(schemaResponse.getBody().size()).isEqualTo(2);
 	}
 
 }
diff --git a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTests.java b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTests.java
index 350d49a4b..b52eee7c6 100644
--- a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTests.java
+++ b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,7 +29,8 @@ import org.springframework.context.ConfigurableApplicationContext;
 public class EntityScanningTests {
 
 	@Test
-	public void testApplicationWithEmbeddedSchemaRegistryServerOutsideOfRootPackage() throws Exception {
+	public void testApplicationWithEmbeddedSchemaRegistryServerOutsideOfRootPackage()
+			throws Exception {
 		final ConfigurableApplicationContext context = SpringApplication
 				.run(CustomApplicationEmbeddingSchemaServer.class, "--server.port=0");
 		context.close();
@@ -38,5 +39,7 @@ public class EntityScanningTests {
 	@EnableAutoConfiguration
 	@EnableSchemaRegistryServer
 	public static class CustomApplicationEmbeddingSchemaServer {
+
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTestsWithEntityScan.java b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTestsWithEntityScan.java
index 0da787ecb..7580df70f 100644
--- a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTestsWithEntityScan.java
+++ b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/EntityScanningTestsWithEntityScan.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,7 +30,8 @@ import org.springframework.context.ConfigurableApplicationContext;
 public class EntityScanningTestsWithEntityScan {
 
 	@Test
-	public void testApplicationWithEmbeddedSchemaRegistryServerOutsideOfRootPackage() throws Exception {
+	public void testApplicationWithEmbeddedSchemaRegistryServerOutsideOfRootPackage()
+			throws Exception {
 		final ConfigurableApplicationContext context = SpringApplication
 				.run(CustomApplicationEmbeddingSchemaServer.class, "--server.port=0");
 		context.close();
@@ -40,5 +41,7 @@ public class EntityScanningTestsWithEntityScan {
 	@EnableSchemaRegistryServer
 	@EntityScan(basePackages = "org.springframework.cloud.stream.schema.server.entityScanning.domain")
 	public static class CustomApplicationEmbeddingSchemaServer {
+
 	}
+
 }
diff --git a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/domain/TestEntity.java b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/domain/TestEntity.java
index bfdad1702..05913377d 100644
--- a/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/domain/TestEntity.java
+++ b/spring-cloud-stream-schema-server/src/test/java/org/springframework/cloud/stream/schema/server/entityScanning/domain/TestEntity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ public class TestEntity {
 	private String name;
 
 	public long getId() {
-		return id;
+		return this.id;
 	}
 
 	public void setId(long id) {
@@ -41,10 +41,11 @@ public class TestEntity {
 	}
 
 	public String getName() {
-		return name;
+		return this.name;
 	}
 
 	public void setName(String name) {
 		this.name = name;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/pom.xml b/spring-cloud-stream-schema/pom.xml
index c2ea26fdc..13c3081b0 100644
--- a/spring-cloud-stream-schema/pom.xml
+++ b/spring-cloud-stream-schema/pom.xml
@@ -1,5 +1,7 @@
 
-
+
 	
 		spring-cloud-stream-parent
 		org.springframework.cloud
@@ -68,16 +70,26 @@
 					
 				
 				
-					${project.basedir}/target/generated-test-sources
-					${project.basedir}/target/generated-test-sources
-					${project.basedir}/src/test/resources/schemas
+					${project.basedir}/target/generated-test-sources
+					
+					
+						${project.basedir}/target/generated-test-sources
+					
+					${project.basedir}/src/test/resources/schemas
+					
 					
 						**/*.avsc
 					
 					
-						${project.basedir}/src/test/resources/schemas/imports/Email.avsc
-						${project.basedir}/src/test/resources/schemas/imports/Sms.avsc
-						${project.basedir}/src/test/resources/schemas/imports/PushNotification.avsc
+						
+							${project.basedir}/src/test/resources/schemas/imports/Email.avsc
+						
+						
+							${project.basedir}/src/test/resources/schemas/imports/Sms.avsc
+						
+						
+							${project.basedir}/src/test/resources/schemas/imports/PushNotification.avsc
+						
 					
 				
 			
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/ParsedSchema.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/ParsedSchema.java
index 6923479df..44b8bd7bb 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/ParsedSchema.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/ParsedSchema.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,18 +47,19 @@ public class ParsedSchema {
 	}
 
 	public Schema getSchema() {
-		return schema;
+		return this.schema;
 	}
 
 	public String getRepresentation() {
-		return representation;
+		return this.representation;
 	}
 
 	public SchemaRegistrationResponse getRegistration() {
-		return registration;
+		return this.registration;
 	}
 
 	public void setRegistration(SchemaRegistrationResponse registration) {
 		this.registration = registration;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaNotFoundException.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaNotFoundException.java
index d02f957d5..0b48c3575 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaNotFoundException.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaNotFoundException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,4 +24,5 @@ public class SchemaNotFoundException extends RuntimeException {
 	public SchemaNotFoundException(String message) {
 		super(message);
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaReference.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaReference.java
index 9ef5a628c..9940b2ada 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaReference.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import org.springframework.util.Assert;
 
 /**
  * References a schema through its subject and version.
+ *
  * @author Marius Bogoevici
  */
 public class SchemaReference {
@@ -97,10 +98,8 @@ public class SchemaReference {
 
 	@Override
 	public String toString() {
-		return "SchemaReference{" +
-				"subject='" + this.subject + '\'' +
-				", version=" + this.version +
-				", format='" + this.format + '\'' +
-				'}';
+		return "SchemaReference{" + "subject='" + this.subject + '\'' + ", version="
+				+ this.version + ", format='" + this.format + '\'' + '}';
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaRegistrationResponse.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaRegistrationResponse.java
index 5b4fa8522..71ed7ba98 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaRegistrationResponse.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/SchemaRegistrationResponse.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,4 +40,5 @@ public class SchemaRegistrationResponse {
 	public void setSchemaReference(SchemaReference schemaReference) {
 		this.schemaReference = schemaReference;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AbstractAvroMessageConverter.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AbstractAvroMessageConverter.java
index 7522a5a4b..d238005bd 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AbstractAvroMessageConverter.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AbstractAvroMessageConverter.java
@@ -47,6 +47,7 @@ import org.springframework.util.MimeType;
 /**
  * Base class for Apache Avro
  * {@link org.springframework.messaging.converter.MessageConverter} implementations.
+ *
  * @author Marius Bogoevici
  * @author Vinicius Carvalho
  * @author Sercan Karaoglu
@@ -73,11 +74,13 @@ public abstract class AbstractAvroMessageConverter extends AbstractMessageConver
 
 	@Override
 	protected boolean canConvertFrom(Message message, Class targetClass) {
-		return super.canConvertFrom(message, targetClass) && (message.getPayload() instanceof byte[]);
+		return super.canConvertFrom(message, targetClass)
+				&& (message.getPayload() instanceof byte[]);
 	}
 
 	@Override
-	protected Object convertFromInternal(Message message, Class targetClass, Object conversionHint) {
+	protected Object convertFromInternal(Message message, Class targetClass,
+			Object conversionHint) {
 		Object result = null;
 		try {
 			byte[] payload = (byte[]) message.getPayload();
@@ -96,7 +99,8 @@ public abstract class AbstractAvroMessageConverter extends AbstractMessageConver
 			Schema readerSchema = resolveReaderSchemaForDeserialization(targetClass);
 
 			@SuppressWarnings("unchecked")
-			DatumReader reader = getDatumReader((Class) targetClass, readerSchema, writerSchema);
+			DatumReader reader = getDatumReader((Class) targetClass,
+					readerSchema, writerSchema);
 			Decoder decoder = DecoderFactory.get().binaryDecoder(payload, null);
 			result = reader.read(null, decoder);
 		}
@@ -132,7 +136,8 @@ public abstract class AbstractAvroMessageConverter extends AbstractMessageConver
 	}
 
 	@SuppressWarnings({ "unchecked", "rawtypes" })
-	protected DatumReader getDatumReader(Class type, Schema schema, Schema writerSchema) {
+	protected DatumReader getDatumReader(Class type, Schema schema,
+			Schema writerSchema) {
 		DatumReader reader = null;
 		if (SpecificRecord.class.isAssignableFrom(type)) {
 			if (schema != null) {
@@ -167,15 +172,15 @@ public abstract class AbstractAvroMessageConverter extends AbstractMessageConver
 			}
 		}
 		if (reader == null) {
-			throw new MessageConversionException(
-					"No schema can be inferred from type " + type
-							.getName() + " and no schema has been explicitly configured.");
+			throw new MessageConversionException("No schema can be inferred from type "
+					+ type.getName() + " and no schema has been explicitly configured.");
 		}
 		return reader;
 	}
 
 	@Override
-	protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) {
+	protected Object convertToInternal(Object payload, MessageHeaders headers,
+			Object conversionHint) {
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 		try {
 			MimeType hintedContentType = null;
@@ -184,7 +189,8 @@ public abstract class AbstractAvroMessageConverter extends AbstractMessageConver
 			}
 			Schema schema = resolveSchemaForWriting(payload, headers, hintedContentType);
 			@SuppressWarnings("unchecked")
-			DatumWriter writer = getDatumWriter((Class) payload.getClass(), schema);
+			DatumWriter writer = getDatumWriter(
+					(Class) payload.getClass(), schema);
 			Encoder encoder = EncoderFactory.get().binaryEncoder(baos, null);
 			writer.write(payload, encoder);
 			encoder.flush();
@@ -195,10 +201,11 @@ public abstract class AbstractAvroMessageConverter extends AbstractMessageConver
 		return baos.toByteArray();
 	}
 
-	protected abstract Schema resolveSchemaForWriting(Object payload, MessageHeaders headers,
-			MimeType hintedContentType);
+	protected abstract Schema resolveSchemaForWriting(Object payload,
+			MessageHeaders headers, MimeType hintedContentType);
 
 	protected abstract Schema resolveWriterSchemaForDeserialization(MimeType mimeType);
 
 	protected abstract Schema resolveReaderSchemaForDeserialization(Class targetClass);
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterAutoConfiguration.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterAutoConfiguration.java
index 17c1f283d..a58cfe7fa 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterAutoConfiguration.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterAutoConfiguration.java
@@ -53,7 +53,8 @@ public class AvroMessageConverterAutoConfiguration {
 	@StreamMessageConverter
 	public AvroSchemaRegistryClientMessageConverter avroSchemaMessageConverter(
 			SchemaRegistryClient schemaRegistryClient) {
-		AvroSchemaRegistryClientMessageConverter avroSchemaRegistryClientMessageConverter = new AvroSchemaRegistryClientMessageConverter(
+		AvroSchemaRegistryClientMessageConverter avroSchemaRegistryClientMessageConverter;
+		avroSchemaRegistryClientMessageConverter = new AvroSchemaRegistryClientMessageConverter(
 				schemaRegistryClient, cacheManager());
 		avroSchemaRegistryClientMessageConverter.setDynamicSchemaGenerationEnabled(
 				this.avroMessageConverterProperties.isDynamicSchemaGenerationEnabled());
@@ -61,28 +62,32 @@ public class AvroMessageConverterAutoConfiguration {
 			avroSchemaRegistryClientMessageConverter.setReaderSchema(
 					this.avroMessageConverterProperties.getReaderSchema());
 		}
-		if (!ObjectUtils.isEmpty(this.avroMessageConverterProperties.getSchemaLocations())) {
+		if (!ObjectUtils
+				.isEmpty(this.avroMessageConverterProperties.getSchemaLocations())) {
 			avroSchemaRegistryClientMessageConverter.setSchemaLocations(
 					this.avroMessageConverterProperties.getSchemaLocations());
 		}
-		if (!ObjectUtils.isEmpty(this.avroMessageConverterProperties.getSchemaImports())) {
+		if (!ObjectUtils
+				.isEmpty(this.avroMessageConverterProperties.getSchemaImports())) {
 			avroSchemaRegistryClientMessageConverter.setSchemaImports(
 					this.avroMessageConverterProperties.getSchemaImports());
 		}
-		avroSchemaRegistryClientMessageConverter.setPrefix(this.avroMessageConverterProperties.getPrefix());
+		avroSchemaRegistryClientMessageConverter
+				.setPrefix(this.avroMessageConverterProperties.getPrefix());
 
 		try {
-			Class clazz = this.avroMessageConverterProperties.getSubjectNamingStrategy();
+			Class clazz = this.avroMessageConverterProperties
+					.getSubjectNamingStrategy();
 			Constructor constructor = ReflectionUtils.accessibleConstructor(clazz);
 
 			avroSchemaRegistryClientMessageConverter.setSubjectNamingStrategy(
-					(SubjectNamingStrategy) constructor.newInstance()
-			);
-		} catch (Exception ex) {
-			throw new IllegalStateException("Unable to create SubjectNamingStrategy " +
-					this.avroMessageConverterProperties.getSubjectNamingStrategy().toString(),
-					ex
-			);
+					(SubjectNamingStrategy) constructor.newInstance());
+		}
+		catch (Exception ex) {
+			throw new IllegalStateException("Unable to create SubjectNamingStrategy "
+					+ this.avroMessageConverterProperties.getSubjectNamingStrategy()
+							.toString(),
+					ex);
 		}
 
 		return avroSchemaRegistryClientMessageConverter;
@@ -93,4 +98,5 @@ public class AvroMessageConverterAutoConfiguration {
 	public CacheManager cacheManager() {
 		return new ConcurrentMapCacheManager();
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterProperties.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterProperties.java
index 451d8c215..3c52ca09a 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterProperties.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroMessageConverterProperties.java
@@ -32,17 +32,17 @@ public class AvroMessageConverterProperties {
 	private Resource readerSchema;
 
 	/**
-	 * The source directory of Apache Avro schema. This schema is used by this
-	 * converter. If this schema depends on other schemas consider defining those
-	 * those dependent ones in the {@link #schemaImports}
+	 * The source directory of Apache Avro schema. This schema is used by this converter.
+	 * If this schema depends on other schemas consider defining those those dependent
+	 * ones in the {@link #schemaImports}
 	 * @parameter
 	 */
 	private Resource[] schemaLocations;
 
 	/**
-	 * A list of files or directories that should be loaded first thus making
-	 * them importable by subsequent schemas. Note that imported files
-	 * should not reference each other.
+	 * A list of files or directories that should be loaded first thus making them
+	 * importable by subsequent schemas. Note that imported files should not reference
+	 * each other.
 	 * @parameter
 	 */
 	private Resource[] schemaImports;
@@ -73,7 +73,8 @@ public class AvroMessageConverterProperties {
 		return this.dynamicSchemaGenerationEnabled;
 	}
 
-	public void setDynamicSchemaGenerationEnabled(boolean dynamicSchemaGenerationEnabled) {
+	public void setDynamicSchemaGenerationEnabled(
+			boolean dynamicSchemaGenerationEnabled) {
 		this.dynamicSchemaGenerationEnabled = dynamicSchemaGenerationEnabled;
 	}
 
@@ -86,16 +87,17 @@ public class AvroMessageConverterProperties {
 	}
 
 	public Class getSubjectNamingStrategy() {
-		return subjectNamingStrategy;
+		return this.subjectNamingStrategy;
 	}
 
-	public void setSubjectNamingStrategy(Class  subjectNamingStrategy) {
+	public void setSubjectNamingStrategy(
+			Class subjectNamingStrategy) {
 		Assert.notNull(subjectNamingStrategy, "cannot be null");
 		this.subjectNamingStrategy = subjectNamingStrategy;
 	}
 
 	public Resource[] getSchemaImports() {
-		return schemaImports;
+		return this.schemaImports;
 	}
 
 	public void setSchemaImports(Resource[] schemaImports) {
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaMessageConverter.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaMessageConverter.java
index a7cc4290a..6c7af1254 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaMessageConverter.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaMessageConverter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import org.springframework.util.MimeType;
  * class for {@link org.apache.avro.specific.SpecificRecord} and regular classes, unless a
  * specific schema is set, case in which that schema will be used instead. For converting
  * to {@link org.apache.avro.generic.GenericRecord} targets, a schema must be set.s
+ *
  * @author Marius Bogoevici
  */
 
@@ -50,6 +51,8 @@ public class AvroSchemaMessageConverter extends AbstractAvroMessageConverter {
 	/**
 	 * Create a {@link AvroSchemaMessageConverter}. The converter will be used for the
 	 * provided {@link MimeType}.
+	 * @param supportedMimeType mime type to be supported by
+	 * {@link AvroSchemaMessageConverter}
 	 */
 	public AvroSchemaMessageConverter(MimeType supportedMimeType) {
 		super(supportedMimeType);
@@ -111,4 +114,5 @@ public class AvroSchemaMessageConverter extends AbstractAvroMessageConverter {
 			MimeType hintedContentType) {
 		return this.schema;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaRegistryClientMessageConverter.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaRegistryClientMessageConverter.java
index 4d843debc..d9f0eb20d 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaRegistryClientMessageConverter.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/AvroSchemaRegistryClientMessageConverter.java
@@ -17,7 +17,6 @@
 package org.springframework.cloud.stream.schema.avro;
 
 import java.io.IOException;
-
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
@@ -78,27 +77,51 @@ import org.springframework.util.ObjectUtils;
 public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessageConverter
 		implements InitializingBean {
 
+	/**
+	 * Avro format defined in the Mime type.
+	 */
 	public static final String AVRO_FORMAT = "avro";
 
+	/**
+	 * Pattern for validating the prefix to be used in the publised subtype.
+	 */
 	public static final Pattern PREFIX_VALIDATION_PATTERN = Pattern
 			.compile("[\\p{Alnum}]");
 
+	/**
+	 * Spring Cloud Stream schema property prefix.
+	 */
 	public static final String CACHE_PREFIX = "org.springframework.cloud.stream.schema";
 
+	/**
+	 * Property for reflection cache.
+	 */
 	public static final String REFLECTION_CACHE_NAME = CACHE_PREFIX + ".reflectionCache";
 
+	/**
+	 * Property for schema cache.
+	 */
 	public static final String SCHEMA_CACHE_NAME = CACHE_PREFIX + ".schemaCache";
 
+	/**
+	 * Property for reference cache.
+	 */
 	public static final String REFERENCE_CACHE_NAME = CACHE_PREFIX + ".referenceCache";
 
-	public static final MimeType DEFAULT_AVRO_MIME_TYPE = new MimeType("application", "*+" + AVRO_FORMAT);
+	/**
+	 * Default Mime type for Avro.
+	 */
+	public static final MimeType DEFAULT_AVRO_MIME_TYPE = new MimeType("application",
+			"*+" + AVRO_FORMAT);
+
+	private final CacheManager cacheManager;
+
+	protected Resource[] schemaImports = new Resource[] {};
 
 	private Pattern versionedSchema;
 
 	private boolean dynamicSchemaGenerationEnabled;
 
-	private final CacheManager cacheManager;
-
 	private Schema readerSchema;
 
 	private Resource[] schemaLocations;
@@ -109,8 +132,6 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 
 	private SubjectNamingStrategy subjectNamingStrategy;
 
-	protected Resource[] schemaImports = new Resource[]{};
-
 	/**
 	 * Creates a new instance, configuring it with {@link SchemaRegistryClient} and
 	 * {@link CacheManager}.
@@ -119,7 +140,8 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 	 * @param cacheManager instance of {@link CacheManager} to cache parsed schemas. If
 	 * caching is not required use {@link NoOpCacheManager}
 	 */
-	public AvroSchemaRegistryClientMessageConverter(SchemaRegistryClient schemaRegistryClient, CacheManager cacheManager) {
+	public AvroSchemaRegistryClientMessageConverter(
+			SchemaRegistryClient schemaRegistryClient, CacheManager cacheManager) {
 		super(Collections.singletonList(DEFAULT_AVRO_MIME_TYPE));
 		Assert.notNull(schemaRegistryClient, "cannot be null");
 		Assert.notNull(cacheManager, "'cacheManager' cannot be null");
@@ -144,8 +166,7 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 	/**
 	 * A set of locations where the converter can load schemas from. Schemas provided at
 	 * these locations will be registered automatically.
-	 *
-	 * @param schemaLocations
+	 * @param schemaLocations array of locations
 	 */
 	public void setSchemaLocations(Resource[] schemaLocations) {
 		Assert.notEmpty(schemaLocations, "cannot be empty");
@@ -155,16 +176,15 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 	/**
 	 * A set of schema locations where should be imported first. Schemas provided at these
 	 * locations will be reference, thus they should not reference each other.
-	 *
-	 * @param schemaImports
+	 * @param schemaImports array of schema imports
 	 */
 	public void setSchemaImports(Resource[] schemaImports) {
 		this.schemaImports = schemaImports;
 	}
 
 	/**
-	 * Set the prefix to be used in the publised subtype. Default 'vnd'.
-	 * @param prefix
+	 * Set the prefix to be used in the published subtype. Default 'vnd'.
+	 * @param prefix prefix to be set
 	 */
 	public void setPrefix(String prefix) {
 		Assert.hasText(prefix, "Prefix cannot be empty");
@@ -190,38 +210,36 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 	@Override
 	public void afterPropertiesSet() throws Exception {
 		this.versionedSchema = Pattern.compile("application/" + this.prefix
-				+ "\\.([\\p{Alnum}\\$\\.]+)\\.v(\\p{Digit}+)\\+"+AVRO_FORMAT);
+				+ "\\.([\\p{Alnum}\\$\\.]+)\\.v(\\p{Digit}+)\\+" + AVRO_FORMAT);
 
 		Stream.of(this.schemaImports, this.schemaLocations)
-				.filter(arr -> !ObjectUtils.isEmpty(arr))
-				.distinct()
-				.peek(resources -> {
+				.filter(arr -> !ObjectUtils.isEmpty(arr)).distinct().peek(resources -> {
 					this.logger.info("Scanning avro schema resources on classpath");
 					if (this.logger.isInfoEnabled()) {
 						this.logger.info("Parsing" + this.schemaImports.length);
 					}
 				}).flatMap(Arrays::stream).forEach(resource -> {
-			try {
-				Schema schema = parseSchema(resource);
-				if (schema.getType().equals(Schema.Type.UNION)) {
-					schema.getTypes().forEach(
-							innerSchema -> registerSchema(resource, innerSchema));
-				}
-				else {
-					registerSchema(resource, schema);
-				}
-			}
-			catch (IOException e) {
-				if (this.logger.isWarnEnabled()) {
-					this.logger.warn(
-							"Failed to parse schema at " + resource.getFilename(),
-							e);
-				}
-			}
-		});
+					try {
+						Schema schema = parseSchema(resource);
+						if (schema.getType().equals(Schema.Type.UNION)) {
+							schema.getTypes().forEach(
+									innerSchema -> registerSchema(resource, innerSchema));
+						}
+						else {
+							registerSchema(resource, schema);
+						}
+					}
+					catch (IOException e) {
+						if (this.logger.isWarnEnabled()) {
+							this.logger.warn(
+									"Failed to parse schema at " + resource.getFilename(),
+									e);
+						}
+					}
+				});
 
 		if (this.cacheManager instanceof NoOpCacheManager) {
-			logger.warn("Schema caching is effectively disabled "
+			this.logger.warn("Schema caching is effectively disabled "
 					+ "since configured cache manager is a NoOpCacheManager. If this was not "
 					+ "the intention, please provide the appropriate instance of CacheManager "
 					+ "(i.e., ConcurrentMapCacheManager).");
@@ -229,7 +247,7 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 	}
 
 	protected String toSubject(Schema schema) {
-		return subjectNamingStrategy.toSubject(schema);
+		return this.subjectNamingStrategy.toSubject(schema);
 	}
 
 	@Override
@@ -274,10 +292,11 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 
 		DirectFieldAccessor dfa = new DirectFieldAccessor(headers);
 		@SuppressWarnings("unchecked")
-		Map _headers = (Map) dfa.getPropertyValue("headers");
+		Map _headers = (Map) dfa
+				.getPropertyValue("headers");
 		_headers.put(MessageHeaders.CONTENT_TYPE,
-				"application/" + this.prefix + "." + schemaReference.getSubject()
-				+ ".v" + schemaReference.getVersion() + "+" + AVRO_FORMAT);
+				"application/" + this.prefix + "." + schemaReference.getSubject() + ".v"
+						+ schemaReference.getVersion() + "+" + AVRO_FORMAT);
 
 		return schema;
 	}
@@ -287,13 +306,17 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 		if (this.readerSchema == null) {
 			SchemaReference schemaReference = extractSchemaReference(mimeType);
 			if (schemaReference != null) {
-				ParsedSchema parsedSchema = cacheManager.getCache(REFERENCE_CACHE_NAME).get(schemaReference, ParsedSchema.class);
+				ParsedSchema parsedSchema = this.cacheManager
+						.getCache(REFERENCE_CACHE_NAME)
+						.get(schemaReference, ParsedSchema.class);
 				if (parsedSchema == null) {
-					String schemaContent = this.schemaRegistryClient.fetch(schemaReference);
+					String schemaContent = this.schemaRegistryClient
+							.fetch(schemaReference);
 					if (schemaContent != null) {
 						Schema schema = new Schema.Parser().parse(schemaContent);
 						parsedSchema = new ParsedSchema(schema);
-						cacheManager.getCache(REFERENCE_CACHE_NAME).putIfAbsent(schemaReference, parsedSchema);
+						this.cacheManager.getCache(REFERENCE_CACHE_NAME)
+								.putIfAbsent(schemaReference, parsedSchema);
 					}
 				}
 				if (parsedSchema != null) {
@@ -325,9 +348,10 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 					.get(payload.getClass().getName(), Schema.class);
 			if (schema == null) {
 				if (!isDynamicSchemaGenerationEnabled()) {
-					throw new SchemaNotFoundException(String
-							.format("No schema found in the local cache for %s, and dynamic schema generation "
-									+ "is not enabled", payload.getClass()));
+					throw new SchemaNotFoundException(String.format(
+							"No schema found in the local cache for %s, and dynamic schema generation "
+									+ "is not enabled",
+							payload.getClass()));
 				}
 				else {
 					schema = ReflectData.get().getSchema(payload.getClass());
@@ -341,15 +365,15 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 
 	private void registerSchema(Resource schemaLocation, Schema schema) {
 		if (this.logger.isInfoEnabled()) {
-			this.logger.info("Resource " + schemaLocation.getFilename()
-					+ " parsed into schema " + schema.getNamespace() + "."
-					+ schema.getName());
+			this.logger.info(
+					"Resource " + schemaLocation.getFilename() + " parsed into schema "
+							+ schema.getNamespace() + "." + schema.getName());
 		}
 		this.schemaRegistryClient.register(toSubject(schema), AVRO_FORMAT,
 				schema.toString());
 		if (this.logger.isInfoEnabled()) {
-			this.logger.info("Schema " + schema.getName()
-					+ " registered with id " + schema);
+			this.logger
+					.info("Schema " + schema.getName() + " registered with id " + schema);
 		}
 		this.cacheManager.getCache(REFLECTION_CACHE_NAME)
 				.put(schema.getNamespace() + "." + schema.getName(), schema);
@@ -365,4 +389,5 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
 		}
 		return schemaReference;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/DefaultSubjectNamingStrategy.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/DefaultSubjectNamingStrategy.java
index eecb544ed..4329f0539 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/DefaultSubjectNamingStrategy.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/DefaultSubjectNamingStrategy.java
@@ -27,4 +27,5 @@ public class DefaultSubjectNamingStrategy implements SubjectNamingStrategy {
 	public String toSubject(Schema schema) {
 		return schema.getName().toLowerCase();
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/OriginalContentTypeResolver.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/OriginalContentTypeResolver.java
index 5d3d5e9e0..e3bb7d942 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/OriginalContentTypeResolver.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/OriginalContentTypeResolver.java
@@ -46,13 +46,14 @@ class OriginalContentTypeResolver implements ContentTypeResolver {
 			mimeType = (MimeType) contentType;
 		}
 		else if (contentType instanceof String) {
-			mimeType = mimeTypeCache.get(contentType);
+			mimeType = this.mimeTypeCache.get(contentType);
 			if (mimeType == null) {
 				String valueAsString = (String) contentType;
 				mimeType = MimeType.valueOf(valueAsString);
-				mimeTypeCache.put(valueAsString, mimeType);
+				this.mimeTypeCache.put(valueAsString, mimeType);
 			}
 		}
 		return mimeType;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/SubjectNamingStrategy.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/SubjectNamingStrategy.java
index c1da40b89..2eafc57d6 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/SubjectNamingStrategy.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/avro/SubjectNamingStrategy.java
@@ -20,14 +20,17 @@ import org.apache.avro.Schema;
 
 /**
  * Provides function towards naming schema registry subjects for Avro files.
+ *
  * @author David Kalosi
  */
 public interface SubjectNamingStrategy {
 
 	/**
-	 * Takes the Avro schema on input and returns the generated subject under which the schema should be registered.
-	 * @param schema
+	 * Takes the Avro schema on input and returns the generated subject under which the
+	 * schema should be registered.
+	 * @param schema schema to register
 	 * @return subject name
 	 */
 	String toSubject(Schema schema);
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/CachingRegistryClient.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/CachingRegistryClient.java
index 304c06fc0..59b6e1490 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/CachingRegistryClient.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/CachingRegistryClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -45,23 +45,25 @@ public class CachingRegistryClient implements SchemaRegistryClient {
 	}
 
 	@Override
-	public SchemaRegistrationResponse register(String subject, String format, String schema) {
-		SchemaRegistrationResponse response = delegate.register(subject, format, schema);
-		cacheManager.getCache(ID_CACHE).put(response.getId(), schema);
-		cacheManager.getCache(REF_CACHE).put(response.getSchemaReference(), schema);
+	public SchemaRegistrationResponse register(String subject, String format,
+			String schema) {
+		SchemaRegistrationResponse response = this.delegate.register(subject, format,
+				schema);
+		this.cacheManager.getCache(ID_CACHE).put(response.getId(), schema);
+		this.cacheManager.getCache(REF_CACHE).put(response.getSchemaReference(), schema);
 		return response;
 	}
 
 	@Override
 	@Cacheable(cacheNames = REF_CACHE)
 	public String fetch(SchemaReference schemaReference) {
-		return delegate.fetch(schemaReference);
+		return this.delegate.fetch(schemaReference);
 	}
 
 	@Override
 	@Cacheable(cacheNames = ID_CACHE)
 	public String fetch(int id) {
-		return delegate.fetch(id);
+		return this.delegate.fetch(id);
 	}
 
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/ConfluentSchemaRegistryClient.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/ConfluentSchemaRegistryClient.java
index 64be7d01a..d739330c6 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/ConfluentSchemaRegistryClient.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/ConfluentSchemaRegistryClient.java
@@ -43,7 +43,8 @@ import org.springframework.web.client.RestTemplate;
  */
 public class ConfluentSchemaRegistryClient implements SchemaRegistryClient {
 
-	private static final List ACCEPT_HEADERS = Arrays.asList("application/vnd.schemaregistry.v1+json",
+	private static final List ACCEPT_HEADERS = Arrays.asList(
+			"application/vnd.schemaregistry.v1+json",
 			"application/vnd.schemaregistry+json", "application/json");
 
 	private RestTemplate template;
@@ -95,11 +96,9 @@ public class ConfluentSchemaRegistryClient implements SchemaRegistryClient {
 			version = getSubjectVersion(subject, payload);
 		}
 		catch (HttpStatusCodeException httpException) {
-			throw new RuntimeException(
-					String.format(
-							"Failed to register subject %s, server replied with status %d",
-							subject, httpException.getStatusCode().value()),
-					httpException);
+			throw new RuntimeException(String.format(
+					"Failed to register subject %s, server replied with status %d",
+					subject, httpException.getStatusCode().value()), httpException);
 		}
 		SchemaRegistrationResponse schemaRegistrationResponse = new SchemaRegistrationResponse();
 		schemaRegistrationResponse.setId(id);
@@ -112,7 +111,8 @@ public class ConfluentSchemaRegistryClient implements SchemaRegistryClient {
 	 * Confluent register API returns the id, but we need the version of a given schema
 	 * subject. After a successful registration we can inquire the server to get the
 	 * version of a schema
-	 * @param subject
+	 * @param subject the schema subject
+	 * @param payload payload to send
 	 * @return the version of the returned schema
 	 */
 	private Integer getSubjectVersion(String subject, String payload) {
@@ -129,11 +129,9 @@ public class ConfluentSchemaRegistryClient implements SchemaRegistryClient {
 			version = (Integer) response.getBody().get("version");
 		}
 		catch (HttpStatusCodeException httpException) {
-			throw new RuntimeException(
-					String.format(
-							"Failed to register subject %s, server replied with status %d",
-							subject, httpException.getStatusCode().value()),
-					httpException);
+			throw new RuntimeException(String.format(
+					"Failed to register subject %s, server replied with status %d",
+					subject, httpException.getStatusCode().value()), httpException);
 		}
 		return version;
 	}
@@ -184,4 +182,5 @@ public class ConfluentSchemaRegistryClient implements SchemaRegistryClient {
 			}
 		}
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/DefaultSchemaRegistryClient.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/DefaultSchemaRegistryClient.java
index c43b18e8d..86c3fed90 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/DefaultSchemaRegistryClient.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/DefaultSchemaRegistryClient.java
@@ -40,7 +40,7 @@ public class DefaultSchemaRegistryClient implements SchemaRegistryClient {
 	}
 
 	public DefaultSchemaRegistryClient(RestTemplate restTemplate) {
-		Assert.notNull(restTemplate,"'restTemplate' must not be null.");
+		Assert.notNull(restTemplate, "'restTemplate' must not be null.");
 		this.restTemplate = restTemplate;
 	}
 
@@ -59,34 +59,37 @@ public class DefaultSchemaRegistryClient implements SchemaRegistryClient {
 
 	@SuppressWarnings({ "rawtypes", "unchecked" })
 	@Override
-	public SchemaRegistrationResponse register(String subject, String format, String schema) {
+	public SchemaRegistrationResponse register(String subject, String format,
+			String schema) {
 		Map requestBody = new HashMap<>();
 		requestBody.put("subject", subject);
 		requestBody.put("format", format);
 		requestBody.put("definition", schema);
-		ResponseEntity responseEntity = this.restTemplate.postForEntity(this.endpoint, requestBody, Map.class);
+		ResponseEntity responseEntity = this.restTemplate
+				.postForEntity(this.endpoint, requestBody, Map.class);
 		if (responseEntity.getStatusCode().is2xxSuccessful()) {
 			SchemaRegistrationResponse registrationResponse = new SchemaRegistrationResponse();
-			Map responseBody = (Map) responseEntity.getBody();
+			Map responseBody = (Map) responseEntity
+					.getBody();
 			registrationResponse.setId((Integer) responseBody.get("id"));
 			registrationResponse.setSchemaReference(
 					new SchemaReference(subject, (Integer) responseBody.get("version"),
 							responseBody.get("format").toString()));
 			return registrationResponse;
 		}
-		throw new RuntimeException("Failed to register schema: " + responseEntity.toString());
+		throw new RuntimeException(
+				"Failed to register schema: " + responseEntity.toString());
 	}
 
 	@SuppressWarnings("rawtypes")
 	@Override
 	public String fetch(SchemaReference schemaReference) {
-		ResponseEntity responseEntity = this.restTemplate.getForEntity(
-				this.endpoint + "/" + schemaReference.getSubject() + "/" + schemaReference
-						.getFormat() + "/v" + schemaReference
-								.getVersion(),
-				Map.class);
+		ResponseEntity responseEntity = this.restTemplate.getForEntity(this.endpoint
+				+ "/" + schemaReference.getSubject() + "/" + schemaReference.getFormat()
+				+ "/v" + schemaReference.getVersion(), Map.class);
 		if (!responseEntity.getStatusCode().is2xxSuccessful()) {
-			throw new RuntimeException("Failed to fetch schema: " + responseEntity.toString());
+			throw new RuntimeException(
+					"Failed to fetch schema: " + responseEntity.toString());
 		}
 		return (String) responseEntity.getBody().get("definition");
 	}
@@ -94,11 +97,13 @@ public class DefaultSchemaRegistryClient implements SchemaRegistryClient {
 	@SuppressWarnings("rawtypes")
 	@Override
 	public String fetch(int id) {
-		ResponseEntity responseEntity = this.restTemplate.getForEntity(
-				this.endpoint + "/schemas/" + id, Map.class);
+		ResponseEntity responseEntity = this.restTemplate
+				.getForEntity(this.endpoint + "/schemas/" + id, Map.class);
 		if (!responseEntity.getStatusCode().is2xxSuccessful()) {
-			throw new RuntimeException("Failed to fetch schema: " + responseEntity.toString());
+			throw new RuntimeException(
+					"Failed to fetch schema: " + responseEntity.toString());
 		}
 		return (String) responseEntity.getBody().get("definition");
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/EnableSchemaRegistryClient.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/EnableSchemaRegistryClient.java
index 7eeb20cd9..733b43e44 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/EnableSchemaRegistryClient.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/EnableSchemaRegistryClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/SchemaRegistryClient.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/SchemaRegistryClient.java
index 9d92cea1b..22e730a3e 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/SchemaRegistryClient.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/SchemaRegistryClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ public interface SchemaRegistryClient {
 	 * Registers a schema with the remote repository returning the unique identifier
 	 * associated with this schema.
 	 * @param subject the full name of the schema
+	 * @param format format of the schema
 	 * @param schema string representation of the schema
 	 * @return a {@link SchemaRegistrationResponse} representing the result of the
 	 * operation
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientConfiguration.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientConfiguration.java
index 77f6ad376..353f66464 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientConfiguration.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientConfiguration.java
@@ -43,12 +43,14 @@ public class SchemaRegistryClientConfiguration {
 	public SchemaRegistryClient schemaRegistryClient() {
 		DefaultSchemaRegistryClient defaultSchemaRegistryClient = new DefaultSchemaRegistryClient();
 
-		if (StringUtils.hasText(schemaRegistryClientProperties.getEndpoint())) {
-			defaultSchemaRegistryClient.setEndpoint(schemaRegistryClientProperties.getEndpoint());
+		if (StringUtils.hasText(this.schemaRegistryClientProperties.getEndpoint())) {
+			defaultSchemaRegistryClient
+					.setEndpoint(this.schemaRegistryClientProperties.getEndpoint());
 		}
 
-		SchemaRegistryClient client = (schemaRegistryClientProperties.isCached())
-				? new CachingRegistryClient(defaultSchemaRegistryClient) : defaultSchemaRegistryClient;
+		SchemaRegistryClient client = (this.schemaRegistryClientProperties.isCached())
+				? new CachingRegistryClient(defaultSchemaRegistryClient)
+				: defaultSchemaRegistryClient;
 
 		return client;
 	}
diff --git a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientProperties.java b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientProperties.java
index afee74f25..b1f3f9681 100644
--- a/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientProperties.java
+++ b/spring-cloud-stream-schema/src/main/java/org/springframework/cloud/stream/schema/client/config/SchemaRegistryClientProperties.java
@@ -38,10 +38,11 @@ public class SchemaRegistryClientProperties {
 	}
 
 	public boolean isCached() {
-		return cached;
+		return this.cached;
 	}
 
 	public void setCached(boolean cached) {
 		this.cached = cached;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroMessageConverterSerializationTests.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroMessageConverterSerializationTests.java
index 3a4c6b431..0b80f61ba 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroMessageConverterSerializationTests.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroMessageConverterSerializationTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,7 +36,6 @@ import org.apache.avro.specific.SpecificDatumWriter;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -57,170 +56,164 @@ import org.springframework.messaging.MessageHeaders;
 import org.springframework.util.MimeType;
 import org.springframework.util.MimeTypeUtils;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 /**
  * @author Vinicius Carvalho
  * @author Sercan Karaoglu
  */
 public class AvroMessageConverterSerializationTests {
 
-		Pattern versionedSchema = Pattern.compile("application/" + "vnd"
-				+ "\\.([\\p{Alnum}\\$\\.]+)\\.v(\\p{Digit}+)\\+avro");
+	Pattern versionedSchema = Pattern.compile(
+			"application/" + "vnd" + "\\.([\\p{Alnum}\\$\\.]+)\\.v(\\p{Digit}+)\\+avro");
 
-		Log logger = LogFactory.getLog(getClass());
+	Log logger = LogFactory.getLog(getClass());
 
-		private ConfigurableApplicationContext schemaRegistryServerContext;
+	private ConfigurableApplicationContext schemaRegistryServerContext;
 
-		@Before
-		public void setup() {
-				schemaRegistryServerContext = SpringApplication
-						.run(SchemaRegistryServerApplication.class,
-								"--spring.main.allow-bean-definition-overriding=true");
-		}
-
-		@After
-		public void tearDown() {
-				schemaRegistryServerContext.close();
-		}
-
-		@Test
-		public void testSchemaImport() throws Exception {
-				SchemaRegistryClient client = new DefaultSchemaRegistryClient();
-				AvroSchemaRegistryClientMessageConverter converter = new AvroSchemaRegistryClientMessageConverter(
-						client, new NoOpCacheManager());
-				converter.setSubjectNamingStrategy(new DefaultSubjectNamingStrategy());
-				converter.setDynamicSchemaGenerationEnabled(false);
-				converter.setSchemaLocations(schemaRegistryServerContext
-						.getResources("classpath:schemas/Command.avsc"));
-				converter.setSchemaImports(schemaRegistryServerContext
-						.getResources("classpath:schemas/imports/*.avsc"));
-				converter.afterPropertiesSet();
-				Command notification = notification();
-				Message specificMessage = converter.toMessage(notification,
-						new MutableMessageHeaders(
-								Collections. emptyMap()));
-				Object o = converter.fromMessage(specificMessage, Command.class);
-
-				Assert.assertEquals("Serialization issue when use schema-imports", o, notification);
-		}
-
-		@Test
-		public void sourceWriteSameVersion() throws Exception {
-				User specificRecord = new User();
-				specificRecord.setName("joe");
-				Schema v1 = new Schema.Parser()
-						.parse(AvroMessageConverterSerializationTests.class
-								.getClassLoader()
-								.getResourceAsStream("schemas/user.avsc"));
-				GenericRecord genericRecord = new GenericData.Record(v1);
-				genericRecord.put("name", "joe");
-				SchemaRegistryClient client = new DefaultSchemaRegistryClient();
-				AvroSchemaRegistryClientMessageConverter converter = new AvroSchemaRegistryClientMessageConverter(
-						client, new NoOpCacheManager());
-
-				converter.setSubjectNamingStrategy(new DefaultSubjectNamingStrategy());
-				converter.setDynamicSchemaGenerationEnabled(false);
-				converter.afterPropertiesSet();
-
-				Message specificMessage = converter.toMessage(specificRecord,
-						new MutableMessageHeaders(
-								Collections. emptyMap()),
-						MimeTypeUtils.parseMimeType("application/*+avro"));
-				SchemaReference specificRef = extractSchemaReference(MimeTypeUtils
-						.parseMimeType(specificMessage.getHeaders().get("contentType")
-								.toString()));
-
-				Message genericMessage = converter.toMessage(genericRecord,
-						new MutableMessageHeaders(
-								Collections. emptyMap()),
-						MimeTypeUtils.parseMimeType("application/*+avro"));
-				SchemaReference genericRef = extractSchemaReference(MimeTypeUtils
-						.parseMimeType(genericMessage.getHeaders().get("contentType")
-								.toString()));
-
-				Assert.assertEquals(genericRef, specificRef);
-				Assert.assertEquals(1, genericRef.getVersion());
-		}
-
-		@Test
-		public void testOriginalContentTypeHeaderOnly() throws Exception {
-				User specificRecord = new User();
-				specificRecord.setName("joe");
-				Schema v1 = new Schema.Parser()
-						.parse(AvroMessageConverterSerializationTests.class
-								.getClassLoader()
-								.getResourceAsStream("schemas/user.avsc"));
-				GenericRecord genericRecord = new GenericData.Record(v1);
-				genericRecord.put("name", "joe");
-				SchemaRegistryClient client = new DefaultSchemaRegistryClient();
-				client.register("user", "avro", v1.toString());
-				AvroSchemaRegistryClientMessageConverter converter = new AvroSchemaRegistryClientMessageConverter(
-						client, new NoOpCacheManager());
-				converter.setDynamicSchemaGenerationEnabled(false);
-				converter.afterPropertiesSet();
-				ByteArrayOutputStream baos = new ByteArrayOutputStream();
-				DatumWriter writer = new SpecificDatumWriter<>(User.class);
-				Encoder encoder = EncoderFactory.get().binaryEncoder(baos, null);
-				writer.write(specificRecord, encoder);
-				encoder.flush();
-				Message source = MessageBuilder.withPayload(baos.toByteArray())
-						.setHeader(MessageHeaders.CONTENT_TYPE,
-								MimeTypeUtils.APPLICATION_OCTET_STREAM)
-						.setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE,
-								"application/vnd.user.v1+avro").build();
-				Object converted = converter.fromMessage(source, User.class);
-				Assert.assertNotNull(converted);
-				Assert.assertEquals(specificRecord.getName().toString(),
-						((User) converted).getName().toString());
-
-		}
-
-		private SchemaReference extractSchemaReference(MimeType mimeType) {
-				SchemaReference schemaReference = null;
-				Matcher schemaMatcher = this.versionedSchema.matcher(mimeType.toString());
-				if (schemaMatcher.find()) {
-						String subject = schemaMatcher.group(1);
-						Integer version = Integer.parseInt(schemaMatcher.group(2));
-						schemaReference = new SchemaReference(subject, version,
-								AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT);
-				}
-				return schemaReference;
-		}
-
-		public static Command notification() {
-				Command messageToSend = getCommandToSend();
-				messageToSend.setType("notification");
-				PushNotification pushNotification = new PushNotification();
-				pushNotification.setArn("google");
-				pushNotification.setText("hello");
-				messageToSend.setPayload(pushNotification);
-				return messageToSend;
-		}
-
-		public static Command sms() {
-				Command messageToSend = getCommandToSend();
-				messageToSend.setType("sms");
-				Sms sms = new Sms();
-				sms.setPhoneNumber("6141231212");
-				sms.setText("hello");
-				messageToSend.setPayload(sms);
-				return messageToSend;
-		}
-
-		public static Command email() {
-				Command messageToSend = getCommandToSend();
-				messageToSend.setType("email");
-				Email email = new Email();
-				email.setAddressTo("sercan");
-				email.setText("hello");
-				email.setTitle("hi");
-				messageToSend.setPayload(email);
-				return messageToSend;
-		}
-
-		public static Command getCommandToSend() {
-				Command messageToSend = new Command();
-				messageToSend.setCorrelationId("abc");
-				return messageToSend;
+	public static Command notification() {
+		Command messageToSend = getCommandToSend();
+		messageToSend.setType("notification");
+		PushNotification pushNotification = new PushNotification();
+		pushNotification.setArn("google");
+		pushNotification.setText("hello");
+		messageToSend.setPayload(pushNotification);
+		return messageToSend;
+	}
+
+	public static Command sms() {
+		Command messageToSend = getCommandToSend();
+		messageToSend.setType("sms");
+		Sms sms = new Sms();
+		sms.setPhoneNumber("6141231212");
+		sms.setText("hello");
+		messageToSend.setPayload(sms);
+		return messageToSend;
+	}
+
+	public static Command email() {
+		Command messageToSend = getCommandToSend();
+		messageToSend.setType("email");
+		Email email = new Email();
+		email.setAddressTo("sercan");
+		email.setText("hello");
+		email.setTitle("hi");
+		messageToSend.setPayload(email);
+		return messageToSend;
+	}
+
+	public static Command getCommandToSend() {
+		Command messageToSend = new Command();
+		messageToSend.setCorrelationId("abc");
+		return messageToSend;
+	}
+
+	@Before
+	public void setup() {
+		this.schemaRegistryServerContext = SpringApplication.run(
+				SchemaRegistryServerApplication.class,
+				"--spring.main.allow-bean-definition-overriding=true");
+	}
+
+	@After
+	public void tearDown() {
+		this.schemaRegistryServerContext.close();
+	}
+
+	@Test
+	public void testSchemaImport() throws Exception {
+		SchemaRegistryClient client = new DefaultSchemaRegistryClient();
+		AvroSchemaRegistryClientMessageConverter converter = new AvroSchemaRegistryClientMessageConverter(
+				client, new NoOpCacheManager());
+		converter.setSubjectNamingStrategy(new DefaultSubjectNamingStrategy());
+		converter.setDynamicSchemaGenerationEnabled(false);
+		converter.setSchemaLocations(this.schemaRegistryServerContext
+				.getResources("classpath:schemas/Command.avsc"));
+		converter.setSchemaImports(this.schemaRegistryServerContext
+				.getResources("classpath:schemas/imports/*.avsc"));
+		converter.afterPropertiesSet();
+		Command notification = notification();
+		Message specificMessage = converter.toMessage(notification,
+				new MutableMessageHeaders(Collections.emptyMap()));
+		Object o = converter.fromMessage(specificMessage, Command.class);
+
+		assertThat(o).isEqualTo(notification)
+				.as("Serialization issue when use schema-imports");
+	}
+
+	@Test
+	public void sourceWriteSameVersion() throws Exception {
+		User specificRecord = new User();
+		specificRecord.setName("joe");
+		Schema v1 = new Schema.Parser().parse(AvroMessageConverterSerializationTests.class
+				.getClassLoader().getResourceAsStream("schemas/user.avsc"));
+		GenericRecord genericRecord = new GenericData.Record(v1);
+		genericRecord.put("name", "joe");
+		SchemaRegistryClient client = new DefaultSchemaRegistryClient();
+		AvroSchemaRegistryClientMessageConverter converter = new AvroSchemaRegistryClientMessageConverter(
+				client, new NoOpCacheManager());
+
+		converter.setSubjectNamingStrategy(new DefaultSubjectNamingStrategy());
+		converter.setDynamicSchemaGenerationEnabled(false);
+		converter.afterPropertiesSet();
+
+		Message specificMessage = converter.toMessage(specificRecord,
+				new MutableMessageHeaders(Collections.emptyMap()),
+				MimeTypeUtils.parseMimeType("application/*+avro"));
+		SchemaReference specificRef = extractSchemaReference(MimeTypeUtils.parseMimeType(
+				specificMessage.getHeaders().get("contentType").toString()));
+
+		Message genericMessage = converter.toMessage(genericRecord,
+				new MutableMessageHeaders(Collections.emptyMap()),
+				MimeTypeUtils.parseMimeType("application/*+avro"));
+		SchemaReference genericRef = extractSchemaReference(MimeTypeUtils.parseMimeType(
+				genericMessage.getHeaders().get("contentType").toString()));
+
+		assertThat(specificRef).isEqualTo(genericRef);
+		assertThat(genericRef.getVersion()).isEqualTo(1);
+	}
+
+	@Test
+	public void testOriginalContentTypeHeaderOnly() throws Exception {
+		User specificRecord = new User();
+		specificRecord.setName("joe");
+		Schema v1 = new Schema.Parser().parse(AvroMessageConverterSerializationTests.class
+				.getClassLoader().getResourceAsStream("schemas/user.avsc"));
+		GenericRecord genericRecord = new GenericData.Record(v1);
+		genericRecord.put("name", "joe");
+		SchemaRegistryClient client = new DefaultSchemaRegistryClient();
+		client.register("user", "avro", v1.toString());
+		AvroSchemaRegistryClientMessageConverter converter = new AvroSchemaRegistryClientMessageConverter(
+				client, new NoOpCacheManager());
+		converter.setDynamicSchemaGenerationEnabled(false);
+		converter.afterPropertiesSet();
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		DatumWriter writer = new SpecificDatumWriter<>(User.class);
+		Encoder encoder = EncoderFactory.get().binaryEncoder(baos, null);
+		writer.write(specificRecord, encoder);
+		encoder.flush();
+		Message source = MessageBuilder.withPayload(baos.toByteArray())
+				.setHeader(MessageHeaders.CONTENT_TYPE,
+						MimeTypeUtils.APPLICATION_OCTET_STREAM)
+				.setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE,
+						"application/vnd.user.v1+avro")
+				.build();
+		Object converted = converter.fromMessage(source, User.class);
+		assertThat(converted).isNotNull();
+		assertThat(specificRecord.getName().toString())
+				.isEqualTo(((User) converted).getName().toString());
+	}
+
+	private SchemaReference extractSchemaReference(MimeType mimeType) {
+		SchemaReference schemaReference = null;
+		Matcher schemaMatcher = this.versionedSchema.matcher(mimeType.toString());
+		if (schemaMatcher.find()) {
+			String subject = schemaMatcher.group(1);
+			Integer version = Integer.parseInt(schemaMatcher.group(2));
+			schemaReference = new SchemaReference(subject, version,
+					AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT);
 		}
+		return schemaReference;
+	}
 
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaMessageConverterTests.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaMessageConverterTests.java
index d04aac0c0..cd47cfd7a 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaMessageConverterTests.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaMessageConverterTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -54,8 +54,8 @@ public class AvroSchemaMessageConverterTests {
 
 	@Test
 	public void testSendMessageWithLocation() throws Exception {
-		ConfigurableApplicationContext sourceContext = SpringApplication.run(AvroSourceApplication.class,
-				"--server.port=0",
+		ConfigurableApplicationContext sourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--schemaLocation=classpath:schemas/users_v1.schema",
 				"--spring.cloud.stream.schemaRegistryClient.enabled=false",
@@ -65,12 +65,13 @@ public class AvroSchemaMessageConverterTests {
 		firstOutboundFoo.setName("foo" + UUID.randomUUID().toString());
 		firstOutboundFoo.setFavoriteColor("foo" + UUID.randomUUID().toString());
 		source.output().send(MessageBuilder.withPayload(firstOutboundFoo).build());
-		MessageCollector sourceMessageCollector = sourceContext.getBean(MessageCollector.class);
-		Message outboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		MessageCollector sourceMessageCollector = sourceContext
+				.getBean(MessageCollector.class);
+		Message outboundMessage = sourceMessageCollector.forChannel(source.output())
+				.poll(1000, TimeUnit.MILLISECONDS);
 
-		ConfigurableApplicationContext barSourceContext = SpringApplication.run(AvroSourceApplication.class,
-				"--server.port=0",
+		ConfigurableApplicationContext barSourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--schemaLocation=classpath:schemas/users_v1.schema",
 				"--spring.cloud.stream.schemaRegistryClient.enabled=false",
@@ -81,9 +82,10 @@ public class AvroSchemaMessageConverterTests {
 		firstOutboundUser2.setFavoritePlace("foo" + UUID.randomUUID().toString());
 		firstOutboundUser2.setName("foo" + UUID.randomUUID().toString());
 		barSource.output().send(MessageBuilder.withPayload(firstOutboundUser2).build());
-		MessageCollector barSourceMessageCollector = barSourceContext.getBean(MessageCollector.class);
-		Message barOutboundMessage = barSourceMessageCollector.forChannel(barSource.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		MessageCollector barSourceMessageCollector = barSourceContext
+				.getBean(MessageCollector.class);
+		Message barOutboundMessage = barSourceMessageCollector
+				.forChannel(barSource.output()).poll(1000, TimeUnit.MILLISECONDS);
 
 		assertThat(barOutboundMessage).isNotNull();
 
@@ -92,11 +94,11 @@ public class AvroSchemaMessageConverterTests {
 		secondUser2OutboundPojo.setFavoritePlace("foo" + UUID.randomUUID().toString());
 		secondUser2OutboundPojo.setName("foo" + UUID.randomUUID().toString());
 		source.output().send(MessageBuilder.withPayload(secondUser2OutboundPojo).build());
-		Message secondBarOutboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		Message secondBarOutboundMessage = sourceMessageCollector
+				.forChannel(source.output()).poll(1000, TimeUnit.MILLISECONDS);
 
-		ConfigurableApplicationContext sinkContext = SpringApplication.run(AvroSinkApplication.class,
-				"--server.port=0",
+		ConfigurableApplicationContext sinkContext = SpringApplication.run(
+				AvroSinkApplication.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.schemaRegistryClient.enabled=false",
 				"--schemaLocation=classpath:schemas/users_v1.schema");
@@ -104,27 +106,33 @@ public class AvroSchemaMessageConverterTests {
 		sink.input().send(outboundMessage);
 		sink.input().send(barOutboundMessage);
 		sink.input().send(secondBarOutboundMessage);
-		List receivedUsers = sinkContext.getBean(AvroSinkApplication.class).receivedUsers;
+		List receivedUsers = sinkContext
+				.getBean(AvroSinkApplication.class).receivedUsers;
 		assertThat(receivedUsers).hasSize(3);
 		assertThat(receivedUsers.get(0)).isNotSameAs(firstOutboundFoo);
-		assertThat(receivedUsers.get(0).getFavoriteColor()).isEqualTo(firstOutboundFoo.getFavoriteColor());
+		assertThat(receivedUsers.get(0).getFavoriteColor())
+				.isEqualTo(firstOutboundFoo.getFavoriteColor());
 		assertThat(receivedUsers.get(0).getName()).isEqualTo(firstOutboundFoo.getName());
 
 		assertThat(receivedUsers.get(1)).isNotSameAs(firstOutboundUser2);
-		assertThat(receivedUsers.get(1).getFavoriteColor()).isEqualTo(firstOutboundUser2.getFavoriteColor());
-		assertThat(receivedUsers.get(1).getName()).isEqualTo(firstOutboundUser2.getName());
+		assertThat(receivedUsers.get(1).getFavoriteColor())
+				.isEqualTo(firstOutboundUser2.getFavoriteColor());
+		assertThat(receivedUsers.get(1).getName())
+				.isEqualTo(firstOutboundUser2.getName());
 
 		assertThat(receivedUsers.get(2)).isNotSameAs(secondUser2OutboundPojo);
-		assertThat(receivedUsers.get(2).getFavoriteColor()).isEqualTo(secondUser2OutboundPojo.getFavoriteColor());
-		assertThat(receivedUsers.get(2).getName()).isEqualTo(secondUser2OutboundPojo.getName());
+		assertThat(receivedUsers.get(2).getFavoriteColor())
+				.isEqualTo(secondUser2OutboundPojo.getFavoriteColor());
+		assertThat(receivedUsers.get(2).getName())
+				.isEqualTo(secondUser2OutboundPojo.getName());
 
 		sourceContext.close();
 	}
 
 	@Test
 	public void testSendMessageWithoutLocation() throws Exception {
-		ConfigurableApplicationContext sourceContext = SpringApplication.run(AvroSourceApplication.class,
-				"--server.port=0",
+		ConfigurableApplicationContext sourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.schemaRegistryClient.enabled=false",
 				"--spring.cloud.stream.bindings.output.contentType=avro/bytes");
@@ -133,12 +141,13 @@ public class AvroSchemaMessageConverterTests {
 		firstOutboundFoo.setName("foo" + UUID.randomUUID().toString());
 		firstOutboundFoo.setFavoriteColor("foo" + UUID.randomUUID().toString());
 		source.output().send(MessageBuilder.withPayload(firstOutboundFoo).build());
-		MessageCollector sourceMessageCollector = sourceContext.getBean(MessageCollector.class);
-		Message outboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		MessageCollector sourceMessageCollector = sourceContext
+				.getBean(MessageCollector.class);
+		Message outboundMessage = sourceMessageCollector.forChannel(source.output())
+				.poll(1000, TimeUnit.MILLISECONDS);
 
-		ConfigurableApplicationContext barSourceContext = SpringApplication.run(AvroSourceApplication.class,
-				"--server.port=0",
+		ConfigurableApplicationContext barSourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.schemaRegistryClient.enabled=false",
 				"--spring.cloud.stream.bindings.output.contentType=avro/bytes");
@@ -148,9 +157,10 @@ public class AvroSchemaMessageConverterTests {
 		firstOutboundUser2.setFavoritePlace("foo" + UUID.randomUUID().toString());
 		firstOutboundUser2.setName("foo" + UUID.randomUUID().toString());
 		barSource.output().send(MessageBuilder.withPayload(firstOutboundUser2).build());
-		MessageCollector barSourceMessageCollector = barSourceContext.getBean(MessageCollector.class);
-		Message barOutboundMessage = barSourceMessageCollector.forChannel(barSource.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		MessageCollector barSourceMessageCollector = barSourceContext
+				.getBean(MessageCollector.class);
+		Message barOutboundMessage = barSourceMessageCollector
+				.forChannel(barSource.output()).poll(1000, TimeUnit.MILLISECONDS);
 
 		assertThat(barOutboundMessage).isNotNull();
 
@@ -159,30 +169,36 @@ public class AvroSchemaMessageConverterTests {
 		secondUser2OutboundPojo.setFavoritePlace("foo" + UUID.randomUUID().toString());
 		secondUser2OutboundPojo.setName("foo" + UUID.randomUUID().toString());
 		source.output().send(MessageBuilder.withPayload(secondUser2OutboundPojo).build());
-		Message secondBarOutboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		Message secondBarOutboundMessage = sourceMessageCollector
+				.forChannel(source.output()).poll(1000, TimeUnit.MILLISECONDS);
 
-		ConfigurableApplicationContext sinkContext = SpringApplication.run(AvroSinkApplication.class,
-				"--server.port=0",
+		ConfigurableApplicationContext sinkContext = SpringApplication.run(
+				AvroSinkApplication.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.schemaRegistryClient.enabled=false");
 		Sink sink = sinkContext.getBean(Sink.class);
 		sink.input().send(outboundMessage);
 		sink.input().send(barOutboundMessage);
 		sink.input().send(secondBarOutboundMessage);
-		List receivedUsers = sinkContext.getBean(AvroSinkApplication.class).receivedUsers;
+		List receivedUsers = sinkContext
+				.getBean(AvroSinkApplication.class).receivedUsers;
 		assertThat(receivedUsers).hasSize(3);
 		assertThat(receivedUsers.get(0)).isNotSameAs(firstOutboundFoo);
-		assertThat(receivedUsers.get(0).getFavoriteColor()).isEqualTo(firstOutboundFoo.getFavoriteColor());
+		assertThat(receivedUsers.get(0).getFavoriteColor())
+				.isEqualTo(firstOutboundFoo.getFavoriteColor());
 		assertThat(receivedUsers.get(0).getName()).isEqualTo(firstOutboundFoo.getName());
 
 		assertThat(receivedUsers.get(1)).isNotSameAs(firstOutboundUser2);
-		assertThat(receivedUsers.get(1).getFavoriteColor()).isEqualTo(firstOutboundUser2.getFavoriteColor());
-		assertThat(receivedUsers.get(1).getName()).isEqualTo(firstOutboundUser2.getName());
+		assertThat(receivedUsers.get(1).getFavoriteColor())
+				.isEqualTo(firstOutboundUser2.getFavoriteColor());
+		assertThat(receivedUsers.get(1).getName())
+				.isEqualTo(firstOutboundUser2.getName());
 
 		assertThat(receivedUsers.get(2)).isNotSameAs(secondUser2OutboundPojo);
-		assertThat(receivedUsers.get(2).getFavoriteColor()).isEqualTo(secondUser2OutboundPojo.getFavoriteColor());
-		assertThat(receivedUsers.get(2).getName()).isEqualTo(secondUser2OutboundPojo.getName());
+		assertThat(receivedUsers.get(2).getFavoriteColor())
+				.isEqualTo(secondUser2OutboundPojo.getFavoriteColor());
+		assertThat(receivedUsers.get(2).getName())
+				.isEqualTo(secondUser2OutboundPojo.getName());
 
 		sourceContext.close();
 	}
@@ -208,11 +224,12 @@ public class AvroSchemaMessageConverterTests {
 		public MessageConverter userMessageConverter() throws IOException {
 			AvroSchemaMessageConverter avroSchemaMessageConverter = new AvroSchemaMessageConverter(
 					MimeType.valueOf("avro/bytes"));
-			if (schemaLocation != null) {
-				avroSchemaMessageConverter.setSchemaLocation(schemaLocation);
+			if (this.schemaLocation != null) {
+				avroSchemaMessageConverter.setSchemaLocation(this.schemaLocation);
 			}
 			return avroSchemaMessageConverter;
 		}
+
 	}
 
 	@EnableBinding(Sink.class)
@@ -226,7 +243,7 @@ public class AvroSchemaMessageConverterTests {
 
 		@StreamListener(Sink.INPUT)
 		public void listen(User1 user) {
-			receivedUsers.add(user);
+			this.receivedUsers.add(user);
 		}
 
 		public void setSchemaLocation(Resource schemaLocation) {
@@ -238,11 +255,12 @@ public class AvroSchemaMessageConverterTests {
 		public MessageConverter userMessageConverter() throws IOException {
 			AvroSchemaMessageConverter avroSchemaMessageConverter = new AvroSchemaMessageConverter(
 					MimeType.valueOf("avro/bytes"));
-			if (schemaLocation != null) {
-				avroSchemaMessageConverter.setSchemaLocation(schemaLocation);
+			if (this.schemaLocation != null) {
+				avroSchemaMessageConverter.setSchemaLocation(this.schemaLocation);
 			}
 			return avroSchemaMessageConverter;
 		}
 
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaRegistryClientMessageConverterTests.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaRegistryClientMessageConverterTests.java
index f40cfb2e1..aa856db60 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaRegistryClientMessageConverterTests.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroSchemaRegistryClientMessageConverterTests.java
@@ -59,200 +59,195 @@ import static org.springframework.cloud.schema.avro.AvroMessageConverterSerializ
  */
 public class AvroSchemaRegistryClientMessageConverterTests {
 
-		static SchemaRegistryClient stubSchemaRegistryClient = new StubSchemaRegistryClient();
+	static SchemaRegistryClient stubSchemaRegistryClient = new StubSchemaRegistryClient();
 
-		private ConfigurableApplicationContext schemaRegistryServerContext;
+	private ConfigurableApplicationContext schemaRegistryServerContext;
 
-		@Before
-		public void setup() {
-				schemaRegistryServerContext = SpringApplication
-						.run(SchemaRegistryServerApplication.class,
-								"--spring.main.allow-bean-definition-overriding=true");
+	@Before
+	public void setup() {
+		this.schemaRegistryServerContext = SpringApplication.run(
+				SchemaRegistryServerApplication.class,
+				"--spring.main.allow-bean-definition-overriding=true");
+	}
+
+	@After
+	public void tearDown() {
+		this.schemaRegistryServerContext.close();
+	}
+
+	@Test
+	public void testSendMessage() throws Exception {
+
+		ConfigurableApplicationContext sourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0",
+				"--spring.jmx.enabled=false",
+				"--spring.cloud.stream.bindings.output.contentType=application/*+avro",
+				"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
+		Source source = sourceContext.getBean(Source.class);
+		User1 firstOutboundFoo = new User1();
+		firstOutboundFoo.setFavoriteColor("foo" + UUID.randomUUID().toString());
+		firstOutboundFoo.setName("foo" + UUID.randomUUID().toString());
+		source.output().send(MessageBuilder.withPayload(firstOutboundFoo).build());
+		MessageCollector sourceMessageCollector = sourceContext
+				.getBean(MessageCollector.class);
+		Message outboundMessage = sourceMessageCollector.forChannel(source.output())
+				.poll(1000, TimeUnit.MILLISECONDS);
+
+		ConfigurableApplicationContext barSourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0",
+				"--spring.jmx.enabled=false",
+				"--spring.cloud.stream.bindings.output.contentType=application/vnd.user1.v1+avro",
+				"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
+		Source barSource = barSourceContext.getBean(Source.class);
+		User2 firstOutboundUser2 = new User2();
+		firstOutboundUser2.setFavoriteColor("foo" + UUID.randomUUID().toString());
+		firstOutboundUser2.setName("foo" + UUID.randomUUID().toString());
+		barSource.output().send(MessageBuilder.withPayload(firstOutboundUser2).build());
+		MessageCollector barSourceMessageCollector = barSourceContext
+				.getBean(MessageCollector.class);
+		Message barOutboundMessage = barSourceMessageCollector
+				.forChannel(barSource.output()).poll(1000, TimeUnit.MILLISECONDS);
+
+		assertThat(barOutboundMessage).isNotNull();
+
+		User2 secondBarOutboundPojo = new User2();
+		secondBarOutboundPojo.setFavoriteColor("foo" + UUID.randomUUID().toString());
+		secondBarOutboundPojo.setName("foo" + UUID.randomUUID().toString());
+		source.output().send(MessageBuilder.withPayload(secondBarOutboundPojo).build());
+		Message secondBarOutboundMessage = sourceMessageCollector
+				.forChannel(source.output()).poll(1000, TimeUnit.MILLISECONDS);
+
+		ConfigurableApplicationContext sinkContext = SpringApplication.run(
+				AvroSinkApplication.class, "--server.port=0",
+				"--spring.jmx.enabled=false");
+		Sink sink = sinkContext.getBean(Sink.class);
+		sink.input().send(outboundMessage);
+		sink.input().send(barOutboundMessage);
+		sink.input().send(secondBarOutboundMessage);
+		List receivedPojos = sinkContext
+				.getBean(AvroSinkApplication.class).receivedPojos;
+		assertThat(receivedPojos).hasSize(3);
+		assertThat(receivedPojos.get(0)).isNotSameAs(firstOutboundFoo);
+		assertThat(receivedPojos.get(0).getFavoriteColor())
+				.isEqualTo(firstOutboundFoo.getFavoriteColor());
+		assertThat(receivedPojos.get(0).getName()).isEqualTo(firstOutboundFoo.getName());
+		assertThat(receivedPojos.get(0).getFavoritePlace()).isEqualTo("NYC");
+
+		assertThat(receivedPojos.get(1)).isNotSameAs(firstOutboundUser2);
+		assertThat(receivedPojos.get(1).getFavoriteColor())
+				.isEqualTo(firstOutboundUser2.getFavoriteColor());
+		assertThat(receivedPojos.get(1).getName())
+				.isEqualTo(firstOutboundUser2.getName());
+		assertThat(receivedPojos.get(1).getFavoritePlace()).isEqualTo("Boston");
+
+		assertThat(receivedPojos.get(2)).isNotSameAs(secondBarOutboundPojo);
+		assertThat(receivedPojos.get(2).getFavoriteColor())
+				.isEqualTo(secondBarOutboundPojo.getFavoriteColor());
+		assertThat(receivedPojos.get(2).getName())
+				.isEqualTo(secondBarOutboundPojo.getName());
+		assertThat(receivedPojos.get(2).getFavoritePlace())
+				.isEqualTo(secondBarOutboundPojo.getFavoritePlace());
+
+		sinkContext.close();
+		barSourceContext.close();
+		sourceContext.close();
+		this.schemaRegistryServerContext.close();
+	}
+
+	@Test
+	public void testSchemaImportConfiguration() throws Exception {
+		final String[] args = { "--server.port=0", "--spring.jmx.enabled=false",
+				"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true",
+				"--spring.cloud.stream.bindings.output.contentType=application/*+avro",
+				"--spring.cloud.stream.bindings.output.destination=test",
+				"--spring.cloud.stream.bindings.schema-registry-client.endpoint=http://localhost:8990",
+				"--spring.cloud.stream.schema.avro.schema-locations=classpath:schemas/Command.avsc",
+				"--spring.cloud.stream.schema.avro.schema-imports=classpath:schemas/imports/Sms.avsc,"
+						+ " classpath:schemas/imports/Email.avsc, classpath:schemas/imports/PushNotification.avsc" };
+
+		final ConfigurableApplicationContext sourceContext = SpringApplication
+				.run(AvroSourceApplication.class, args);
+		final ConfigurableApplicationContext sinkContext = SpringApplication
+				.run(CommandSinkApplication.class, args);
+		final Source barSource = sourceContext.getBean(Source.class);
+		final Command notification = notification();
+		barSource.output().send(MessageBuilder.withPayload(notification).build());
+		final MessageCollector barSourceMessageCollector = sourceContext
+				.getBean(MessageCollector.class);
+		final Message outboundMessage = barSourceMessageCollector
+				.forChannel(barSource.output()).poll(1000, TimeUnit.MILLISECONDS);
+		assertThat(outboundMessage).isNotNull();
+		Sink sink = sinkContext.getBean(Sink.class);
+		sink.input().send(outboundMessage);
+		List receivedPojos = sinkContext
+				.getBean(CommandSinkApplication.class).receivedPojos;
+
+		assertThat(receivedPojos).hasSize(1);
+		assertThat(receivedPojos.get(0)).isEqualTo(notification);
+
+	}
+
+	@Test
+	public void testNoCacheConfiguration() {
+		ConfigurableApplicationContext sourceContext = SpringApplication
+				.run(NoCacheConfiguration.class, "--spring.main.web-environment=false");
+		AvroSchemaRegistryClientMessageConverter converter = sourceContext
+				.getBean(AvroSchemaRegistryClientMessageConverter.class);
+		DirectFieldAccessor accessor = new DirectFieldAccessor(converter);
+		assertThat(accessor.getPropertyValue("cacheManager"))
+				.isInstanceOf(NoOpCacheManager.class);
+	}
+
+	@EnableBinding(Source.class)
+	@EnableAutoConfiguration
+	@EnableSchemaRegistryClient
+	public static class AvroSourceApplication {
+
+	}
+
+	@EnableBinding(Sink.class)
+	@EnableAutoConfiguration
+	@EnableSchemaRegistryClient
+	public static class AvroSinkApplication {
+
+		public List receivedPojos = new ArrayList<>();
+
+		@StreamListener(Sink.INPUT)
+		public void listen(User2 fooPojo) {
+			this.receivedPojos.add(fooPojo);
 		}
 
-		@After
-		public void tearDown() {
-				schemaRegistryServerContext.close();
+	}
+
+	@EnableBinding(Sink.class)
+	@EnableAutoConfiguration
+	@EnableSchemaRegistryClient
+	public static class CommandSinkApplication {
+
+		public List receivedPojos = new ArrayList<>();
+
+		@StreamListener(Sink.INPUT)
+		public void listen(Command fooPojo) {
+			this.receivedPojos.add(fooPojo);
 		}
 
-		@Test
-		public void testSendMessage() throws Exception {
+	}
 
-				ConfigurableApplicationContext sourceContext = SpringApplication
-						.run(AvroSourceApplication.class, "--server.port=0",
-								"--spring.jmx.enabled=false",
-								"--spring.cloud.stream.bindings.output.contentType=application/*+avro",
-								"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
-				Source source = sourceContext.getBean(Source.class);
-				User1 firstOutboundFoo = new User1();
-				firstOutboundFoo.setFavoriteColor("foo" + UUID.randomUUID().toString());
-				firstOutboundFoo.setName("foo" + UUID.randomUUID().toString());
-				source.output()
-						.send(MessageBuilder.withPayload(firstOutboundFoo).build());
-				MessageCollector sourceMessageCollector = sourceContext
-						.getBean(MessageCollector.class);
-				Message outboundMessage = sourceMessageCollector
-						.forChannel(source.output()).poll(1000, TimeUnit.MILLISECONDS);
+	@Configuration
+	public static class NoCacheConfiguration {
 
-				ConfigurableApplicationContext barSourceContext = SpringApplication
-						.run(AvroSourceApplication.class, "--server.port=0",
-								"--spring.jmx.enabled=false",
-								"--spring.cloud.stream.bindings.output.contentType=application/vnd.user1.v1+avro",
-								"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
-				Source barSource = barSourceContext.getBean(Source.class);
-				User2 firstOutboundUser2 = new User2();
-				firstOutboundUser2.setFavoriteColor("foo" + UUID.randomUUID().toString());
-				firstOutboundUser2.setName("foo" + UUID.randomUUID().toString());
-				barSource.output()
-						.send(MessageBuilder.withPayload(firstOutboundUser2).build());
-				MessageCollector barSourceMessageCollector = barSourceContext
-						.getBean(MessageCollector.class);
-				Message barOutboundMessage = barSourceMessageCollector
-						.forChannel(barSource.output()).poll(1000, TimeUnit.MILLISECONDS);
-
-				assertThat(barOutboundMessage).isNotNull();
-
-				User2 secondBarOutboundPojo = new User2();
-				secondBarOutboundPojo
-						.setFavoriteColor("foo" + UUID.randomUUID().toString());
-				secondBarOutboundPojo.setName("foo" + UUID.randomUUID().toString());
-				source.output()
-						.send(MessageBuilder.withPayload(secondBarOutboundPojo).build());
-				Message secondBarOutboundMessage = sourceMessageCollector
-						.forChannel(source.output()).poll(1000, TimeUnit.MILLISECONDS);
-
-				ConfigurableApplicationContext sinkContext = SpringApplication
-						.run(AvroSinkApplication.class, "--server.port=0",
-								"--spring.jmx.enabled=false");
-				Sink sink = sinkContext.getBean(Sink.class);
-				sink.input().send(outboundMessage);
-				sink.input().send(barOutboundMessage);
-				sink.input().send(secondBarOutboundMessage);
-				List receivedPojos = sinkContext
-						.getBean(AvroSinkApplication.class).receivedPojos;
-				assertThat(receivedPojos).hasSize(3);
-				assertThat(receivedPojos.get(0)).isNotSameAs(firstOutboundFoo);
-				assertThat(receivedPojos.get(0).getFavoriteColor())
-						.isEqualTo(firstOutboundFoo.getFavoriteColor());
-				assertThat(receivedPojos.get(0).getName())
-						.isEqualTo(firstOutboundFoo.getName());
-				assertThat(receivedPojos.get(0).getFavoritePlace()).isEqualTo("NYC");
-
-				assertThat(receivedPojos.get(1)).isNotSameAs(firstOutboundUser2);
-				assertThat(receivedPojos.get(1).getFavoriteColor())
-						.isEqualTo(firstOutboundUser2.getFavoriteColor());
-				assertThat(receivedPojos.get(1).getName())
-						.isEqualTo(firstOutboundUser2.getName());
-				assertThat(receivedPojos.get(1).getFavoritePlace()).isEqualTo("Boston");
-
-				assertThat(receivedPojos.get(2)).isNotSameAs(secondBarOutboundPojo);
-				assertThat(receivedPojos.get(2).getFavoriteColor())
-						.isEqualTo(secondBarOutboundPojo.getFavoriteColor());
-				assertThat(receivedPojos.get(2).getName())
-						.isEqualTo(secondBarOutboundPojo.getName());
-				assertThat(receivedPojos.get(2).getFavoritePlace())
-						.isEqualTo(secondBarOutboundPojo.getFavoritePlace());
-
-				sinkContext.close();
-				barSourceContext.close();
-				sourceContext.close();
-				schemaRegistryServerContext.close();
+		@Bean
+		@StreamMessageConverter
+		AvroSchemaRegistryClientMessageConverter avroSchemaRegistryClientMessageConverter() {
+			return new AvroSchemaRegistryClientMessageConverter(
+					new DefaultSchemaRegistryClient(), new NoOpCacheManager());
 		}
 
-		@Test
-		public void testSchemaImportConfiguration() throws Exception{
-				final String[] args = { "--server.port=0", "--spring.jmx.enabled=false",
-						"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true",
-						"--spring.cloud.stream.bindings.output.contentType=application/*+avro",
-						"--spring.cloud.stream.bindings.output.destination=test",
-						"--spring.cloud.stream.bindings.schema-registry-client.endpoint=http://localhost:8990",
-						"--spring.cloud.stream.schema.avro.schema-locations=classpath:schemas/Command.avsc",
-						"--spring.cloud.stream.schema.avro.schema-imports=classpath:schemas/imports/Sms.avsc, classpath:schemas/imports/Email.avsc, classpath:schemas/imports/PushNotification.avsc" };
-
-				final ConfigurableApplicationContext sourceContext = SpringApplication
-						.run(AvroSourceApplication.class, args);
-				final ConfigurableApplicationContext sinkContext = SpringApplication
-						.run(CommandSinkApplication.class, args);
-				final Source barSource = sourceContext.getBean(Source.class);
-				final Command notification = notification();
-				barSource.output()
-						.send(MessageBuilder.withPayload(notification).build());
-				final MessageCollector barSourceMessageCollector = sourceContext
-						.getBean(MessageCollector.class);
-				final Message outboundMessage = barSourceMessageCollector
-						.forChannel(barSource.output()).poll(1000, TimeUnit.MILLISECONDS);
-				assertThat(outboundMessage).isNotNull();
-				Sink sink = sinkContext.getBean(Sink.class);
-				sink.input().send(outboundMessage);
-				List receivedPojos = sinkContext
-						.getBean(CommandSinkApplication.class).receivedPojos;
-
-				assertThat(receivedPojos).hasSize(1);
-				assertThat(receivedPojos.get(0)).isEqualTo(notification);
-
+		@Bean
+		ServletWebServerFactory servletWebServerFactory() {
+			return new TomcatServletWebServerFactory();
 		}
 
-		@Test
-		public void testNoCacheConfiguration() {
-				ConfigurableApplicationContext sourceContext = SpringApplication
-						.run(NoCacheConfiguration.class,
-								"--spring.main.web-environment=false");
-				AvroSchemaRegistryClientMessageConverter converter = sourceContext
-						.getBean(AvroSchemaRegistryClientMessageConverter.class);
-				DirectFieldAccessor accessor = new DirectFieldAccessor(converter);
-				assertThat(accessor.getPropertyValue("cacheManager"))
-						.isInstanceOf(NoOpCacheManager.class);
-		}
+	}
 
-		@EnableBinding(Source.class)
-		@EnableAutoConfiguration
-		@EnableSchemaRegistryClient
-		public static class AvroSourceApplication {
-
-		}
-
-		@EnableBinding(Sink.class)
-		@EnableAutoConfiguration
-		@EnableSchemaRegistryClient
-		public static class AvroSinkApplication {
-
-				public List receivedPojos = new ArrayList<>();
-
-				@StreamListener(Sink.INPUT)
-				public void listen(User2 fooPojo) {
-						receivedPojos.add(fooPojo);
-				}
-
-		}
-
-		@EnableBinding(Sink.class)
-		@EnableAutoConfiguration
-		@EnableSchemaRegistryClient
-		public static class CommandSinkApplication {
-
-				public List receivedPojos = new ArrayList<>();
-
-				@StreamListener(Sink.INPUT)
-				public void listen(Command fooPojo) {
-						receivedPojos.add(fooPojo);
-				}
-
-		}
-
-		@Configuration
-		public static class NoCacheConfiguration {
-
-				@Bean
-				@StreamMessageConverter
-				AvroSchemaRegistryClientMessageConverter avroSchemaRegistryClientMessageConverter() {
-						return new AvroSchemaRegistryClientMessageConverter(
-								new DefaultSchemaRegistryClient(),
-								new NoOpCacheManager());
-				}
-
-				@Bean
-				ServletWebServerFactory servletWebServerFactory() {
-						return new TomcatServletWebServerFactory();
-				}
-		}
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroStubSchemaRegistryClientMessageConverterTests.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroStubSchemaRegistryClientMessageConverterTests.java
index ee809a5ff..f910370fe 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroStubSchemaRegistryClientMessageConverterTests.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/AvroStubSchemaRegistryClientMessageConverterTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,9 +47,8 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
 
 	@Test
 	public void testSendMessage() throws Exception {
-		ConfigurableApplicationContext sourceContext = SpringApplication.run(AvroSourceApplication.class,
-				"--server.port=0",
-				"--debug",
+		ConfigurableApplicationContext sourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0", "--debug",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.output.contentType=application/*+avro",
 				"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
@@ -58,12 +57,13 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
 		firstOutboundFoo.setFavoriteColor("foo" + UUID.randomUUID().toString());
 		firstOutboundFoo.setName("foo" + UUID.randomUUID().toString());
 		source.output().send(MessageBuilder.withPayload(firstOutboundFoo).build());
-		MessageCollector sourceMessageCollector = sourceContext.getBean(MessageCollector.class);
-		Message outboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		MessageCollector sourceMessageCollector = sourceContext
+				.getBean(MessageCollector.class);
+		Message outboundMessage = sourceMessageCollector.forChannel(source.output())
+				.poll(1000, TimeUnit.MILLISECONDS);
 
-		ConfigurableApplicationContext barSourceContext = SpringApplication.run(AvroSourceApplication.class,
-				"--server.port=0",
+		ConfigurableApplicationContext barSourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0",
 				"--spring.jmx.enabled=false",
 				"--spring.cloud.stream.bindings.output.contentType=application/vnd.user1.v1+avro",
 				"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
@@ -72,9 +72,10 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
 		firstOutboundUser2.setFavoriteColor("foo" + UUID.randomUUID().toString());
 		firstOutboundUser2.setName("foo" + UUID.randomUUID().toString());
 		barSource.output().send(MessageBuilder.withPayload(firstOutboundUser2).build());
-		MessageCollector barSourceMessageCollector = barSourceContext.getBean(MessageCollector.class);
-		Message barOutboundMessage = barSourceMessageCollector.forChannel(barSource.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		MessageCollector barSourceMessageCollector = barSourceContext
+				.getBean(MessageCollector.class);
+		Message barOutboundMessage = barSourceMessageCollector
+				.forChannel(barSource.output()).poll(1000, TimeUnit.MILLISECONDS);
 
 		assertThat(barOutboundMessage).isNotNull();
 
@@ -82,31 +83,39 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
 		secondBarOutboundPojo.setFavoriteColor("foo" + UUID.randomUUID().toString());
 		secondBarOutboundPojo.setName("foo" + UUID.randomUUID().toString());
 		source.output().send(MessageBuilder.withPayload(secondBarOutboundPojo).build());
-		Message secondBarOutboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
-				TimeUnit.MILLISECONDS);
+		Message secondBarOutboundMessage = sourceMessageCollector
+				.forChannel(source.output()).poll(1000, TimeUnit.MILLISECONDS);
 
-		ConfigurableApplicationContext sinkContext = SpringApplication.run(AvroSinkApplication.class,
-				"--server.port=0", "--spring.jmx.enabled=false");
+		ConfigurableApplicationContext sinkContext = SpringApplication.run(
+				AvroSinkApplication.class, "--server.port=0",
+				"--spring.jmx.enabled=false");
 		Sink sink = sinkContext.getBean(Sink.class);
 		sink.input().send(outboundMessage);
 		sink.input().send(barOutboundMessage);
 		sink.input().send(secondBarOutboundMessage);
-		List receivedPojos = sinkContext.getBean(AvroSinkApplication.class).receivedPojos;
+		List receivedPojos = sinkContext
+				.getBean(AvroSinkApplication.class).receivedPojos;
 		assertThat(receivedPojos).hasSize(3);
 		assertThat(receivedPojos.get(0)).isNotSameAs(firstOutboundFoo);
-		assertThat(receivedPojos.get(0).getFavoriteColor()).isEqualTo(firstOutboundFoo.getFavoriteColor());
+		assertThat(receivedPojos.get(0).getFavoriteColor())
+				.isEqualTo(firstOutboundFoo.getFavoriteColor());
 		assertThat(receivedPojos.get(0).getName()).isEqualTo(firstOutboundFoo.getName());
 		assertThat(receivedPojos.get(0).getFavoritePlace()).isEqualTo("NYC");
 
 		assertThat(receivedPojos.get(1)).isNotSameAs(firstOutboundUser2);
-		assertThat(receivedPojos.get(1).getFavoriteColor()).isEqualTo(firstOutboundUser2.getFavoriteColor());
-		assertThat(receivedPojos.get(1).getName()).isEqualTo(firstOutboundUser2.getName());
+		assertThat(receivedPojos.get(1).getFavoriteColor())
+				.isEqualTo(firstOutboundUser2.getFavoriteColor());
+		assertThat(receivedPojos.get(1).getName())
+				.isEqualTo(firstOutboundUser2.getName());
 		assertThat(receivedPojos.get(1).getFavoritePlace()).isEqualTo("Boston");
 
 		assertThat(receivedPojos.get(2)).isNotSameAs(secondBarOutboundPojo);
-		assertThat(receivedPojos.get(2).getFavoriteColor()).isEqualTo(secondBarOutboundPojo.getFavoriteColor());
-		assertThat(receivedPojos.get(2).getName()).isEqualTo(secondBarOutboundPojo.getName());
-		assertThat(receivedPojos.get(2).getFavoritePlace()).isEqualTo(secondBarOutboundPojo.getFavoritePlace());
+		assertThat(receivedPojos.get(2).getFavoriteColor())
+				.isEqualTo(secondBarOutboundPojo.getFavoriteColor());
+		assertThat(receivedPojos.get(2).getName())
+				.isEqualTo(secondBarOutboundPojo.getName());
+		assertThat(receivedPojos.get(2).getFavoritePlace())
+				.isEqualTo(secondBarOutboundPojo.getFavoritePlace());
 
 		sourceContext.close();
 	}
@@ -119,6 +128,7 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
 		public SchemaRegistryClient schemaRegistryClient() {
 			return stubSchemaRegistryClient;
 		}
+
 	}
 
 	@EnableBinding(Sink.class)
@@ -129,7 +139,7 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
 
 		@StreamListener(Sink.INPUT)
 		public void listen(User2 fooPojo) {
-			receivedPojos.add(fooPojo);
+			this.receivedPojos.add(fooPojo);
 		}
 
 		@Bean
@@ -138,4 +148,5 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
 		}
 
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/CustomSubjectNamingStrategy.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/CustomSubjectNamingStrategy.java
index e165cb059..71a92a041 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/CustomSubjectNamingStrategy.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/CustomSubjectNamingStrategy.java
@@ -32,4 +32,5 @@ class CustomSubjectNamingStrategy implements SubjectNamingStrategy {
 	public String toSubject(Schema schema) {
 		return schema.getFullName();
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/StubSchemaRegistryClient.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/StubSchemaRegistryClient.java
index 47995b8f0..ac9518dfd 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/StubSchemaRegistryClient.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/StubSchemaRegistryClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -39,12 +39,14 @@ public class StubSchemaRegistryClient implements SchemaRegistryClient {
 	private final Map> storedSchemas = new HashMap<>();
 
 	@Override
-	public SchemaRegistrationResponse register(String subject, String format, String schema) {
+	public SchemaRegistrationResponse register(String subject, String format,
+			String schema) {
 		if (!this.storedSchemas.containsKey(subject)) {
 			this.storedSchemas.put(subject, new TreeMap());
 		}
 		Map schemaVersions = this.storedSchemas.get(subject);
-		for (Map.Entry integerSchemaEntry : schemaVersions.entrySet()) {
+		for (Map.Entry integerSchemaEntry : schemaVersions
+				.entrySet()) {
 
 			if (integerSchemaEntry.getValue().getSchema().equals(schema)) {
 				SchemaRegistrationResponse schemaRegistrationResponse = new SchemaRegistrationResponse();
@@ -60,24 +62,27 @@ public class StubSchemaRegistryClient implements SchemaRegistryClient {
 		schemaVersions.put(nextVersion, new SchemaWithId(id, schema));
 		SchemaRegistrationResponse schemaRegistrationResponse = new SchemaRegistrationResponse();
 		schemaRegistrationResponse.setId(this.index.getAndIncrement());
-		schemaRegistrationResponse.setSchemaReference(
-				new SchemaReference(subject, nextVersion, AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT));
+		schemaRegistrationResponse.setSchemaReference(new SchemaReference(subject,
+				nextVersion, AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT));
 		this.schemasById.put(id, schema);
 		return schemaRegistrationResponse;
 	}
 
 	@Override
 	public String fetch(SchemaReference schemaReference) {
-		if (!AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT.equals(schemaReference.getFormat())) {
+		if (!AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT
+				.equals(schemaReference.getFormat())) {
 			throw new IllegalArgumentException("Only 'avro' is supported by this client");
 		}
 		if (!this.storedSchemas.containsKey(schemaReference.getSubject())) {
 			throw new SchemaNotFoundException("Not found: " + schemaReference);
 		}
-		if (!this.storedSchemas.get(schemaReference.getSubject()).containsKey(schemaReference.getVersion())) {
+		if (!this.storedSchemas.get(schemaReference.getSubject())
+				.containsKey(schemaReference.getVersion())) {
 			throw new SchemaNotFoundException("Not found: " + schemaReference);
 		}
-		return this.storedSchemas.get(schemaReference.getSubject()).get(schemaReference.getVersion()).getSchema();
+		return this.storedSchemas.get(schemaReference.getSubject())
+				.get(schemaReference.getVersion()).getSchema();
 	}
 
 	@Override
@@ -103,6 +108,7 @@ public class StubSchemaRegistryClient implements SchemaRegistryClient {
 		public String getSchema() {
 			return this.schema;
 		}
+
 	}
 
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/SubjectNamingStrategyTest.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/SubjectNamingStrategyTest.java
index 467d23ce6..018617b99 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/SubjectNamingStrategyTest.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/SubjectNamingStrategyTest.java
@@ -44,13 +44,13 @@ public class SubjectNamingStrategyTest {
 
 	@Test
 	public void testCustomNamingStrategy() throws Exception {
-		ConfigurableApplicationContext sourceContext = SpringApplication.run(AvroSourceApplication.class,
-			"--server.port=0",
-			"--debug",
-			"--spring.jmx.enabled=false",
-			"--spring.cloud.stream.bindings.output.contentType=application/*+avro",
-			"--spring.cloud.stream.schema.avro.subjectNamingStrategy=org.springframework.cloud.schema.avro.CustomSubjectNamingStrategy",
-			"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
+		ConfigurableApplicationContext sourceContext = SpringApplication.run(
+				AvroSourceApplication.class, "--server.port=0", "--debug",
+				"--spring.jmx.enabled=false",
+				"--spring.cloud.stream.bindings.output.contentType=application/*+avro",
+				"--spring.cloud.stream.schema.avro.subjectNamingStrategy="
+						+ "org.springframework.cloud.schema.avro.CustomSubjectNamingStrategy",
+				"--spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled=true");
 
 		Source source = sourceContext.getBean(Source.class);
 		User1 user1 = new User1();
@@ -58,11 +58,13 @@ public class SubjectNamingStrategyTest {
 		user1.setName("foo" + UUID.randomUUID().toString());
 		source.output().send(MessageBuilder.withPayload(user1).build());
 
-		MessageCollector barSourceMessageCollector = sourceContext.getBean(MessageCollector.class);
-		Message message = barSourceMessageCollector.forChannel(source.output()).poll(1000, TimeUnit.MILLISECONDS);
+		MessageCollector barSourceMessageCollector = sourceContext
+				.getBean(MessageCollector.class);
+		Message message = barSourceMessageCollector.forChannel(source.output())
+				.poll(1000, TimeUnit.MILLISECONDS);
 
-		assertThat(message.getHeaders().get("contentType"))
-				.isEqualTo(MimeType.valueOf("application/vnd.org.springframework.cloud.schema.avro.User1.v1+avro"));
+		assertThat(message.getHeaders().get("contentType")).isEqualTo(MimeType.valueOf(
+				"application/vnd.org.springframework.cloud.schema.avro.User1.v1+avro"));
 	}
 
 	@EnableBinding(Source.class)
@@ -73,5 +75,7 @@ public class SubjectNamingStrategyTest {
 		public SchemaRegistryClient schemaRegistryClient() {
 			return stubSchemaRegistryClient;
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User1.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User1.java
index 6a2fa1cbd..d2512010a 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User1.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -54,4 +54,5 @@ public class User1 {
 	public void setFavoriteColor(String favoriteColor) {
 		this.favoriteColor = favoriteColor;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User2.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User2.java
index 422c4035e..c0903a98e 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User2.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/User2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -66,4 +66,5 @@ public class User2 {
 	public void setFavoritePlace(String favoritePlace) {
 		this.favoritePlace = favoritePlace;
 	}
+
 }
diff --git a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/client/ConfluentSchemaRegistryClientTests.java b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/client/ConfluentSchemaRegistryClientTests.java
index da5e10259..080e18834 100644
--- a/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/client/ConfluentSchemaRegistryClientTests.java
+++ b/spring-cloud-stream-schema/src/test/java/org/springframework/cloud/schema/avro/client/ConfluentSchemaRegistryClientTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
 
 package org.springframework.cloud.schema.avro.client;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -31,6 +30,7 @@ import org.springframework.test.web.client.MockRestServiceServer;
 import org.springframework.web.client.HttpStatusCodeException;
 import org.springframework.web.client.RestTemplate;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
@@ -38,122 +38,139 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
 import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
 
-
 /**
  * @author Vinicius Carvalho
  */
 public class ConfluentSchemaRegistryClientTests {
 
 	private RestTemplate restTemplate;
+
 	private MockRestServiceServer mockRestServiceServer;
 
 	@Before
-	public void setup(){
+	public void setup() {
 		this.restTemplate = new RestTemplate();
-		this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate);
+		this.mockRestServiceServer = MockRestServiceServer
+				.createServer(this.restTemplate);
 	}
 
 	@Test
-	public void registerSchema() throws Exception{
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user/versions"))
+	public void registerSchema() throws Exception {
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user/versions"))
 				.andExpect(method(HttpMethod.POST))
-				.andExpect(header("Content-Type","application/json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Content-Type", "application/json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withSuccess("{\"id\":101}", MediaType.APPLICATION_JSON));
 
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user"))
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user"))
 				.andExpect(method(HttpMethod.POST))
-				.andExpect(header("Content-Type","application/json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Content-Type", "application/json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withSuccess("{\"version\":1}", MediaType.APPLICATION_JSON));
 
-		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(this.restTemplate);
-		SchemaRegistrationResponse response = client.register("user","avro","{}");
-		Assert.assertEquals(1,response.getSchemaReference().getVersion());
-		Assert.assertEquals(101,response.getId());
+		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(
+				this.restTemplate);
+		SchemaRegistrationResponse response = client.register("user", "avro", "{}");
+		assertThat(response.getSchemaReference().getVersion()).isEqualTo(1);
+		assertThat(response.getId()).isEqualTo(101);
 		this.mockRestServiceServer.verify();
 	}
 
 	@Test(expected = RuntimeException.class)
 	public void registerWithInvalidJson() {
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user/versions"))
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user/versions"))
 				.andExpect(method(HttpMethod.POST))
-				.andExpect(header("Content-Type","application/json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Content-Type", "application/json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withBadRequest());
-		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(this.restTemplate);
-		SchemaRegistrationResponse response = client.register("user","avro","<>");
+		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(
+				this.restTemplate);
+		SchemaRegistrationResponse response = client.register("user", "avro", "<>");
 	}
 
 	@Test
 	public void registerIncompatibleSchema() {
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user/versions"))
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user/versions"))
 				.andExpect(method(HttpMethod.POST))
-				.andExpect(header("Content-Type","application/json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Content-Type", "application/json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withStatus(HttpStatus.CONFLICT));
-		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(this.restTemplate);
+		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(
+				this.restTemplate);
 		Exception expected = null;
 		try {
-			SchemaRegistrationResponse response = client.register("user","avro","{}");
+			SchemaRegistrationResponse response = client.register("user", "avro", "{}");
 		}
 		catch (Exception e) {
 			expected = e;
 		}
-		Assert.assertTrue(expected instanceof RuntimeException);
-		Assert.assertTrue(expected.getCause() instanceof HttpStatusCodeException);
+		assertThat(expected instanceof RuntimeException).isTrue();
+		assertThat(expected.getCause() instanceof HttpStatusCodeException).isTrue();
 		this.mockRestServiceServer.verify();
 	}
 
 	@Test
 	public void responseErrorFetch() {
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user/versions"))
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user/versions"))
 				.andExpect(method(HttpMethod.POST))
-				.andExpect(header("Content-Type","application/json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Content-Type", "application/json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withSuccess("{\"id\":101}", MediaType.APPLICATION_JSON));
 
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user"))
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user"))
 				.andExpect(method(HttpMethod.POST))
-				.andExpect(header("Content-Type","application/json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Content-Type", "application/json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withBadRequest());
-		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(this.restTemplate);
+		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(
+				this.restTemplate);
 		Exception expected = null;
 		try {
-			SchemaRegistrationResponse response = client.register("user","avro","{}");
+			SchemaRegistrationResponse response = client.register("user", "avro", "{}");
 		}
 		catch (Exception e) {
 			expected = e;
 		}
-		Assert.assertTrue(expected instanceof RuntimeException);
-		Assert.assertTrue(expected.getCause() instanceof HttpStatusCodeException);
+		assertThat(expected instanceof RuntimeException).isTrue();
+		assertThat(expected.getCause() instanceof HttpStatusCodeException).isTrue();
 		this.mockRestServiceServer.verify();
 	}
 
 	@Test
-	public void findByReference(){
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user/versions/1"))
+	public void findByReference() {
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user/versions/1"))
 				.andExpect(method(HttpMethod.GET))
-				.andExpect(header("Content-Type","application/vnd.schemaregistry.v1+json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(
+						header("Content-Type", "application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withSuccess("{\"schema\":\"\"}", MediaType.APPLICATION_JSON));
-		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(this.restTemplate);
-		SchemaReference reference = new SchemaReference("user",1,"avro");
+		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(
+				this.restTemplate);
+		SchemaReference reference = new SchemaReference("user", 1, "avro");
 		String schema = client.fetch(reference);
-		Assert.assertEquals("",schema);
+		assertThat(schema).isEqualTo("");
 		this.mockRestServiceServer.verify();
 	}
 
 	@Test(expected = SchemaNotFoundException.class)
-	public void schemaNotFound(){
-		this.mockRestServiceServer.expect(requestTo("http://localhost:8081/subjects/user/versions/1"))
+	public void schemaNotFound() {
+		this.mockRestServiceServer
+				.expect(requestTo("http://localhost:8081/subjects/user/versions/1"))
 				.andExpect(method(HttpMethod.GET))
-				.andExpect(header("Content-Type","application/vnd.schemaregistry.v1+json"))
-				.andExpect(header("Accept","application/vnd.schemaregistry.v1+json"))
+				.andExpect(
+						header("Content-Type", "application/vnd.schemaregistry.v1+json"))
+				.andExpect(header("Accept", "application/vnd.schemaregistry.v1+json"))
 				.andRespond(withStatus(HttpStatus.NOT_FOUND));
-		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(this.restTemplate);
-		SchemaReference reference = new SchemaReference("user",1,"avro");
+		ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(
+				this.restTemplate);
+		SchemaReference reference = new SchemaReference("user", 1, "avro");
 		String schema = client.fetch(reference);
 	}
 
diff --git a/spring-cloud-stream-schema/src/test/resources/schemas/Command.avsc b/spring-cloud-stream-schema/src/test/resources/schemas/Command.avsc
index 754067146..3cfc1d9ce 100644
--- a/spring-cloud-stream-schema/src/test/resources/schemas/Command.avsc
+++ b/spring-cloud-stream-schema/src/test/resources/schemas/Command.avsc
@@ -16,4 +16,4 @@
          "type":["Sms", "Email", "PushNotification"]
       }
    ]
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-stream-schema/src/test/resources/schemas/imports/Email.avsc b/spring-cloud-stream-schema/src/test/resources/schemas/imports/Email.avsc
index c7c68e736..2b24fc236 100644
--- a/spring-cloud-stream-schema/src/test/resources/schemas/imports/Email.avsc
+++ b/spring-cloud-stream-schema/src/test/resources/schemas/imports/Email.avsc
@@ -16,4 +16,4 @@
         "type":"string"
      }
  ]
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-stream-schema/src/test/resources/schemas/imports/PushNotification.avsc b/spring-cloud-stream-schema/src/test/resources/schemas/imports/PushNotification.avsc
index 66286b536..afded1f20 100644
--- a/spring-cloud-stream-schema/src/test/resources/schemas/imports/PushNotification.avsc
+++ b/spring-cloud-stream-schema/src/test/resources/schemas/imports/PushNotification.avsc
@@ -12,4 +12,4 @@
         "type":"string"
     }
  ]
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-stream-schema/src/test/resources/schemas/imports/Sms.avsc b/spring-cloud-stream-schema/src/test/resources/schemas/imports/Sms.avsc
index e306afcc0..90b7ced8c 100644
--- a/spring-cloud-stream-schema/src/test/resources/schemas/imports/Sms.avsc
+++ b/spring-cloud-stream-schema/src/test/resources/schemas/imports/Sms.avsc
@@ -11,4 +11,4 @@
         "type":"string"
         }
  ]
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-stream-schema/src/test/resources/schemas/status.avsc b/spring-cloud-stream-schema/src/test/resources/schemas/status.avsc
index 5b0383229..972a80c08 100644
--- a/spring-cloud-stream-schema/src/test/resources/schemas/status.avsc
+++ b/spring-cloud-stream-schema/src/test/resources/schemas/status.avsc
@@ -7,4 +7,4 @@
     {"name": "text", "type": "string"},
     {"name": "timestamp", "type": "long"}
   ]
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-stream-schema/src/test/resources/schemas/users_v1.schema b/spring-cloud-stream-schema/src/test/resources/schemas/users_v1.schema
index f5ef8c98d..662029a22 100644
--- a/spring-cloud-stream-schema/src/test/resources/schemas/users_v1.schema
+++ b/spring-cloud-stream-schema/src/test/resources/schemas/users_v1.schema
@@ -7,4 +7,4 @@
     {"name": "favoriteColor", "type": ["string", "null"]}
 
   ]
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-stream-schema/src/test/resources/schemas/users_v2.schema b/spring-cloud-stream-schema/src/test/resources/schemas/users_v2.schema
index 586a1ff47..1cb8c4130 100644
--- a/spring-cloud-stream-schema/src/test/resources/schemas/users_v2.schema
+++ b/spring-cloud-stream-schema/src/test/resources/schemas/users_v2.schema
@@ -7,4 +7,4 @@
     {"name": "favoriteColor", "type": ["string", "null"]},
     {"name": "favoritePlace", "type": ["string","null"], "default" : "NYC"}
   ]
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-stream-test-support-internal/pom.xml b/spring-cloud-stream-test-support-internal/pom.xml
index ea694c373..45137dbe8 100644
--- a/spring-cloud-stream-test-support-internal/pom.xml
+++ b/spring-cloud-stream-test-support-internal/pom.xml
@@ -1,5 +1,7 @@
 
-
+
 	4.0.0
 	
 		org.springframework.cloud
@@ -8,7 +10,8 @@
 	
 	spring-cloud-stream-test-support-internal
 	Set of classes and utility code that may assist in testing both
-	spring-cloud-stream itself, and also modules.
+		spring-cloud-stream itself, and also modules.
+	
 	
 		
 			junit
diff --git a/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java
index db462a801..d46a10dfc 100644
--- a/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java
+++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java
@@ -35,11 +35,15 @@ import static org.junit.Assert.fail;
  * skipped, depending on the value of system property
  * {@value #SCS_EXTERNAL_SERVERS_REQUIRED}.
  *
+ * @param  resource type
  * @author Eric Bottard
  * @author Gary Russell
  */
 public abstract class AbstractExternalResourceTestSupport implements TestRule {
 
+	/**
+	 * SCS external servers required environment variable.
+	 */
 	public static final String SCS_EXTERNAL_SERVERS_REQUIRED = "SCS_EXTERNAL_SERVERS_REQUIRED";
 
 	protected final Log logger = LogFactory.getLog(getClass());
@@ -76,7 +80,8 @@ public abstract class AbstractExternalResourceTestSupport implements TestRule
 						cleanupResource();
 					}
 					catch (Exception ignored) {
-						logger.warn("Exception while trying to cleanup proper resource",
+						AbstractExternalResourceTestSupport.this.logger.warn(
+								"Exception while trying to cleanup proper resource",
 								ignored);
 					}
 				}
@@ -88,18 +93,21 @@ public abstract class AbstractExternalResourceTestSupport implements TestRule
 	private Statement failOrSkip(final Exception e) {
 		String serversRequired = System.getenv(SCS_EXTERNAL_SERVERS_REQUIRED);
 		if ("true".equalsIgnoreCase(serversRequired)) {
-			logger.error(resourceDescription + " IS REQUIRED BUT NOT AVAILABLE", e);
-			fail(resourceDescription + " IS NOT AVAILABLE");
+			this.logger.error(this.resourceDescription + " IS REQUIRED BUT NOT AVAILABLE",
+					e);
+			fail(this.resourceDescription + " IS NOT AVAILABLE");
 			// Never reached, here to satisfy method signature
 			return null;
 		}
 		else {
-			logger.error(resourceDescription + " IS NOT AVAILABLE, SKIPPING TESTS", e);
+			this.logger.error(
+					this.resourceDescription + " IS NOT AVAILABLE, SKIPPING TESTS", e);
 			return new Statement() {
 
 				@Override
 				public void evaluate() throws Throwable {
-					Assume.assumeTrue("Skipping test due to " + resourceDescription
+					Assume.assumeTrue("Skipping test due to "
+							+ AbstractExternalResourceTestSupport.this.resourceDescription
 							+ " not being available " + e, false);
 				}
 			};
@@ -107,23 +115,23 @@ public abstract class AbstractExternalResourceTestSupport implements TestRule
 	}
 
 	private void maybeCleanup() {
-		if (resource != null) {
+		if (this.resource != null) {
 			try {
 				cleanupResource();
 			}
 			catch (Exception ignored) {
-				logger.warn("Exception while trying to cleanup failed resource", ignored);
+				this.logger.warn("Exception while trying to cleanup failed resource",
+						ignored);
 			}
 		}
 	}
 
 	public R getResource() {
-		return resource;
+		return this.resource;
 	}
 
 	/**
 	 * Perform cleanup of the {@link #resource} field, which is guaranteed to be non null.
-	 *
 	 * @throws Exception any exception thrown by this method will be logged and swallowed
 	 */
 	protected abstract void cleanupResource() throws Exception;
@@ -132,6 +140,7 @@ public abstract class AbstractExternalResourceTestSupport implements TestRule
 	 * Try to obtain and validate a resource. Implementors should either set the
 	 * {@link #resource} field with a valid resource and return normally, or throw an
 	 * exception.
+	 * @throws Exception when resource couldn't be obtained
 	 */
 	protected abstract void obtainResource() throws Exception;
 
diff --git a/spring-cloud-stream-test-support/pom.xml b/spring-cloud-stream-test-support/pom.xml
index 59500bf56..bbb7998bb 100644
--- a/spring-cloud-stream-test-support/pom.xml
+++ b/spring-cloud-stream-test-support/pom.xml
@@ -1,5 +1,7 @@
 
-
+
 	4.0.0
 	
 		org.springframework.cloud
@@ -7,7 +9,8 @@
 		2.1.1.BUILD-SNAPSHOT
 	
 	spring-cloud-stream-test-support
-	A set of classes to ease testing of Spring Cloud Stream modules.
+	A set of classes to ease testing of Spring Cloud Stream modules.
+	
 	
 		
 			org.springframework.boot
diff --git a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollector.java b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollector.java
index 41a9a19bc..2274f584d 100644
--- a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollector.java
+++ b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 the original author or authors.
+ * Copyright 2015-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,6 +31,9 @@ public interface MessageCollector {
 
 	/**
 	 * Obtain a queue that will receive messages sent to the given channel.
+	 * @param channel message channel
+	 * @return blocking queue for stored message
 	 */
 	BlockingQueue> forChannel(MessageChannel channel);
+
 }
diff --git a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollectorAutoConfiguration.java b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollectorAutoConfiguration.java
index 11031764b..c14041bce 100644
--- a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollectorAutoConfiguration.java
+++ b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/MessageCollectorAutoConfiguration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,7 +32,8 @@ public class MessageCollectorAutoConfiguration {
 
 	@Bean
 	public MessageCollector messageCollector(BinderFactory binderFactory) {
-		return ((TestSupportBinder) binderFactory.getBinder("test", MessageChannel.class)).messageCollector();
+		return ((TestSupportBinder) binderFactory.getBinder("test", MessageChannel.class))
+				.messageCollector();
 	}
 
 }
diff --git a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestBinderEnvironmentPostProcessor.java b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestBinderEnvironmentPostProcessor.java
index b8fca8ff4..a597d28b0 100644
--- a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestBinderEnvironmentPostProcessor.java
+++ b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestBinderEnvironmentPostProcessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,9 +33,12 @@ import org.springframework.core.env.MapPropertySource;
 public class TestBinderEnvironmentPostProcessor implements EnvironmentPostProcessor {
 
 	@Override
-	public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+	public void postProcessEnvironment(ConfigurableEnvironment environment,
+			SpringApplication application) {
 		Map propertiesToAdd = new HashMap<>();
 		propertiesToAdd.put("spring.cloud.stream.binders.test.defaultCandidate", "false");
-		environment.getPropertySources().addLast(new MapPropertySource("testBinderConfig", propertiesToAdd));
+		environment.getPropertySources()
+				.addLast(new MapPropertySource("testBinderConfig", propertiesToAdd));
 	}
+
 }
diff --git a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestSupportBinder.java b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestSupportBinder.java
index a1bcd915f..3edbf64e7 100644
--- a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestSupportBinder.java
+++ b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/binder/TestSupportBinder.java
@@ -64,15 +64,16 @@ import org.springframework.util.StringUtils;
  * @author Soby Chacko
  * @see MessageQueueMatcher
  */
-public class TestSupportBinder implements Binder {
+public class TestSupportBinder
+		implements Binder {
 
 	private final MessageCollectorImpl messageCollector = new MessageCollectorImpl();
 
 	private final ConcurrentMap messageChannels = new ConcurrentHashMap<>();
 
 	@Override
-	public Binding bindConsumer(String name, String group, MessageChannel inboundBindTarget,
-			ConsumerProperties properties) {
+	public Binding bindConsumer(String name, String group,
+			MessageChannel inboundBindTarget, ConsumerProperties properties) {
 		return new TestBinding(inboundBindTarget, null);
 	}
 
@@ -81,9 +82,10 @@ public class TestSupportBinder implements Binder bindProducer(String name, MessageChannel outboundBindTarget,
-			ProducerProperties properties) {
-		final BlockingQueue> queue = messageCollector.register(outboundBindTarget, properties.isUseNativeEncoding());
+	public Binding bindProducer(String name,
+			MessageChannel outboundBindTarget, ProducerProperties properties) {
+		final BlockingQueue> queue = this.messageCollector
+				.register(outboundBindTarget, properties.isUseNativeEncoding());
 		((SubscribableChannel) outboundBindTarget).subscribe(new MessageHandler() {
 			@Override
 			public void handleMessage(Message message) throws MessagingException {
@@ -91,11 +93,11 @@ public class TestSupportBinder implements Binder>> results = new HashMap<>();
 
-		private BlockingQueue> register(MessageChannel channel, boolean useNativeEncoding) {
-			// we need to add this interceptor to ensure MessageCollector's compatibility with
+		private BlockingQueue> register(MessageChannel channel,
+				boolean useNativeEncoding) {
+			// we need to add this interceptor to ensure MessageCollector's compatibility
+			// with
 			// previous versions of SCSt when native encoding is disabled.
 			if (!useNativeEncoding) {
-				((AbstractMessageChannel) channel).addInterceptor(new InboundMessageConvertingInterceptor());
+				((AbstractMessageChannel) channel)
+						.addInterceptor(new InboundMessageConvertingInterceptor());
 			}
 			LinkedBlockingDeque> result = new LinkedBlockingDeque<>();
-			Assert.isTrue(!results.containsKey(channel), "Channel [" + channel + "] was already bound");
-			results.put(channel, result);
+			Assert.isTrue(!this.results.containsKey(channel),
+					"Channel [" + channel + "] was already bound");
+			this.results.put(channel, result);
 			return result;
 		}
 
 		private void unregister(MessageChannel channel) {
-			Assert.notNull(results.remove(channel),
-					"Trying to unregister a mapping for an unknown channel [" + channel + "]");
+			Assert.notNull(this.results.remove(channel),
+					"Trying to unregister a mapping for an unknown channel [" + channel
+							+ "]");
 		}
 
 		@Override
 		public BlockingQueue> forChannel(MessageChannel channel) {
-			BlockingQueue> queue = results.get(channel);
-			Assert.notNull(queue, "Channel [" + channel + "] was not bound by " + TestSupportBinder.class);
+			BlockingQueue> queue = this.results.get(channel);
+			Assert.notNull(queue, "Channel [" + channel + "] was not bound by "
+					+ TestSupportBinder.class);
 			return queue;
 		}
+
 	}
 
 	/**
@@ -145,56 +154,80 @@ public class TestSupportBinder implements Binder preSend(Message message, MessageChannel channel) {
 			Class targetClass = null;
 			MessageConverter converter = null;
-			MimeType contentType = message.getHeaders().containsKey(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)
-						? MimeType.valueOf(message.getHeaders().get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE).toString())
-								: MimeType.valueOf(contentTypeResolver.resolve(message.getHeaders()).toString());
+			MimeType contentType = message.getHeaders()
+					.containsKey(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)
+							? MimeType.valueOf(message.getHeaders()
+									.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)
+									.toString())
+							: MimeType.valueOf(this.contentTypeResolver
+									.resolve(message.getHeaders()).toString());
 
-			if (contentType != null){
-				if (equalTypeAndSubType(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT, contentType) ||
-						equalTypeAndSubType(MessageConverterUtils.X_JAVA_OBJECT, contentType)) {
-					// for Java and Kryo de-serialization we need to reset the content type
-					message = MessageBuilder.fromMessage(message).setHeader(MessageHeaders.CONTENT_TYPE, contentType).build();
-					converter = equalTypeAndSubType(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT, contentType)
-							? converterFactory.getMessageConverterForType(contentType)
-									: converterFactory.getMessageConverterForAllRegistered();
+			if (contentType != null) {
+				if (equalTypeAndSubType(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT,
+						contentType)
+						|| equalTypeAndSubType(MessageConverterUtils.X_JAVA_OBJECT,
+								contentType)) {
+					// for Java and Kryo de-serialization we need to reset the content
+					// type
+					message = MessageBuilder.fromMessage(message)
+							.setHeader(MessageHeaders.CONTENT_TYPE, contentType).build();
+					converter = equalTypeAndSubType(
+							MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT, contentType)
+									? this.converterFactory
+											.getMessageConverterForType(contentType)
+									: this.converterFactory
+											.getMessageConverterForAllRegistered();
 					String targetClassName = contentType.getParameter("type");
 					if (StringUtils.hasText(targetClassName)) {
 						try {
-							targetClass = Class.forName(targetClassName, false, Thread.currentThread().getContextClassLoader());
+							targetClass = Class.forName(targetClassName, false,
+									Thread.currentThread().getContextClassLoader());
 						}
 						catch (Exception e) {
-							throw new IllegalStateException("Failed to determine class name for contentType: "
-									+ message.getHeaders().get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE), e);
+							throw new IllegalStateException(
+									"Failed to determine class name for contentType: "
+											+ message.getHeaders().get(
+													BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE),
+									e);
 						}
 					}
 				}
@@ -202,41 +235,41 @@ public class TestSupportBinder implements Binder binder() {
-		return messageChannelBinder;
+		return this.messageChannelBinder;
 	}
 
 }
diff --git a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcher.java b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcher.java
index 443cf7991..d26053349 100644
--- a/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcher.java
+++ b/spring-cloud-stream-test-support/src/main/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcher.java
@@ -57,6 +57,7 @@ import org.springframework.messaging.Message;
  * 
  * 

* + * @param return type * @author Eric Bottard * @author Janne Valkealahti */ @@ -72,7 +73,8 @@ public class MessageQueueMatcher extends BaseMatcher private Map>, T> actuallyReceived = new HashMap<>(); - public MessageQueueMatcher(Matcher delegate, long timeout, TimeUnit unit, Extractor, T> extractor) { + public MessageQueueMatcher(Matcher delegate, long timeout, TimeUnit unit, + Extractor, T> extractor) { this.delegate = delegate; this.timeout = timeout; this.unit = (unit != null ? unit : TimeUnit.SECONDS); @@ -80,7 +82,8 @@ public class MessageQueueMatcher extends BaseMatcher } @SuppressWarnings({ "unchecked", "rawtypes" }) - public static

MessageQueueMatcher

receivesMessageThat(Matcher> messageMatcher) { + public static

MessageQueueMatcher

receivesMessageThat( + Matcher> messageMatcher) { return new MessageQueueMatcher(messageMatcher, 5, TimeUnit.SECONDS, new Extractor, Message

>("a message that ") { @Override @@ -91,7 +94,8 @@ public class MessageQueueMatcher extends BaseMatcher } @SuppressWarnings({ "unchecked", "rawtypes" }) - public static

MessageQueueMatcher

receivesPayloadThat(Matcher

payloadMatcher) { + public static

MessageQueueMatcher

receivesPayloadThat( + Matcher

payloadMatcher) { return new MessageQueueMatcher(payloadMatcher, 5, TimeUnit.SECONDS, new Extractor, P>("a message whose payload ") { @Override @@ -107,10 +111,10 @@ public class MessageQueueMatcher extends BaseMatcher BlockingQueue> queue = (BlockingQueue>) item; Message received = null; try { - if (timeout > 0) { - received = queue.poll(timeout, unit); + if (this.timeout > 0) { + received = queue.poll(this.timeout, this.unit); } - else if (timeout == 0) { + else if (this.timeout == 0) { received = queue.poll(); } else { @@ -120,21 +124,22 @@ public class MessageQueueMatcher extends BaseMatcher catch (InterruptedException e) { return false; } - T unwrapped = extractor.apply(received); - actuallyReceived.put(queue, unwrapped); - return delegate.matches(unwrapped); + T unwrapped = this.extractor.apply(received); + this.actuallyReceived.put(queue, unwrapped); + return this.delegate.matches(unwrapped); } @Override public void describeMismatch(Object item, Description description) { @SuppressWarnings("unchecked") BlockingQueue> queue = (BlockingQueue>) item; - T value = actuallyReceived.get(queue); + T value = this.actuallyReceived.get(queue); if (value != null) { description.appendText("received: ").appendValue(value); } else { - description.appendText("timed out after " + timeout + " " + unit.name().toLowerCase()); + description.appendText("timed out after " + this.timeout + " " + + this.unit.name().toLowerCase()); } } @@ -152,14 +157,19 @@ public class MessageQueueMatcher extends BaseMatcher @Override public void describeTo(Description description) { - description.appendText("Channel to receive ").appendDescriptionOf(extractor).appendDescriptionOf(delegate); + description.appendText("Channel to receive ").appendDescriptionOf(this.extractor) + .appendDescriptionOf(this.delegate); } /** * A transformation to be applied to a received message before asserting, e.g. * to only inspect the payload. + * + * @param input type + * @param return type */ - public static abstract class Extractor implements Function, SelfDescribing { + public static abstract class Extractor + implements Function, SelfDescribing { private final String behaviorDescription; @@ -169,8 +179,9 @@ public class MessageQueueMatcher extends BaseMatcher @Override public void describeTo(Description description) { - description.appendText(behaviorDescription); + description.appendText(this.behaviorDescription); } + } } diff --git a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/bean/AggregateWithBeanTest.java b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/bean/AggregateWithBeanTest.java index b3121b682..9550a0c5a 100644 --- a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/bean/AggregateWithBeanTest.java +++ b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/bean/AggregateWithBeanTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,8 +44,9 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Marius Bogoevici */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = AggregateWithBeanTest.ChainedProcessors.class, properties = { "server.port=-1","--spring.cloud.stream.bindings.input.contentType=text/plain", - "--spring.cloud.stream.bindings.output.contentType=text/plain"}) +@SpringBootTest(classes = AggregateWithBeanTest.ChainedProcessors.class, properties = { + "server.port=-1", "--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.cloud.stream.bindings.output.contentType=text/plain" }) @Ignore public class AggregateWithBeanTest { @@ -58,10 +59,13 @@ public class AggregateWithBeanTest { @Test @SuppressWarnings("unchecked") public void testAggregateApplication() throws InterruptedException { - Processor uppercaseProcessor = aggregateApplication.getBinding(Processor.class, "upper"); - Processor suffixProcessor = aggregateApplication.getBinding(Processor.class, "suffix"); + Processor uppercaseProcessor = this.aggregateApplication + .getBinding(Processor.class, "upper"); + Processor suffixProcessor = this.aggregateApplication.getBinding(Processor.class, + "suffix"); uppercaseProcessor.input().send(MessageBuilder.withPayload("Hello").build()); - Message receivedMessage = (Message) messageCollector.forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS); + Message receivedMessage = (Message) this.messageCollector + .forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS); assertThat(receivedMessage).isNotNull(); assertThat(receivedMessage.getPayload()).isEqualTo("HELLO WORLD!"); } @@ -73,8 +77,10 @@ public class AggregateWithBeanTest { @Bean public AggregateApplication aggregateApplication() { return new AggregateApplicationBuilder().from(UppercaseProcessor.class) - .namespace("upper").to(SuffixProcessor.class).namespace("suffix").build(); + .namespace("upper").to(SuffixProcessor.class).namespace("suffix") + .build(); } + } @Configuration @@ -86,6 +92,7 @@ public class AggregateWithBeanTest { public String transform(String in) { return in.toUpperCase(); } + } @Configuration @@ -97,5 +104,7 @@ public class AggregateWithBeanTest { public String transform(String in) { return in + " WORLD!"; } + } + } diff --git a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/main/AggregateWithMainTest.java b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/main/AggregateWithMainTest.java index 9412e9acd..7f6f22cde 100644 --- a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/main/AggregateWithMainTest.java +++ b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/aggregate/main/AggregateWithMainTest.java @@ -48,17 +48,22 @@ public class AggregateWithMainTest { @Test public void testAggregateApplication() throws InterruptedException { // emulate a main method - ConfigurableApplicationContext context = new AggregateApplicationBuilder(MainConfiguration.class).web(false) - .from(UppercaseProcessor.class).namespace("upper") - .to(SuffixProcessor.class).namespace("suffix") - .run("--spring.cloud.stream.bindings.input.contentType=text/plain","--spring.cloud.stream.bindings.output.contentType=text/plain"); + ConfigurableApplicationContext context = new AggregateApplicationBuilder( + MainConfiguration.class).web(false).from(UppercaseProcessor.class) + .namespace("upper").to(SuffixProcessor.class).namespace("suffix") + .run("--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.cloud.stream.bindings.output.contentType=text/plain"); - AggregateApplication aggregateAccessor = context.getBean(AggregateApplication.class); + AggregateApplication aggregateAccessor = context + .getBean(AggregateApplication.class); MessageCollector messageCollector = context.getBean(MessageCollector.class); - Processor uppercaseProcessor = aggregateAccessor.getBinding(Processor.class, "upper"); - Processor suffixProcessor = aggregateAccessor.getBinding(Processor.class, "suffix"); + Processor uppercaseProcessor = aggregateAccessor.getBinding(Processor.class, + "upper"); + Processor suffixProcessor = aggregateAccessor.getBinding(Processor.class, + "suffix"); uppercaseProcessor.input().send(MessageBuilder.withPayload("Hello").build()); - Message receivedMessage = (Message) messageCollector.forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS); + Message receivedMessage = (Message) messageCollector + .forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS); assertThat(receivedMessage).isNotNull(); assertThat(receivedMessage.getPayload()).isEqualTo("HELLO WORLD!"); context.close(); diff --git a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/disable/AutoconfigurationDisabledTest.java b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/disable/AutoconfigurationDisabledTest.java index 9448b849a..f767aa2f6 100644 --- a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/disable/AutoconfigurationDisabledTest.java +++ b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/disable/AutoconfigurationDisabledTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -41,11 +41,9 @@ import static org.assertj.core.api.Assertions.assertThat; */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = AutoconfigurationDisabledTest.MyProcessor.class, properties = { - "server.port=-1", - "spring.cloud.stream.defaultBinder=test", + "server.port=-1", "spring.cloud.stream.defaultBinder=test", "--spring.cloud.stream.bindings.input.contentType=text/plain", - "--spring.cloud.stream.bindings.output.contentType=text/plain" -}) + "--spring.cloud.stream.bindings.output.contentType=text/plain" }) @DirtiesContext public class AutoconfigurationDisabledTest { @@ -58,9 +56,10 @@ public class AutoconfigurationDisabledTest { @SuppressWarnings("unchecked") @Test public void testAutoconfigurationDisabled() throws Exception { - processor.input().send(MessageBuilder.withPayload("Hello").build()); + this.processor.input().send(MessageBuilder.withPayload("Hello").build()); // Since the interaction is synchronous, the result should be immediate - Message response = (Message) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS); + Message response = (Message) this.messageCollector + .forChannel(this.processor.output()).poll(1000, TimeUnit.MILLISECONDS); assertThat(response).isNotNull(); assertThat(response.getPayload()).isEqualTo("Hello world"); } @@ -73,5 +72,7 @@ public class AutoconfigurationDisabledTest { public String transform(String in) { return in + " world"; } + } + } diff --git a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/example/ExampleTest.java b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/example/ExampleTest.java index adc1560df..a8db2e11d 100644 --- a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/example/ExampleTest.java +++ b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/example/ExampleTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. @@ -39,10 +39,11 @@ import static org.assertj.core.api.Assertions.assertThat; * correctly. */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = ExampleTest.MyProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE, - properties = { +// @checkstyle:off +@SpringBootTest(classes = ExampleTest.MyProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = { "--spring.cloud.stream.bindings.input.contentType=text/plain", - "--spring.cloud.stream.bindings.output.contentType=text/plain"}) + "--spring.cloud.stream.bindings.output.contentType=text/plain" }) +// @checkstyle:on @DirtiesContext public class ExampleTest { @@ -57,7 +58,8 @@ public class ExampleTest { public void testWiring() { Message message = new GenericMessage<>("hello"); this.processor.input().send(message); - Message received = (Message) this.messageCollector.forChannel(this.processor.output()).poll(); + Message received = (Message) this.messageCollector + .forChannel(this.processor.output()).poll(); assertThat(received.getPayload()).isEqualTo("hello world"); } @@ -69,6 +71,7 @@ public class ExampleTest { public String transform(String in) { return in + " world"; } + } } diff --git a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcherTest.java b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcherTest.java index 1adf733ef..5ebc2118f 100644 --- a/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcherTest.java +++ b/spring-cloud-stream-test-support/src/test/java/org/springframework/cloud/stream/test/matcher/MessageQueueMatcherTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,13 +44,14 @@ public class MessageQueueMatcherTest { @Test public void testTimeout() { Message msg = new GenericMessage<>("hello"); - MessageQueueMatcher matcher = MessageQueueMatcher.receivesMessageThat(is(msg)).within(2, - TimeUnit.MILLISECONDS); + MessageQueueMatcher matcher = MessageQueueMatcher.receivesMessageThat(is(msg)) + .within(2, TimeUnit.MILLISECONDS); boolean result = matcher.matches(this.queue); assertThat(result).isFalse(); matcher.describeMismatch(this.queue, this.description); - assertThat(this.description.toString()).isEqualTo("timed out after 2 milliseconds"); + assertThat(this.description.toString()) + .isEqualTo("timed out after 2 milliseconds"); } @Test @@ -76,16 +77,19 @@ public class MessageQueueMatcherTest { @Test public void testExtractor() { - Message msg = new GenericMessage<>("hello", Collections.singletonMap("foo", (Object) "bar")); + Message msg = new GenericMessage<>("hello", + Collections.singletonMap("foo", (Object) "bar")); - MessageQueueMatcher.Extractor, String> headerExtractor = new MessageQueueMatcher.Extractor, String>( + MessageQueueMatcher.Extractor, String> headerExtractor; + headerExtractor = new MessageQueueMatcher.Extractor, String>( "whose 'foo' header") { @Override public String apply(Message message) { return message.getHeaders().get("foo", String.class); } }; - MessageQueueMatcher matcher = new MessageQueueMatcher<>(is("bar"), -1, null, headerExtractor); + MessageQueueMatcher matcher = new MessageQueueMatcher<>(is("bar"), -1, null, + headerExtractor); this.queue.offer(msg); boolean result = matcher.matches(this.queue); assertThat(result); @@ -102,6 +106,8 @@ public class MessageQueueMatcherTest { Message msg = new GenericMessage<>("hello"); MessageQueueMatcher matcher = MessageQueueMatcher.receivesMessageThat(is(msg)); this.description.appendDescriptionOf(matcher); - assertThat(this.description.toString()).isEqualTo(("Channel to receive a message that is <" + msg + ">")); + assertThat(this.description.toString()) + .isEqualTo(("Channel to receive a message that is <" + msg + ">")); } + } diff --git a/spring-cloud-stream-tools/pom.xml b/spring-cloud-stream-tools/pom.xml deleted file mode 100644 index 97590bfce..000000000 --- a/spring-cloud-stream-tools/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - 4.0.0 - 2.1.1.BUILD-SNAPSHOT - - org.springframework.cloud - spring-cloud-build - 2.1.0.BUILD-SNAPSHOT - - - - spring-cloud-stream-tools - spring-cloud-stream-build-tools - Spring Cloud Stream Build Tools - - - 1.8 - - - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/libs-release-local - - false - - - - - - - diff --git a/spring-cloud-stream-tools/src/main/resources/checkstyle-header.txt b/spring-cloud-stream-tools/src/main/resources/checkstyle-header.txt deleted file mode 100644 index e2b6f5d33..000000000 --- a/spring-cloud-stream-tools/src/main/resources/checkstyle-header.txt +++ /dev/null @@ -1,17 +0,0 @@ -^\Q/*\E$ -^\Q * Copyright \E(20\d\d\-)?20\d\d\Q the original author or authors.\E$ -^\Q *\E$ -^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$ -^\Q * you may not use this file except in compliance with the License.\E$ -^\Q * You may obtain a copy of the License at\E$ -^\Q *\E$ -^\Q * http://www.apache.org/licenses/LICENSE-2.0\E$ -^\Q *\E$ -^\Q * Unless required by applicable law or agreed to in writing, software\E$ -^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$ -^\Q * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\E$ -^\Q * See the License for the specific language governing permissions and\E$ -^\Q * limitations under the License.\E$ -^\Q */\E$ -^$ -^.*$ diff --git a/spring-cloud-stream-tools/src/main/resources/checkstyle-suppressions.xml b/spring-cloud-stream-tools/src/main/resources/checkstyle-suppressions.xml deleted file mode 100644 index a5be3bd96..000000000 --- a/spring-cloud-stream-tools/src/main/resources/checkstyle-suppressions.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/spring-cloud-stream-tools/src/main/resources/checkstyle.xml b/spring-cloud-stream-tools/src/main/resources/checkstyle.xml deleted file mode 100644 index 393bfd3e6..000000000 --- a/spring-cloud-stream-tools/src/main/resources/checkstyle.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-cloud-stream/pom.xml b/spring-cloud-stream/pom.xml index 39aadefc8..8622dbd99 100644 --- a/spring-cloud-stream/pom.xml +++ b/spring-cloud-stream/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 spring-cloud-stream diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplication.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplication.java index ed64130e8..a67d1c504 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplication.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplication.java @@ -30,10 +30,11 @@ public interface AggregateApplication { * {@link org.springframework.cloud.stream.messaging.Source}, * {@link org.springframework.cloud.stream.messaging.Sink} or custom interface) from * the given namespace. - * * @param bindableType the bindable type * @param namespace the namespace * @param parameterized bindable type + * @return binding */ T getBinding(Class bindableType, String namespace); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationBuilder.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationBuilder.java index dfcd499d0..80be43c96 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationBuilder.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationBuilder.java @@ -105,6 +105,7 @@ public class AggregateApplicationBuilder implements AggregateApplication, /** * Adding auto configuration classes to parent sources excluding the configuration * classes related to binder/binding. + * @param sources sources to which parent sources will be added */ private void addParentSources(Object[] sources) { if (!this.parentSources.contains(ParentConfiguration.class)) { @@ -130,7 +131,6 @@ public class AggregateApplicationBuilder implements AggregateApplication, /** * Flag to explicitly request a web or non-web environment. - * * @param webEnvironment true if the application has a web environment * @return the AggregateApplicationBuilder being constructed * @see SpringApplicationBuilder#web(boolean) @@ -142,7 +142,6 @@ public class AggregateApplicationBuilder implements AggregateApplication, /** * Configures the headless attribute of the build application. - * * @param headless true if the application is headless * @return the AggregateApplicationBuilder being constructed * @see SpringApplicationBuilder#headless(boolean) @@ -165,12 +164,12 @@ public class AggregateApplicationBuilder implements AggregateApplication, @Override public T getBinding(Class bindableType, String namespace) { - if (parentContext == null) { + if (this.parentContext == null) { throw new IllegalStateException( "The aggregate application has not been started yet"); } try { - ChildContextHolder contextHolder = parentContext + ChildContextHolder contextHolder = this.parentContext .getBean(namespace + CHILD_CONTEXT_SUFFIX, ChildContextHolder.class); return contextHolder.getChildContext().getBean(bindableType); } @@ -190,15 +189,15 @@ public class AggregateApplicationBuilder implements AggregateApplication, this.parentArgs.addAll(Arrays.asList(parentArgs)); List> apps = new ArrayList<>(); if (this.sourceConfigurer != null) { - apps.add(sourceConfigurer); + apps.add(this.sourceConfigurer); } - if (!processorConfigurers.isEmpty()) { - for (ProcessorConfigurer processorConfigurer : processorConfigurers) { + if (!this.processorConfigurers.isEmpty()) { + for (ProcessorConfigurer processorConfigurer : this.processorConfigurers) { apps.add(processorConfigurer); } } if (this.sinkConfigurer != null) { - apps.add(sinkConfigurer); + apps.add(this.sinkConfigurer); } LinkedHashMap, String> appsToEmbed = new LinkedHashMap<>(); LinkedHashMap, String> appConfigurers = new LinkedHashMap<>(); @@ -211,7 +210,9 @@ public class AggregateApplicationBuilder implements AggregateApplication, // binder // org.springframework.cloud.stream.aggregation.AggregationTest$TestSource appConfigurer.namespace = AggregateApplicationUtils.getDefaultNamespace( - DOLLAR_ESCAPE_PATTERN.matcher(appConfigurer.getApp().getName()).replaceAll("."), i); + DOLLAR_ESCAPE_PATTERN.matcher(appConfigurer.getApp().getName()) + .replaceAll("."), + i); } appsToEmbed.put(appToEmbed, appConfigurer.namespace); appConfigurers.put(appConfigurer, appConfigurer.namespace); @@ -313,29 +314,42 @@ public class AggregateApplicationBuilder implements AggregateApplication, } public ConfigurableApplicationContext getChildContext() { - return childContext; + return this.childContext; } + } + /** + * Auto configuration for {@link SharedBindingTargetRegistry}. + */ @ImportAutoConfiguration(ChannelBindingAutoConfiguration.class) @EnableBinding public static class ParentConfiguration { + @Bean @ConditionalOnMissingBean(SharedBindingTargetRegistry.class) public SharedBindingTargetRegistry sharedBindingTargetRegistry() { return new SharedBindingTargetRegistry(); } + } + /** + * Auto configuration for {@link EndpointAutoConfiguration}. + */ @ImportAutoConfiguration(EndpointAutoConfiguration.class) public static class ParentActuatorConfiguration { + } + /** + * Source configurer. + */ public class SourceConfigurer extends AppConfigurer { public SourceConfigurer(Class app) { this.app = app; - sourceConfigurer = this; + AggregateApplicationBuilder.this.sourceConfigurer = this; } public SinkConfigurer to(Class sink) { @@ -348,20 +362,26 @@ public class AggregateApplicationBuilder implements AggregateApplication, } + /** + * Sink configurer. + */ public class SinkConfigurer extends AppConfigurer { public SinkConfigurer(Class app) { this.app = app; - sinkConfigurer = this; + AggregateApplicationBuilder.this.sinkConfigurer = this; } } + /** + * Processor configurer. + */ public class ProcessorConfigurer extends AppConfigurer { public ProcessorConfigurer(Class app) { this.app = app; - processorConfigurers.add(this); + AggregateApplicationBuilder.this.processorConfigurers.add(this); } public SinkConfigurer to(Class sink) { @@ -374,6 +394,11 @@ public class AggregateApplicationBuilder implements AggregateApplication, } + /** + * Abstraction over configuration of an applciation. + * + * @param type of a configurer + */ public abstract class AppConfigurer> { Class app; @@ -416,7 +441,7 @@ public class AggregateApplicationBuilder implements AggregateApplication, } public ConfigurableApplicationContext run(String... args) { - return applicationBuilder.run(args); + return AggregateApplicationBuilder.this.applicationBuilder.run(args); } void embed() { @@ -446,7 +471,7 @@ public class AggregateApplicationBuilder implements AggregateApplication, } public AggregateApplication build() { - return applicationBuilder; + return AggregateApplicationBuilder.this.applicationBuilder; } public String[] getArgs() { @@ -456,6 +481,7 @@ public class AggregateApplicationBuilder implements AggregateApplication, public String getNamespace() { return this.namespace; } + } private final class ChildContextBuilder { diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationUtils.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationUtils.java index ca2c5d91a..3f9b53958 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationUtils.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/AggregateApplicationUtils.java @@ -61,8 +61,8 @@ abstract class AggregateApplicationUtils { protected static SpringApplicationBuilder embedApp( ConfigurableApplicationContext parentContext, String namespace, Class app) { - return new SpringApplicationBuilder(app).web(WebApplicationType.NONE).main(app).bannerMode(Mode.OFF) - .properties("spring.jmx.default-domain=" + namespace) + return new SpringApplicationBuilder(app).web(WebApplicationType.NONE).main(app) + .bannerMode(Mode.OFF).properties("spring.jmx.default-domain=" + namespace) .properties( InternalPropertyNames.NAMESPACE_PROPERTY_NAME + "=" + namespace) .registerShutdownHook(false).parent(parentContext); @@ -81,8 +81,8 @@ abstract class AggregateApplicationUtils { } sharedChannel = new DirectChannel(); if (i < appsWithNamespace.size() - 1) { - sharedBindingTargetRegistry.register(namespace + "." + OUTPUT_BINDING_NAME, - sharedChannel); + sharedBindingTargetRegistry + .register(namespace + "." + OUTPUT_BINDING_NAME, sharedChannel); } i++; } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedBindingTargetRegistry.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedBindingTargetRegistry.java index 1d1071e2c..a26515a35 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedBindingTargetRegistry.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedBindingTargetRegistry.java @@ -28,7 +28,8 @@ import java.util.concurrent.ConcurrentSkipListMap; */ public class SharedBindingTargetRegistry { - private Map sharedBindingTargets = new ConcurrentSkipListMap<>(String.CASE_INSENSITIVE_ORDER); + private Map sharedBindingTargets = new ConcurrentSkipListMap<>( + String.CASE_INSENSITIVE_ORDER); @SuppressWarnings("unchecked") public T get(String id, Class bindingTargetType) { @@ -37,8 +38,9 @@ public class SharedBindingTargetRegistry { return null; } if (!bindingTargetType.isAssignableFrom(sharedBindingTarget.getClass())) { - throw new IllegalArgumentException("A shared " + bindingTargetType.getName() + " was requested, " - + "but the existing shared target with id '" + id + "' is a " + sharedBindingTarget.getClass()); + throw new IllegalArgumentException("A shared " + bindingTargetType.getName() + + " was requested, " + "but the existing shared target with id '" + id + + "' is a " + sharedBindingTarget.getClass()); } else { return (T) sharedBindingTarget; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedChannelRegistry.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedChannelRegistry.java index 97ba8c683..515dd2734 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedChannelRegistry.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/aggregate/SharedChannelRegistry.java @@ -36,7 +36,8 @@ public class SharedChannelRegistry { private final SharedBindingTargetRegistry sharedBindingTargetRegistry; - public SharedChannelRegistry(SharedBindingTargetRegistry sharedBindingTargetRegistry) { + public SharedChannelRegistry( + SharedBindingTargetRegistry sharedBindingTargetRegistry) { this.sharedBindingTargetRegistry = sharedBindingTargetRegistry; } @@ -49,14 +50,18 @@ public class SharedChannelRegistry { } public Map getAll() { - Map sharedBindingTargets = this.sharedBindingTargetRegistry.getAll(); + Map sharedBindingTargets = this.sharedBindingTargetRegistry + .getAll(); Map sharedMessageChannels = new HashMap<>(); - for (Map.Entry sharedBindingTargetEntry : sharedBindingTargets.entrySet()) { - if (MessageChannel.class.isAssignableFrom(sharedBindingTargetEntry.getValue().getClass())) { + for (Map.Entry sharedBindingTargetEntry : sharedBindingTargets + .entrySet()) { + if (MessageChannel.class + .isAssignableFrom(sharedBindingTargetEntry.getValue().getClass())) { sharedMessageChannels.put(sharedBindingTargetEntry.getKey(), (MessageChannel) sharedBindingTargetEntry.getValue()); } } return Collections.unmodifiableMap(sharedMessageChannels); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Bindings.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Bindings.java index 3c584a77b..b1b71fa2f 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Bindings.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Bindings.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/EnableBinding.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/EnableBinding.java index 1e818f9b5..a5260c39a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/EnableBinding.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/EnableBinding.java @@ -43,13 +43,14 @@ import org.springframework.integration.config.EnableIntegration; @Documented @Inherited @Configuration -@Import({ BindingBeansRegistrar.class, BinderFactoryConfiguration.class}) +@Import({ BindingBeansRegistrar.class, BinderFactoryConfiguration.class }) @EnableIntegration public @interface EnableBinding { /** * A list of interfaces having methods annotated with {@link Input} and/or * {@link Output} to indicate binding targets. + * @return list of interfaces */ Class[] value() default {}; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Input.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Input.java index 3c6026f8b..29dce09cf 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Input.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Input.java @@ -33,17 +33,16 @@ import org.springframework.beans.factory.annotation.Qualifier; */ @Qualifier -@Target({ ElementType.FIELD, ElementType.METHOD, - ElementType.ANNOTATION_TYPE, ElementType.PARAMETER }) +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE, + ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Input { /** - * Specify the binding target name; - * used as a bean name for binding target - * and as a destination name by default. + * Specify the binding target name; used as a bean name for binding target and as a + * destination name by default. * @return the binding target name */ String value() default ""; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Output.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Output.java index d18a1f929..24890f84c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Output.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/Output.java @@ -34,17 +34,16 @@ import org.springframework.beans.factory.annotation.Qualifier; */ @Qualifier -@Target({ ElementType.FIELD, ElementType.METHOD, - ElementType.ANNOTATION_TYPE, ElementType.PARAMETER }) +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE, + ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Output { /** - * Specify the binding target name; - * used as a bean name for binding target - * and as a destination name by default. + * Specify the binding target name; used as a bean name for binding target and as a + * destination name by default. * @return the binding target name */ String value() default ""; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamListener.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamListener.java index 75d274b9a..0067a1381 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamListener.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamListener.java @@ -55,16 +55,16 @@ import org.springframework.messaging.handler.annotation.MessageMapping; * {@link StreamListener} and using * {@link org.springframework.messaging.handler.annotation.SendTo} on the method for * the return type (if applicable). In this case the method must have exactly one - * parameter, corresponding to an input. + * parameter, corresponding to an input. * * * An example of declarative method signature using the former idiom is as follows: * *

  * @StreamListener
- * public @Output("joined") Flux join(
- *       @Input("input1") Flux input1,
- *       @Input("input2") Flux input2) {
+ * public @Output("joined") Flux<String> join(
+ *       @Input("input1") Flux<String> input1,
+ *       @Input("input2") Flux<String> input2) {
  *   // ... join the two input streams via functional operators
  * }
  * 
@@ -74,7 +74,7 @@ import org.springframework.messaging.handler.annotation.MessageMapping; *
  * @StreamListener(Processor.INPUT)
  * @SendTo(Processor.OUTPUT)
- * public Flux convert(Flux input) {
+ * public Flux<String> convert(Flux<String> input) {
  *     return input.map(String::toUppercase);
  * }
  * 
@@ -159,12 +159,13 @@ public @interface StreamListener { * The expression is evaluated during application initialization, and not for each * individual message. * - * Prior to version 1.3.0, the default value used to be "false" and headers were - * not propagated by default. + * Prior to version 1.3.0, the default value used to be "false" and headers were not + * propagated by default. * * Starting with version 1.3.0, the default value is "true". * * @since 1.2.3 + * @return {@link Boolean} in a String format */ String copyHeaders() default "true"; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamMessageConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamMessageConverter.java index dd31a18ca..3c1b309f3 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamMessageConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamMessageConverter.java @@ -26,7 +26,8 @@ import org.springframework.beans.factory.annotation.Qualifier; /** * Marker to tag {@link org.springframework.messaging.converter.MessageConverter} beans - * that will be added to the {@link org.springframework.cloud.stream.converter.CompositeMessageConverterFactory}. + * that will be added to the + * {@link org.springframework.cloud.stream.converter.CompositeMessageConverterFactory}. * * @author Vinicius Carvalho * @author Arten Bilan diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamRetryTemplate.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamRetryTemplate.java index 6c8f042ec..7467afa88 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamRetryTemplate.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/annotation/StreamRetryTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -27,8 +27,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.retry.support.RetryTemplate; /** - * Marker to tag an instance of {@link RetryTemplate} to be used by the binder. - * This annotation is also a @Bean to simplify configuration (see below) + * Marker to tag an instance of {@link RetryTemplate} to be used by the binder. This + * annotation is also a @Bean to simplify configuration (see below) * *
  * @StreamRetryTemplate
@@ -41,7 +41,7 @@ import org.springframework.retry.support.RetryTemplate;
  * @since 2.1
  */
 
-@Target({ElementType.FIELD,ElementType.METHOD})
+@Target({ ElementType.FIELD, ElementType.METHOD })
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Bean
diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java
index 60daa46ec..c8a2871ab 100644
--- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java
+++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractBinder.java
@@ -41,6 +41,9 @@ import org.springframework.util.StringUtils;
 /**
  * Base class for {@link Binder} implementations.
  *
+ * @param  outbound bind target class
+ * @param  consumer properties class
+ * @param 

producer properties class * @author David Turanski * @author Gary Russell * @author Ilayaperumal Gopinathan @@ -51,7 +54,7 @@ import org.springframework.util.StringUtils; * @author Oleg Zhurakousky */ public abstract class AbstractBinder - implements ApplicationContextAware, InitializingBean, Binder { + implements ApplicationContextAware, InitializingBean, Binder { /** * The delimiter between a group and index when constructing a binder @@ -65,15 +68,16 @@ public abstract class AbstractBinder bindConsumer(String name, String group, T target, C properties) { + public final Binding bindConsumer(String name, String group, T target, + C properties) { if (StringUtils.isEmpty(group)) { - Assert.isTrue(!properties.isPartitioned(), "A consumer group is required for a partitioned subscription"); + Assert.isTrue(!properties.isPartitioned(), + "A consumer group is required for a partitioned subscription"); } return doBindConsumer(name, group, target, properties); } - protected abstract Binding doBindConsumer(String name, String group, T inputTarget, C properties); + protected abstract Binding doBindConsumer(String name, String group, T inputTarget, + C properties); @Override - public final Binding bindProducer(String name, T outboundBindTarget, P properties) { + public final Binding bindProducer(String name, T outboundBindTarget, + P properties) { return doBindProducer(name, outboundBindTarget, properties); } - protected abstract Binding doBindProducer(String name, T outboundBindTarget, P properties); + protected abstract Binding doBindProducer(String name, T outboundBindTarget, + P properties); /** * Construct a name comprised of the name and group. - * - * @param name the name. + * @param name the name. * @param group the group. * @return the constructed name. */ protected final String groupedName(String name, String group) { - return name + GROUP_INDEX_DELIMITER + (StringUtils.hasText(group) ? group : "default"); + return name + GROUP_INDEX_DELIMITER + + (StringUtils.hasText(group) ? group : "default"); } /** - * Deprecated as of v2.0. Doesn't do anything other then returns an instance - * of {@link MessageValues} built from {@link Message}. Remains primarily for - * backward compatibility and will be removed in the next major release. + * Deprecated as of v2.0. Doesn't do anything other then returns an instance of + * {@link MessageValues} built from {@link Message}. Remains primarily for backward + * compatibility and will be removed in the next major release. + * @param message message to serialize + * @return wrapped message */ @Deprecated protected final MessageValues serializePayloadIfNecessary(Message message) { @@ -163,18 +178,20 @@ public abstract class AbstractBinder - consumer properties type * @param

- producer properties type * @param - type which provides the consumer and producer properties + * @author Oleg Zhurakousky + * @since 2.1 */ public abstract class AbstractExtendedBindingProperties - implements ExtendedBindingProperties, ApplicationContextAware { + implements ExtendedBindingProperties, ApplicationContextAware { private final Map bindings = new HashMap<>(); @@ -61,18 +59,19 @@ public abstract class AbstractExtendedBindingProperties the consumer properties type * @param

the producer properties type - * + * @param the provisioning producer properties type * @author Marius Bogoevici * @author Ilayaperumal Gopinathan * @author Soby Chacko * @author Oleg Zhurakousky * @author Artem Bilan * @author Gary Russell - * * @since 1.1 */ +// @checkstyle:off public abstract class AbstractMessageChannelBinder> - extends AbstractBinder - implements PollableConsumerBinder, ApplicationEventPublisherAware { + extends AbstractBinder implements + PollableConsumerBinder, ApplicationEventPublisherAware { - private final EmbeddedHeadersChannelInterceptor embeddedHeadersChannelInterceptor = - new EmbeddedHeadersChannelInterceptor(this.logger); - - private final ObjectMapper objectMapper = new ObjectMapper(); + // @checkstyle:on /** * {@link ProvisioningProvider} delegated by the downstream binder implementations. */ protected final PP provisioningProvider; + // @checkstyle:off + private final EmbeddedHeadersChannelInterceptor embeddedHeadersChannelInterceptor = new EmbeddedHeadersChannelInterceptor( + this.logger); + + // @checkstyle:on + + private final ObjectMapper objectMapper = new ObjectMapper(); + /** - * Indicates which headers are to be embedded in the payload if - * a binding requires embedding headers. + * Indicates which headers are to be embedded in the payload if a binding requires + * embedding headers. */ private final String[] headersToEmbed; @@ -119,25 +124,29 @@ public abstract class AbstractMessageChannelBinder containerCustomizer) { + public AbstractMessageChannelBinder(String[] headersToEmbed, PP provisioningProvider, + ListenerContainerCustomizer containerCustomizer) { this.headersToEmbed = headersToEmbed == null ? new String[0] : headersToEmbed; this.provisioningProvider = provisioningProvider; - this.containerCustomizer = containerCustomizer == null ? (c, q, g) -> { } : containerCustomizer; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.applicationEventPublisher = applicationEventPublisher; + this.containerCustomizer = containerCustomizer == null ? (c, q, g) -> { + } : containerCustomizer; } protected ApplicationEventPublisher getApplicationEventPublisher() { return this.applicationEventPublisher; } + @Override + public void setApplicationEventPublisher( + ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } + @SuppressWarnings("unchecked") protected ListenerContainerCustomizer getContainerCustomizer() { return (ListenerContainerCustomizer) this.containerCustomizer; @@ -146,13 +155,13 @@ public abstract class AbstractMessageChannelBinder doBindProducer(final String destination, MessageChannel outputChannel, - final P producerProperties) throws BinderException { + public final Binding doBindProducer(final String destination, + MessageChannel outputChannel, final P producerProperties) + throws BinderException { Assert.isInstanceOf(SubscribableChannel.class, outputChannel, "Binding is supported only for SubscribableChannel instances"); final MessageHandler producerMessageHandler; final ProducerDestination producerDestination; try { - producerDestination = this.provisioningProvider.provisionProducerDestination(destination, - producerProperties); + producerDestination = this.provisioningProvider + .provisionProducerDestination(destination, producerProperties); SubscribableChannel errorChannel = producerProperties.isErrorChannelEnabled() ? registerErrorInfrastructure(producerDestination) : null; - producerMessageHandler = createProducerMessageHandler(producerDestination, producerProperties, - outputChannel, errorChannel); + producerMessageHandler = createProducerMessageHandler(producerDestination, + producerProperties, outputChannel, errorChannel); if (producerMessageHandler instanceof InitializingBean) { ((InitializingBean) producerMessageHandler).afterPropertiesSet(); } @@ -185,26 +195,30 @@ public abstract class AbstractMessageChannelBinder binding = new DefaultBinding(destination, outputChannel, - producerMessageHandler instanceof Lifecycle ? (Lifecycle) producerMessageHandler : null) { + Binding binding = new DefaultBinding(destination, + outputChannel, producerMessageHandler instanceof Lifecycle + ? (Lifecycle) producerMessageHandler : null) { @Override public Map getExtendedInfo() { @@ -237,8 +251,6 @@ public abstract class AbstractMessageChannelBinder * *

- * * @param destination the name of the target destination. * @param producerProperties the producer properties. * @param channel the channel to bind. * @param errorChannel the error channel (if enabled, otherwise null). If not null, - * the binder must wire this channel into the producer endpoint so that errors - * are forwarded to it. + * the binder must wire this channel into the producer endpoint so that errors are + * forwarded to it. * @return the message handler for sending data to the target middleware - * @throws Exception + * @throws Exception when producer messsage handler failed to be created */ protected MessageHandler createProducerMessageHandler(ProducerDestination destination, P producerProperties, MessageChannel channel, MessageChannel errorChannel) throws Exception { - return createProducerMessageHandler(destination, producerProperties, errorChannel); + return createProducerMessageHandler(destination, producerProperties, + errorChannel); } /** @@ -301,27 +314,26 @@ public abstract class AbstractMessageChannelBinder * *

- * * @param destination the name of the target destination * @param producerProperties the producer properties * @param errorChannel the error channel (if enabled, otherwise null). If not null, - * the binder must wire this channel into the producer endpoint so that errors - * are forwarded to it. + * the binder must wire this channel into the producer endpoint so that errors are + * forwarded to it. * @return the message handler for sending data to the target middleware - * @throws Exception + * @throws Exception upon failure to create the producer message handler */ - protected abstract MessageHandler createProducerMessageHandler(ProducerDestination destination, - P producerProperties, MessageChannel errorChannel) - throws Exception; + protected abstract MessageHandler createProducerMessageHandler( + ProducerDestination destination, P producerProperties, + MessageChannel errorChannel) throws Exception; /** * Invoked after the unbinding of a producer. Subclasses may override this to provide * their own logic for dealing with unbinding. - * * @param destination the bound destination * @param producerProperties the producer properties */ - protected void afterUnbindProducer(ProducerDestination destination, P producerProperties) { + protected void afterUnbindProducer(ProducerDestination destination, + P producerProperties) { } /** @@ -333,7 +345,6 @@ public abstract class AbstractMessageChannelBinder doBindConsumer(String name, String group, MessageChannel inputChannel, - final C properties) throws BinderException { + public final Binding doBindConsumer(String name, String group, + MessageChannel inputChannel, final C properties) throws BinderException { MessageProducer consumerEndpoint = null; try { - ConsumerDestination destination = this.provisioningProvider.provisionConsumerDestination(name, group, properties); + ConsumerDestination destination = this.provisioningProvider + .provisionConsumerDestination(name, group, properties); // the function support for the inbound channel is only for Sink if (shouldWireDunctionToChannel(false)) { - inputChannel = this.postProcessInboundChannelForFunction(inputChannel, (ConsumerProperties) properties); + inputChannel = this.postProcessInboundChannelForFunction(inputChannel, + (ConsumerProperties) properties); } if (HeaderMode.embeddedHeaders.equals(properties.getHeaderMode())) { enhanceMessageChannel(inputChannel); @@ -363,8 +376,9 @@ public abstract class AbstractMessageChannelBinder binding = new DefaultBinding(name, group, inputChannel, - consumerEndpoint instanceof Lifecycle ? (Lifecycle) consumerEndpoint : null) { + Binding binding = new DefaultBinding(name, + group, inputChannel, consumerEndpoint instanceof Lifecycle + ? (Lifecycle) consumerEndpoint : null) { @Override public Map getExtendedInfo() { @@ -384,11 +398,11 @@ public abstract class AbstractMessageChannelBinder> bindPollableConsumer(String name, String group, - final PollableSource inboundBindTarget, C properties) { + public Binding> bindPollableConsumer(String name, + String group, final PollableSource inboundBindTarget, + C properties) { Assert.isInstanceOf(DefaultPollableMessageSource.class, inboundBindTarget); DefaultPollableMessageSource bindingTarget = (DefaultPollableMessageSource) inboundBindTarget; - ConsumerDestination destination = this.provisioningProvider.provisionConsumerDestination(name, group, - properties); + ConsumerDestination destination = this.provisioningProvider + .provisionConsumerDestination(name, group, properties); if (HeaderMode.embeddedHeaders.equals(properties.getHeaderMode())) { bindingTarget.addInterceptor(0, this.embeddedHeadersChannelInterceptor); } - final PolledConsumerResources resources = createPolledConsumerResources(name, group, destination, properties); + final PolledConsumerResources resources = createPolledConsumerResources(name, + group, destination, properties); bindingTarget.setSource(resources.getSource()); if (resources.getErrorInfrastructure() != null) { if (resources.getErrorInfrastructure().getErrorChannel() != null) { - bindingTarget.setErrorChannel(resources.getErrorInfrastructure().getErrorChannel()); + bindingTarget.setErrorChannel( + resources.getErrorInfrastructure().getErrorChannel()); } ErrorMessageStrategy ems = getErrorMessageStrategy(); if (ems != null) { @@ -434,15 +452,16 @@ public abstract class AbstractMessageChannelBinder 1) { bindingTarget.setRetryTemplate(buildRetryTemplate(properties)); - bindingTarget.setRecoveryCallback( - getPolledConsumerRecoveryCallback(resources.getErrorInfrastructure(), properties)); + bindingTarget.setRecoveryCallback(getPolledConsumerRecoveryCallback( + resources.getErrorInfrastructure(), properties)); } postProcessPollableSource(bindingTarget); if (resources.getSource() instanceof Lifecycle) { - ((Lifecycle) resources.getSource()).start(); + ((Lifecycle) resources.getSource()).start(); } - Binding> binding = new DefaultBinding>(name, group, inboundBindTarget, - resources.getSource() instanceof Lifecycle ? (Lifecycle) resources.getSource() : null) { + Binding> binding = new DefaultBinding>( + name, group, inboundBindTarget, resources.getSource() instanceof Lifecycle + ? (Lifecycle) resources.getSource() : null) { @Override public Map getExtendedInfo() { @@ -457,7 +476,7 @@ public abstract class AbstractMessageChannelBinder getPolledConsumerRecoveryCallback(ErrorInfrastructure errorInfrastructure, - C properties) { + protected RecoveryCallback getPolledConsumerRecoveryCallback( + ErrorInfrastructure errorInfrastructure, C properties) { return errorInfrastructure.getRecoverer(); } - protected PolledConsumerResources createPolledConsumerResources(String name, String group, - ConsumerDestination destination, C consumerProperties) { - throw new UnsupportedOperationException("This binder does not support pollable consumers"); + protected PolledConsumerResources createPolledConsumerResources(String name, + String group, ConsumerDestination destination, C consumerProperties) { + throw new UnsupportedOperationException( + "This binder does not support pollable consumers"); } private void enhanceMessageChannel(MessageChannel inputChannel) { - ((AbstractMessageChannel) inputChannel).addInterceptor(0, this.embeddedHeadersChannelInterceptor); + ((AbstractMessageChannel) inputChannel).addInterceptor(0, + this.embeddedHeadersChannelInterceptor); } /** * Creates {@link MessageProducer} that receives data from the consumer destination. * will be started and stopped by the binder. - * * @param group the consumer group * @param destination reference to the consumer destination * @param properties the consumer properties * @return the consumer endpoint. + * @throws Exception when consumer endpoint creation failed. */ - protected abstract MessageProducer createConsumerEndpoint(ConsumerDestination destination, String group, - C properties) throws Exception; + protected abstract MessageProducer createConsumerEndpoint( + ConsumerDestination destination, String group, C properties) throws Exception; /** * Invoked after the unbinding of a consumer. The binder implementation can override * this method to provide their own logic (e.g. for cleaning up destinations). - * * @param destination the consumer destination * @param group the consumer group * @param consumerProperties the consumer properties */ - protected void afterUnbindConsumer(ConsumerDestination destination, String group, C consumerProperties) { + protected void afterUnbindConsumer(ConsumerDestination destination, String group, + C consumerProperties) { } /** @@ -518,26 +539,31 @@ public abstract class AbstractMessageChannelBinder doGetExtendedInfo(Object destination, Object properties) { Map extendedInfo = new LinkedHashMap<>(); extendedInfo.put("bindingDestination", destination.toString()); - extendedInfo.put(properties.getClass().getSimpleName(), objectMapper.convertValue(properties, Map.class)); + extendedInfo.put(properties.getClass().getSimpleName(), + this.objectMapper.convertValue(properties, Map.class)); return extendedInfo; } @@ -812,10 +867,12 @@ public abstract class AbstractMessageChannelBinder publisher = MessageChannelReactiveUtils.toPublisher(outputChannel); - // If the app has an explicit Supplier bean defined, make that as the publisher + Publisher publisher = MessageChannelReactiveUtils + .toPublisher(outputChannel); + // If the app has an explicit Supplier bean defined, make that as the + // publisher if (this.integrationFlowFunctionSupport.containsFunction(Supplier.class)) { - IntegrationFlowBuilder integrationFlowBuilder = IntegrationFlows.from(outputChannel).bridge(); + IntegrationFlowBuilder integrationFlowBuilder = IntegrationFlows + .from(outputChannel).bridge(); publisher = integrationFlowBuilder.toReactivePublisher(); } if (this.integrationFlowFunctionSupport.containsFunction(Function.class, this.streamFunctionProperties.getDefinition())) { DirectChannel actualOutputChannel = new DirectChannel(); if (outputChannel instanceof AbstractMessageChannel) { - moveChannelInterceptors((AbstractMessageChannel) outputChannel, actualOutputChannel); + moveChannelInterceptors((AbstractMessageChannel) outputChannel, + actualOutputChannel); } - this.integrationFlowFunctionSupport.andThenFunction(publisher, actualOutputChannel, - this.streamFunctionProperties); + this.integrationFlowFunctionSupport.andThenFunction(publisher, + actualOutputChannel, this.streamFunctionProperties); return actualOutputChannel; } } return (SubscribableChannel) outputChannel; } - private SubscribableChannel postProcessInboundChannelForFunction(MessageChannel inputChannel, ConsumerProperties consumerProperties) { - if (this.integrationFlowFunctionSupport != null && - (this.integrationFlowFunctionSupport.containsFunction(Consumer.class) || - this.integrationFlowFunctionSupport.containsFunction(Function.class))) { + private SubscribableChannel postProcessInboundChannelForFunction( + MessageChannel inputChannel, ConsumerProperties consumerProperties) { + if (this.integrationFlowFunctionSupport != null + && (this.integrationFlowFunctionSupport.containsFunction(Consumer.class) + || this.integrationFlowFunctionSupport + .containsFunction(Function.class))) { DirectChannel actualInputChannel = new DirectChannel(); if (inputChannel instanceof AbstractMessageChannel) { - moveChannelInterceptors((AbstractMessageChannel) inputChannel, actualInputChannel); + moveChannelInterceptors((AbstractMessageChannel) inputChannel, + actualInputChannel); } - this.integrationFlowFunctionSupport.andThenFunction(MessageChannelReactiveUtils.toPublisher(actualInputChannel), + this.integrationFlowFunctionSupport.andThenFunction( + MessageChannelReactiveUtils.toPublisher(actualInputChannel), inputChannel, this.streamFunctionProperties); return actualInputChannel; } @@ -883,7 +948,8 @@ public abstract class AbstractMessageChannelBinder message) throws Exception { - Message messageToSend = (this.useNativeEncoding) ? message - : serializeAndEmbedHeadersIfApplicable(message); - this.delegate.handleMessage(messageToSend); - } - - - @SuppressWarnings("deprecation") - private Message serializeAndEmbedHeadersIfApplicable(Message message) throws Exception { - MessageValues transformed = serializePayloadIfNecessary(message); - Object payload; - if (this.embedHeaders) { - Object contentType = transformed.get(MessageHeaders.CONTENT_TYPE); - // transform content type headers to String, so that they can be properly - // embedded in JSON - if (contentType != null) { - transformed.put(MessageHeaders.CONTENT_TYPE, contentType.toString()); - } - Object originalContentType = transformed.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); - if (originalContentType != null) { - transformed.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, originalContentType.toString()); - } - payload = EmbeddedHeaderUtils.embedHeaders(transformed, this.embeddedHeaders); - } - else { - payload = transformed.getPayload(); - } - return getMessageBuilderFactory().withPayload(payload).copyHeaders(transformed.getHeaders()).build(); - } - - @Override - public void start() { - if (this.delegate instanceof Lifecycle) { - ((Lifecycle) this.delegate).start(); - } - } - - @Override - public void stop() { - if (this.delegate instanceof Lifecycle) { - ((Lifecycle) this.delegate).stop(); - } - } - - @Override - public boolean isRunning() { - return this.delegate instanceof Lifecycle && ((Lifecycle) this.delegate).isRunning(); - } - } - protected static class ErrorInfrastructure { private final SubscribableChannel errorChannel; @@ -970,8 +965,8 @@ public abstract class AbstractMessageChannelBinder preSend(Message message, MessageChannel channel) { - if (message.getPayload() instanceof byte[] && - !message.getHeaders().containsKey(BinderHeaders.NATIVE_HEADERS_PRESENT) - && EmbeddedHeaderUtils.mayHaveEmbeddedHeaders((byte[]) message.getPayload())) { + if (message.getPayload() instanceof byte[] + && !message.getHeaders() + .containsKey(BinderHeaders.NATIVE_HEADERS_PRESENT) + && EmbeddedHeaderUtils + .mayHaveEmbeddedHeaders((byte[]) message.getPayload())) { MessageValues messageValues; try { - messageValues = EmbeddedHeaderUtils.extractHeaders((Message) message, true); + messageValues = EmbeddedHeaderUtils + .extractHeaders((Message) message, true); } catch (Exception e) { /* @@ -1016,8 +1015,9 @@ public abstract class AbstractMessageChannelBinder source, ErrorInfrastructure errorInfrastructure) { + public PolledConsumerResources(MessageSource source, + ErrorInfrastructure errorInfrastructure) { this.source = source; this.errorInfrastructure = errorInfrastructure; } @@ -1048,4 +1049,82 @@ public abstract class AbstractMessageChannelBinder message) throws Exception { + Message messageToSend = (this.useNativeEncoding) ? message + : serializeAndEmbedHeadersIfApplicable(message); + this.delegate.handleMessage(messageToSend); + } + + @SuppressWarnings("deprecation") + private Message serializeAndEmbedHeadersIfApplicable(Message message) + throws Exception { + MessageValues transformed = serializePayloadIfNecessary(message); + Object payload; + if (this.embedHeaders) { + Object contentType = transformed.get(MessageHeaders.CONTENT_TYPE); + // transform content type headers to String, so that they can be properly + // embedded in JSON + if (contentType != null) { + transformed.put(MessageHeaders.CONTENT_TYPE, contentType.toString()); + } + Object originalContentType = transformed + .get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); + if (originalContentType != null) { + transformed.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, + originalContentType.toString()); + } + payload = EmbeddedHeaderUtils.embedHeaders(transformed, + this.embeddedHeaders); + } + else { + payload = transformed.getPayload(); + } + return getMessageBuilderFactory().withPayload(payload) + .copyHeaders(transformed.getHeaders()).build(); + } + + @Override + public void start() { + if (this.delegate instanceof Lifecycle) { + ((Lifecycle) this.delegate).start(); + } + } + + @Override + public void stop() { + if (this.delegate instanceof Lifecycle) { + ((Lifecycle) this.delegate).stop(); + } + } + + @Override + public boolean isRunning() { + return this.delegate instanceof Lifecycle + && ((Lifecycle) this.delegate).isRunning(); + } + + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binder.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binder.java index fe82232f1..0fd1bdcdd 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binder.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binder.java @@ -24,7 +24,6 @@ package org.springframework.cloud.stream.binder; * @param the primary binding type (e.g. MessageChannel). * @param the consumer properties type. * @param

the producer properties type. - * * @author Mark Fisher * @author David Turanski * @author Gary Russell @@ -45,8 +44,10 @@ public interface Binder bindConsumer(String name, String group, T inboundBindTarget, C consumerProperties); + Binding bindConsumer(String name, String group, T inboundBindTarget, + C consumerProperties); /** * Bind the target component as a message producer to the logical entity identified by @@ -54,6 +55,7 @@ public interface Binder bindProducer(String name, T outboundBindTarget, P producerProperties); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderConfiguration.java index 5d31d578f..1e1638b1a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderConfiguration.java @@ -46,8 +46,8 @@ public class BinderConfiguration { * @param defaultCandidate whether the binder should be considered as a candidate when * determining a default */ - public BinderConfiguration(String binderType, Map properties, boolean inheritEnvironment, - boolean defaultCandidate) { + public BinderConfiguration(String binderType, Map properties, + boolean inheritEnvironment, boolean defaultCandidate) { this.binderType = binderType; this.properties = properties; this.inheritEnvironment = inheritEnvironment; @@ -55,18 +55,19 @@ public class BinderConfiguration { } public String getBinderType() { - return binderType; + return this.binderType; } public Map getProperties() { - return properties; + return this.properties; } public boolean isInheritEnvironment() { - return inheritEnvironment; + return this.inheritEnvironment; } public boolean isDefaultCandidate() { - return defaultCandidate; + return this.defaultCandidate; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderErrorChannel.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderErrorChannel.java index 843d86793..587318dc0 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderErrorChannel.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderErrorChannel.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,14 +22,15 @@ import org.springframework.integration.channel.PublishSubscribeChannel; import org.springframework.messaging.MessageHandler; /** - * A channel for errors. If it has a {@link LastSubscriberMessageHandler} - * subscriber, it can only have one and it will always be the last subscriber. + * A channel for errors. If it has a {@link LastSubscriberMessageHandler} subscriber, it + * can only have one and it will always be the last subscriber. * * @author Gary Russell * @since 1.3 * */ -class BinderErrorChannel extends PublishSubscribeChannel implements LastSubscriberAwareChannel { +class BinderErrorChannel extends PublishSubscribeChannel + implements LastSubscriberAwareChannel { private final AtomicInteger subscribers = new AtomicInteger(); @@ -38,17 +39,20 @@ class BinderErrorChannel extends PublishSubscribeChannel implements LastSubscrib @Override public boolean subscribe(MessageHandler handler) { this.subscribers.incrementAndGet(); - if (handler instanceof LastSubscriberMessageHandler && this.finalHandler != null) { - throw new IllegalStateException("Only one LastSubscriberMessageHandler is allowed"); + if (handler instanceof LastSubscriberMessageHandler + && this.finalHandler != null) { + throw new IllegalStateException( + "Only one LastSubscriberMessageHandler is allowed"); } if (this.finalHandler != null) { unsubscribe(this.finalHandler); } boolean result = super.subscribe(handler); if (this.finalHandler != null) { - super.subscribe(finalHandler); + super.subscribe(this.finalHandler); } - if (handler instanceof LastSubscriberMessageHandler && this.finalHandler == null) { + if (handler instanceof LastSubscriberMessageHandler + && this.finalHandler == null) { this.finalHandler = (LastSubscriberMessageHandler) handler; } return result; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderFactory.java index a6db121fd..92842ad55 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,10 +25,12 @@ public interface BinderFactory { * Returns the binder instance associated with the given configuration name. Instance * caching is a requirement, and implementations must return the same instance on * subsequent invocations with the same arguments. - * + * @param the primary binding type * @param configurationName the name of a binder configuration + * @param bindableType binding target type * @return the binder instance */ - Binder getBinder(String configurationName, - Class bindableType); + Binder getBinder( + String configurationName, Class bindableType); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderHeaders.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderHeaders.java index 0399c9721..fe77cacf5 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderHeaders.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderHeaders.java @@ -21,6 +21,7 @@ import org.springframework.messaging.MessageHeaders; /** * Spring Integration message headers for Spring Cloud Stream. + * * @author Gary Russell * @author David Turanski * @author Soby Chacko @@ -40,10 +41,8 @@ public final class BinderHeaders { public static final String[] STANDARD_HEADERS = new String[] { IntegrationMessageHeaderAccessor.CORRELATION_ID, IntegrationMessageHeaderAccessor.SEQUENCE_SIZE, - IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER, - MessageHeaders.CONTENT_TYPE, - BINDER_ORIGINAL_CONTENT_TYPE - }; + IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER, MessageHeaders.CONTENT_TYPE, + BINDER_ORIGINAL_CONTENT_TYPE }; private static final String PREFIX = "scst_"; @@ -69,8 +68,8 @@ public final class BinderHeaders { public static final String NATIVE_HEADERS_PRESENT = PREFIX + "nativeHeadersPresent"; /** - * Indicates the Spring Cloud Stream version. - * Used for determining if legacy content type check supported or not. + * Indicates the Spring Cloud Stream version. Used for determining if legacy content + * type check supported or not. * @since 2.0 */ public static final String SCST_VERSION = PREFIX + "version"; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderSpecificPropertiesProvider.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderSpecificPropertiesProvider.java index 878f25a96..f348689da 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderSpecificPropertiesProvider.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderSpecificPropertiesProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -17,9 +17,7 @@ package org.springframework.cloud.stream.binder; /** - * * @author Oleg Zhurakousky - * * @since 2.1 * */ @@ -28,4 +26,5 @@ public interface BinderSpecificPropertiesProvider { Object getConsumer(); Object getProducer(); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderType.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderType.java index da66f7b85..df47038d6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderType.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderType.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,11 +40,11 @@ public class BinderType { } public String getDefaultName() { - return defaultName; + return this.defaultName; } public Class[] getConfigurationClasses() { - return configurationClasses; + return this.configurationClasses; } @Override @@ -56,17 +56,18 @@ public class BinderType { return false; } BinderType that = (BinderType) o; - if (!defaultName.equals(that.defaultName)) { + if (!this.defaultName.equals(that.defaultName)) { return false; } - return Arrays.equals(configurationClasses, that.configurationClasses); + return Arrays.equals(this.configurationClasses, that.configurationClasses); } @Override public int hashCode() { - int result = defaultName.hashCode(); - result = 31 * result + Arrays.hashCode(configurationClasses); + int result = this.defaultName.hashCode(); + result = 31 * result + Arrays.hashCode(this.configurationClasses); return result; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binding.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binding.java index 7096e5f44..a872e5a0a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binding.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/Binding.java @@ -28,12 +28,12 @@ import org.springframework.integration.endpoint.Pausable; * represents a connection from an adapter to an input. A producer binding represents a * connection from an output to an adapter. * + * @param type of a binding * @author Jennifer Hickey * @author Mark Fisher * @author Gary Russell * @author Marius Bogoevici * @author Oleg Zhurakousky - * * @see org.springframework.cloud.stream.annotation.EnableBinding */ public interface Binding extends Pausable { @@ -43,28 +43,30 @@ public interface Binding extends Pausable { } /** - * Stops the target component represented by this instance. - * NOTE: At the time the instance is created the component is already started. - * This operation is typically used by actuator to re-bind/re-start. + * Stops the target component represented by this instance. NOTE: At the time the + * instance is created the component is already started. This operation is typically + * used by actuator to re-bind/re-start. * * @see BindingsEndpoint */ - default void start() {} + default void start() { + } /** - * Starts the target component represented by this instance. - * NOTE: At the time the instance is created the component is already started. - * This operation is typically used by actuator to re-bind/re-start. + * Starts the target component represented by this instance. NOTE: At the time the + * instance is created the component is already started. This operation is typically + * used by actuator to re-bind/re-start. * * @see BindingsEndpoint */ - default void stop() {} + default void stop() { + } /** - * Pauses the target component represented by this instance if and only if the component - * implements {@link Pausable} interface - * NOTE: At the time the instance is created the component is already started and active. - * This operation is typically used by actuator to pause/resume. + * Pauses the target component represented by this instance if and only if the + * component implements {@link Pausable} interface NOTE: At the time the instance is + * created the component is already started and active. This operation is typically + * used by actuator to pause/resume. * * @see BindingsEndpoint */ @@ -73,10 +75,10 @@ public interface Binding extends Pausable { } /** - * Resumes the target component represented by this instance if and only if the component - * implements {@link Pausable} interface - * NOTE: At the time the instance is created the component is already started and active. - * This operation is typically used by actuator to pause/resume. + * Resumes the target component represented by this instance if and only if the + * component implements {@link Pausable} interface NOTE: At the time the instance is + * created the component is already started and active. This operation is typically + * used by actuator to pause/resume. * * @see BindingsEndpoint */ @@ -85,15 +87,14 @@ public interface Binding extends Pausable { } /** - * Returns 'true' if the target component represented by this instance is running. + * @return 'true' if the target component represented by this instance is running. */ default boolean isRunning() { return false; } /** - * Returns the name of this binding (i.e., channel name) - * + * Returns the name of this binding (i.e., channel name). * @return binding name */ default String getName() { @@ -109,13 +110,15 @@ public interface Binding extends Pausable { void unbind(); /** - * Returns boolean flag representing this binding's type. If 'true' this binding is an 'input' binding - * otherwise it is 'output' (as in binding annotated with either @Input or @Output). - * + * Returns boolean flag representing this binding's type. If 'true' this binding is an + * 'input' binding otherwise it is 'output' (as in binding annotated with + * either @Input or @Output). * @return 'true' if this binding represents an input binding. */ default boolean isInput() { - throw new UnsupportedOperationException("Binding implementation `" + this.getClass().getName() - + "` must implement this operation before it is called"); + throw new UnsupportedOperationException( + "Binding implementation `" + this.getClass().getName() + + "` must implement this operation before it is called"); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCleaner.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCleaner.java index 0477165a6..3be109f4e 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCleaner.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCleaner.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCreatedEvent.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCreatedEvent.java index 03f9183e8..b4db34577 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCreatedEvent.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindingCreatedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -22,7 +22,6 @@ import org.springframework.context.ApplicationEvent; * ApplicationEvent fired whenever the the Binding is created. * * @author Oleg Zhurakousky - * * @since 2.0 * * #see AbstractMessageChannelBinder diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ConsumerProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ConsumerProperties.java index a737b933d..662a6eb37 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ConsumerProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ConsumerProperties.java @@ -23,7 +23,6 @@ import javax.validation.constraints.Min; import com.fasterxml.jackson.annotation.JsonInclude; - /** * Common consumer properties. * @@ -37,7 +36,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; public class ConsumerProperties { /** - * Signals if this consumer needs to be started automatically + * Signals if this consumer needs to be started automatically. * * Default: true */ @@ -55,61 +54,52 @@ public class ConsumerProperties { /** * When set to a value greater than equal to zero, allows customizing the instance - * count of this consumer (if different from spring.cloud.stream.instanceCount). - * When set to a negative value, it will default to spring.cloud.stream.instanceCount. - * See that property for more information. - * Default: -1 - * NOTE: This setting will override the one set in 'spring.cloud.stream.instance-count' + * count of this consumer (if different from spring.cloud.stream.instanceCount). When + * set to a negative value, it will default to spring.cloud.stream.instanceCount. See + * that property for more information. Default: -1 NOTE: This setting will override + * the one set in 'spring.cloud.stream.instance-count' */ private int instanceCount = -1; /** * When set to a value greater than equal to zero, allows customizing the instance - * index of this consumer (if different from spring.cloud.stream.instanceIndex). - * When set to a negative value, it will default to spring.cloud.stream.instanceIndex. - * See that property for more information. - * Default: -1 - * NOTE: This setting will override the one set in 'spring.cloud.stream.instance-index' + * index of this consumer (if different from spring.cloud.stream.instanceIndex). When + * set to a negative value, it will default to spring.cloud.stream.instanceIndex. See + * that property for more information. Default: -1 NOTE: This setting will override + * the one set in 'spring.cloud.stream.instance-index' */ private int instanceIndex = -1; /** - * The number of attempts to process the message (including the first) - * in the event of processing failures. This is a RetryTemplate configuration - * which is provided by the framework. - * Default: 3. Set to 1 to disable retry. You can also provide custom RetryTemplate - * in the event you want to take complete control of the RetryTemplate. Simply configure - * it as @Bean inside your application configuration. + * The number of attempts to process the message (including the first) in the event of + * processing failures. This is a RetryTemplate configuration which is provided by the + * framework. Default: 3. Set to 1 to disable retry. You can also provide custom + * RetryTemplate in the event you want to take complete control of the RetryTemplate. + * Simply configure it as @Bean inside your application configuration. */ private int maxAttempts = 3; /** - * The backoff initial interval on retry. This is a RetryTemplate configuration - * which is provided by the framework. - * Default: 1000 ms. - * You can also provide custom RetryTemplate - * in the event you want to take complete control of the RetryTemplate. Simply configure - * it as @Bean inside your application configuration. + * The backoff initial interval on retry. This is a RetryTemplate configuration which + * is provided by the framework. Default: 1000 ms. You can also provide custom + * RetryTemplate in the event you want to take complete control of the RetryTemplate. + * Simply configure it as @Bean inside your application configuration. */ private int backOffInitialInterval = 1000; /** - * The maximum backoff interval. This is a RetryTemplate configuration - * which is provided by the framework. - * Default: 10000 ms. - * You can also provide custom RetryTemplate - * in the event you want to take complete control of the RetryTemplate. Simply configure - * it as @Bean inside your application configuration. + * The maximum backoff interval. This is a RetryTemplate configuration which is + * provided by the framework. Default: 10000 ms. You can also provide custom + * RetryTemplate in the event you want to take complete control of the RetryTemplate. + * Simply configure it as @Bean inside your application configuration. */ private int backOffMaxInterval = 10000; /** - * The backoff multiplier.This is a RetryTemplate configuration - * which is provided by the framework. - * Default: 2.0. - * You can also provide custom RetryTemplate - * in the event you want to take complete control of the RetryTemplate. Simply configure - * it as @Bean inside your application configuration. + * The backoff multiplier.This is a RetryTemplate configuration which is provided by + * the framework. Default: 2.0. You can also provide custom RetryTemplate in the event + * you want to take complete control of the RetryTemplate. Simply configure it + * as @Bean inside your application configuration. */ private double backOffMultiplier = 2.0; @@ -120,47 +110,49 @@ public class ConsumerProperties { private boolean defaultRetryable = true; /** - * A map of Throwable class names in the key and a boolean in the value. - * Specify those exceptions (and subclasses) that will or won't be retried. + * A map of Throwable class names in the key and a boolean in the value. Specify those + * exceptions (and subclasses) that will or won't be retried. */ private Map, Boolean> retryableExceptions = new LinkedHashMap<>(); /** - * When set to none, disables header parsing on input. Effective only - * for messaging middleware that does not support message headers natively - * and requires header embedding. This option is useful when consuming data - * from non-Spring Cloud Stream applications when native headers are not - * supported. When set to headers, uses the middleware’s native header mechanism. - * When set to embeddedHeaders, embeds headers into the message payload. - * Default: depends on binder implementation. Rabbit and Kafka binders currently - * distributed with spring cloud stream support headers natively. + * When set to none, disables header parsing on input. Effective only for messaging + * middleware that does not support message headers natively and requires header + * embedding. This option is useful when consuming data from non-Spring Cloud Stream + * applications when native headers are not supported. When set to headers, uses the + * middleware’s native header mechanism. When set to embeddedHeaders, embeds headers + * into the message payload. Default: depends on binder implementation. Rabbit and + * Kafka binders currently distributed with spring cloud stream support headers + * natively. */ private HeaderMode headerMode; /** * When set to true, the inbound message is deserialized directly by client library, - * which must be configured correspondingly (e.g. setting an appropriate Kafka producer value serializer). - * NOTE: This is binder specific setting which has no effect if binder does not support native - * serialization/deserialization. Currently only Kafka binder supports it. - * Default: 'false' + * which must be configured correspondingly (e.g. setting an appropriate Kafka + * producer value serializer). NOTE: This is binder specific setting which has no + * effect if binder does not support native serialization/deserialization. Currently + * only Kafka binder supports it. Default: 'false' */ private boolean useNativeDecoding; /** - * When set to true, the underlying binder will natively multiplex destinations on the same input binding. - * For example, in the case of a comma separated multiple destinations, the core framework will skip binding - * them individually if this is set to true, but delegate that responsibility to the binder. + * When set to true, the underlying binder will natively multiplex destinations on the + * same input binding. For example, in the case of a comma separated multiple + * destinations, the core framework will skip binding them individually if this is set + * to true, but delegate that responsibility to the binder. * - * By default this property is set to `false` and the binder will individually bind each destinations in case - * of a comma separated multi destination list. The individual binder implementations that need to support multiple - * input bindings natively (multiplex) can enable this property. Under normal circumstances, the end users are - * not expected to enable or disable this property directly. + * By default this property is set to `false` and the binder will individually bind + * each destinations in case of a comma separated multi destination list. The + * individual binder implementations that need to support multiple input bindings + * natively (multiplex) can enable this property. Under normal circumstances, the end + * users are not expected to enable or disable this property directly. */ private boolean multiplex; @Min(value = 1, message = "Concurrency should be greater than zero.") public int getConcurrency() { - return concurrency; + return this.concurrency; } public void setConcurrency(int concurrency) { @@ -168,7 +160,7 @@ public class ConsumerProperties { } public boolean isPartitioned() { - return partitioned; + return this.partitioned; } public void setPartitioned(boolean partitioned) { @@ -177,7 +169,7 @@ public class ConsumerProperties { @Min(value = -1, message = "Instance count should be greater than or equal to -1.") public int getInstanceCount() { - return instanceCount; + return this.instanceCount; } public void setInstanceCount(int instanceCount) { @@ -186,7 +178,7 @@ public class ConsumerProperties { @Min(value = -1, message = "Instance index should be greater than or equal to -1") public int getInstanceIndex() { - return instanceIndex; + return this.instanceIndex; } public void setInstanceIndex(int instanceIndex) { @@ -195,7 +187,7 @@ public class ConsumerProperties { @Min(value = 1, message = "Max attempts should be greater than zero.") public int getMaxAttempts() { - return maxAttempts; + return this.maxAttempts; } public void setMaxAttempts(int maxAttempts) { @@ -204,7 +196,7 @@ public class ConsumerProperties { @Min(value = 1, message = "Backoff initial interval should be greater than zero.") public int getBackOffInitialInterval() { - return backOffInitialInterval; + return this.backOffInitialInterval; } public void setBackOffInitialInterval(int backOffInitialInterval) { @@ -213,7 +205,7 @@ public class ConsumerProperties { @Min(value = 1, message = "Backoff max interval should be greater than zero.") public int getBackOffMaxInterval() { - return backOffMaxInterval; + return this.backOffMaxInterval; } public void setBackOffMaxInterval(int backOffMaxInterval) { @@ -222,7 +214,7 @@ public class ConsumerProperties { @Min(value = 1, message = "Backoff multiplier should be greater than zero.") public double getBackOffMultiplier() { - return backOffMultiplier; + return this.backOffMultiplier; } public void setBackOffMultiplier(double backOffMultiplier) { @@ -241,7 +233,8 @@ public class ConsumerProperties { return this.retryableExceptions; } - public void setRetryableExceptions(Map, Boolean> retryableExceptions) { + public void setRetryableExceptions( + Map, Boolean> retryableExceptions) { this.retryableExceptions = retryableExceptions; } @@ -254,7 +247,7 @@ public class ConsumerProperties { } public boolean isUseNativeDecoding() { - return useNativeDecoding; + return this.useNativeDecoding; } public void setUseNativeDecoding(boolean useNativeDecoding) { @@ -262,7 +255,7 @@ public class ConsumerProperties { } public boolean isMultiplex() { - return multiplex; + return this.multiplex; } public void setMultiplex(boolean multiplex) { @@ -270,10 +263,11 @@ public class ConsumerProperties { } public boolean isAutoStartup() { - return autoStartup; + return this.autoStartup; } public void setAutoStartup(boolean autoStartup) { this.autoStartup = autoStartup; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java index f7262e835..9a3795c28 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java @@ -43,7 +43,6 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; - /** * Default {@link BinderFactory} implementation. * @@ -54,22 +53,26 @@ import org.springframework.util.StringUtils; * @author Soby Chacko * @author Artem Bilan */ -public class DefaultBinderFactory implements BinderFactory, DisposableBean, ApplicationContextAware { +public class DefaultBinderFactory + implements BinderFactory, DisposableBean, ApplicationContextAware { private final Map binderConfigurations; + // @checkstyle:off private final Map, ConfigurableApplicationContext>> binderInstanceCache = new HashMap<>(); - private volatile ConfigurableApplicationContext context; + // @checkstyle:on private final Map defaultBinderForBindingTargetType = new HashMap<>(); + private final BinderTypeRegistry binderTypeRegistry; + + private volatile ConfigurableApplicationContext context; + private Collection listeners; private volatile String defaultBinder; - private final BinderTypeRegistry binderTypeRegistry; - public DefaultBinderFactory(Map binderConfigurations, BinderTypeRegistry binderTypeRegistry) { this.binderConfigurations = new HashMap<>(binderConfigurations); @@ -92,27 +95,33 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl @Override public void destroy() { - this.binderInstanceCache.values().stream().map(Entry::getValue).forEach(ConfigurableApplicationContext::close); + this.binderInstanceCache.values().stream().map(Entry::getValue) + .forEach(ConfigurableApplicationContext::close); this.defaultBinderForBindingTargetType.clear(); } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public synchronized Binder getBinder(String name, Class bindingTargetType) { + public synchronized Binder getBinder(String name, + Class bindingTargetType) { String binderName = StringUtils.hasText(name) ? name : this.defaultBinder; - Map binders = this.context == null ? Collections.emptyMap() : this.context.getBeansOfType(Binder.class); + Map binders = this.context == null ? Collections.emptyMap() + : this.context.getBeansOfType(Binder.class); Binder binder; if (StringUtils.hasText(binderName) && binders.containsKey(binderName)) { - binder = (Binder) this.context.getBean(binderName); + binder = (Binder) this.context + .getBean(binderName); } else if (binders.size() == 1) { binder = binders.values().iterator().next(); } - else if (binders.size() > 1) { - throw new IllegalStateException("Multiple binders are available, however neither default nor " - + "per-destination binder name is provided. Available binders are " + binders.keySet()); + else if (binders.size() > 1) { + throw new IllegalStateException( + "Multiple binders are available, however neither default nor " + + "per-destination binder name is provided. Available binders are " + + binders.keySet()); } else { /* @@ -123,45 +132,53 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl return binder; } - - private Binder doGetBinder(String name, Class bindingTargetType) { + private Binder doGetBinder(String name, + Class bindingTargetType) { String configurationName; // Fall back to a default if no argument is provided if (StringUtils.isEmpty(name)) { - Assert.notEmpty(this.binderConfigurations, "A default binder has been requested, but there is no binder available"); + Assert.notEmpty(this.binderConfigurations, + "A default binder has been requested, but there is no binder available"); if (!StringUtils.hasText(this.defaultBinder)) { Set defaultCandidateConfigurations = new HashSet<>(); - for (Map.Entry binderConfigurationEntry : this.binderConfigurations.entrySet()) { + for (Map.Entry binderConfigurationEntry : this.binderConfigurations + .entrySet()) { if (binderConfigurationEntry.getValue().isDefaultCandidate()) { - defaultCandidateConfigurations.add(binderConfigurationEntry.getKey()); + defaultCandidateConfigurations + .add(binderConfigurationEntry.getKey()); } } if (defaultCandidateConfigurations.size() == 1) { configurationName = defaultCandidateConfigurations.iterator().next(); - this.defaultBinderForBindingTargetType.put(bindingTargetType.getName(), configurationName); + this.defaultBinderForBindingTargetType + .put(bindingTargetType.getName(), configurationName); } else { List candidatesForBindableType = new ArrayList<>(); for (String defaultCandidateConfiguration : defaultCandidateConfigurations) { - Binder binderInstance = getBinderInstance(defaultCandidateConfiguration); - Class binderType = GenericsUtils.getParameterType(binderInstance.getClass(), Binder.class, 0); + Binder binderInstance = getBinderInstance( + defaultCandidateConfiguration); + Class binderType = GenericsUtils.getParameterType( + binderInstance.getClass(), Binder.class, 0); if (binderType.isAssignableFrom(bindingTargetType)) { candidatesForBindableType.add(defaultCandidateConfiguration); } } if (candidatesForBindableType.size() == 1) { configurationName = candidatesForBindableType.iterator().next(); - this.defaultBinderForBindingTargetType.put(bindingTargetType.getName(), configurationName); + this.defaultBinderForBindingTargetType + .put(bindingTargetType.getName(), configurationName); } else { String countMsg = (candidatesForBindableType.size() == 0) - ? "are no binders" - : "is more than one binder"; + ? "are no binders" : "is more than one binder"; throw new IllegalStateException( - "A default binder has been requested, but there " + countMsg - + " available for '" + bindingTargetType.getName() + "' : " - + StringUtils.collectionToCommaDelimitedString(candidatesForBindableType) - + ", and no default binder has been set."); + "A default binder has been requested, but there " + + countMsg + " available for '" + + bindingTargetType.getName() + "' : " + + StringUtils.collectionToCommaDelimitedString( + candidatesForBindableType) + + ", and no default binder has been set."); } } } @@ -172,9 +189,11 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl else { configurationName = name; } - Binder binderInstance = getBinderInstance(configurationName); + Binder binderInstance = getBinderInstance( + configurationName); Assert.state(verifyBinderTypeMatchesTarget(binderInstance, bindingTargetType), - "The binder '" + configurationName + "' cannot bind a " + bindingTargetType.getName()); + "The binder '" + configurationName + "' cannot bind a " + + bindingTargetType.getName()); return binderInstance; } @@ -182,25 +201,32 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl * Return true if the binder is a {@link PollableConsumerBinder} and the target type * is a {@link PollableSource} and their generic types match (e.g. MessageHandler), OR * if it's a {@link Binder} and the target matches the binder's generic type. + * @param bindng target type * @param binderInstance the binder. * @param bindingTargetType the binding target type. * @return true if the conditions match. */ private boolean verifyBinderTypeMatchesTarget(Binder binderInstance, Class bindingTargetType) { - return (binderInstance instanceof PollableConsumerBinder - && GenericsUtils.checkCompatiblePollableBinder(binderInstance, bindingTargetType)) - || GenericsUtils.getParameterType(binderInstance.getClass(), Binder.class, 0) - .isAssignableFrom(bindingTargetType); + return (binderInstance instanceof PollableConsumerBinder && GenericsUtils + .checkCompatiblePollableBinder(binderInstance, bindingTargetType)) + || GenericsUtils + .getParameterType(binderInstance.getClass(), Binder.class, 0) + .isAssignableFrom(bindingTargetType); } @SuppressWarnings("unchecked") - private Binder getBinderInstance(String configurationName) { + private Binder getBinderInstance( + String configurationName) { if (!this.binderInstanceCache.containsKey(configurationName)) { - BinderConfiguration binderConfiguration = this.binderConfigurations.get(configurationName); - Assert.state(binderConfiguration != null, "Unknown binder configuration: " + configurationName); - BinderType binderType = this.binderTypeRegistry.get(binderConfiguration.getBinderType()); - Assert.notNull(binderType, "Binder type " + binderConfiguration.getBinderType() + " is not defined"); + BinderConfiguration binderConfiguration = this.binderConfigurations + .get(configurationName); + Assert.state(binderConfiguration != null, + "Unknown binder configuration: " + configurationName); + BinderType binderType = this.binderTypeRegistry + .get(binderConfiguration.getBinderType()); + Assert.notNull(binderType, "Binder type " + + binderConfiguration.getBinderType() + " is not defined"); Map binderProperties = new HashMap<>(); this.flatten(null, binderConfiguration.getProperties(), binderProperties); @@ -209,22 +235,30 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl // precedence ArrayList args = new ArrayList<>(); for (Map.Entry property : binderProperties.entrySet()) { - args.add(String.format("--%s=%s", property.getKey(), property.getValue())); + args.add( + String.format("--%s=%s", property.getKey(), property.getValue())); } // Initialize the domain with a unique name based on the bootstrapping context // setting - ConfigurableEnvironment environment = this.context != null ? this.context.getEnvironment() : null; - String defaultDomain = environment != null ? environment.getProperty("spring.jmx.default-domain") : ""; - args.add("--spring.jmx.default-domain=" + defaultDomain + "binder." + configurationName); - // Initializing SpringApplicationBuilder with SpelExpressionConverterConfiguration due to the fact that - // infrastructure related configuration is not propagated in a multi binder scenario. - // See this GH issue for more details: https://github.com/spring-cloud/spring-cloud-stream/issues/1412 - // and the associated PR: https://github.com/spring-cloud/spring-cloud-stream/pull/1413 - SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder(SpelExpressionConverterConfiguration.class) - .sources(binderType.getConfigurationClasses()) - .bannerMode(Mode.OFF) - .logStartupInfo(false) - .web(WebApplicationType.NONE); + ConfigurableEnvironment environment = this.context != null + ? this.context.getEnvironment() : null; + String defaultDomain = environment != null + ? environment.getProperty("spring.jmx.default-domain") : ""; + args.add("--spring.jmx.default-domain=" + defaultDomain + "binder." + + configurationName); + // Initializing SpringApplicationBuilder with + // SpelExpressionConverterConfiguration due to the fact that + // infrastructure related configuration is not propagated in a multi binder + // scenario. + // See this GH issue for more details: + // https://github.com/spring-cloud/spring-cloud-stream/issues/1412 + // and the associated PR: + // https://github.com/spring-cloud/spring-cloud-stream/pull/1413 + SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder( + SpelExpressionConverterConfiguration.class) + .sources(binderType.getConfigurationClasses()) + .bannerMode(Mode.OFF).logStartupInfo(false) + .web(WebApplicationType.NONE); // If the environment is not customized and a main context is available, we // will set the latter as parent. // This ensures that the defaults and user-defined customizations (e.g. custom @@ -232,52 +266,66 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl // are propagated to the binder context. If the environment is customized, // then the binder context should // not inherit any beans from the parent - boolean useApplicationContextAsParent = binderProperties.isEmpty() && this.context != null; + boolean useApplicationContextAsParent = binderProperties.isEmpty() + && this.context != null; if (useApplicationContextAsParent) { springApplicationBuilder.parent(this.context); } - // If the current application context is not set as parent and the environment is set, + // If the current application context is not set as parent and the environment + // is set, // provide the current context as an additional bean in the BeanFactory. - if (environment != null && !useApplicationContextAsParent){ - springApplicationBuilder.initializers(new InitializerWithOuterContext(this.context)); + if (environment != null && !useApplicationContextAsParent) { + springApplicationBuilder + .initializers(new InitializerWithOuterContext(this.context)); } - if (environment != null && (useApplicationContextAsParent || binderConfiguration.isInheritEnvironment())) { + if (environment != null && (useApplicationContextAsParent + || binderConfiguration.isInheritEnvironment())) { StandardEnvironment binderEnvironment = new StandardEnvironment(); binderEnvironment.merge(environment); // See ConfigurationPropertySources.ATTACHED_PROPERTY_SOURCE_NAME binderEnvironment.getPropertySources().remove("configurationProperties"); springApplicationBuilder.environment(binderEnvironment); } - ConfigurableApplicationContext binderProducingContext = - springApplicationBuilder.run(args.toArray(new String[0])); + ConfigurableApplicationContext binderProducingContext = springApplicationBuilder + .run(args.toArray(new String[0])); Binder binder = binderProducingContext.getBean(Binder.class); /* - * This will ensure that application defined errorChannel and other beans are accessible within binder's context - * (see https://github.com/spring-cloud/spring-cloud-stream/issues/1384) + * This will ensure that application defined errorChannel and other beans are + * accessible within binder's context (see + * https://github.com/spring-cloud/spring-cloud-stream/issues/1384) */ if (this.context != null && binder instanceof ApplicationContextAware) { - ((ApplicationContextAware)binder).setApplicationContext(this.context); + ((ApplicationContextAware) binder).setApplicationContext(this.context); } if (!CollectionUtils.isEmpty(this.listeners)) { - for (Listener binderFactoryListener : listeners) { - binderFactoryListener.afterBinderContextInitialized(configurationName, binderProducingContext); + for (Listener binderFactoryListener : this.listeners) { + binderFactoryListener.afterBinderContextInitialized(configurationName, + binderProducingContext); } } - this.binderInstanceCache.put(configurationName, new SimpleImmutableEntry<>(binder, binderProducingContext)); + this.binderInstanceCache.put(configurationName, + new SimpleImmutableEntry<>(binder, binderProducingContext)); } - return (Binder) this.binderInstanceCache.get(configurationName).getKey(); + return (Binder) this.binderInstanceCache + .get(configurationName).getKey(); } /** - * Ensures that nested properties are flattened (i.e., foo.bar=baz instead of foo={bar=baz}) + * Ensures that nested properties are flattened (i.e., foo.bar=baz instead of + * foo={bar=baz}). + * @param propertyName property name to flatten + * @param value value that contains the property name + * @param flattenedProperties map to which we'll add the falttened property */ @SuppressWarnings("unchecked") - private void flatten(String propertyName, Object value, Map flattenedProperties) { + private void flatten(String propertyName, Object value, + Map flattenedProperties) { if (value instanceof Map) { - ((Map) value) - .forEach((k, v) -> flatten((propertyName != null ? propertyName + "." : "") + k, v, flattenedProperties)); + ((Map) value).forEach((k, v) -> flatten( + (propertyName != null ? propertyName + "." : "") + k, v, + flattenedProperties)); } else { flattenedProperties.put(propertyName, value.toString()); @@ -295,15 +343,17 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl /** * Applying additional capabilities to the binder after the binder context has * been initialized. - * * @param configurationName the binder configuration name * @param binderContext the application context of the binder */ void afterBinderContextInitialized(String configurationName, ConfigurableApplicationContext binderContext); + } - private static class InitializerWithOuterContext implements ApplicationContextInitializer { + private static class InitializerWithOuterContext + implements ApplicationContextInitializer { + private final ApplicationContext context; InitializerWithOuterContext(ApplicationContext context) { @@ -312,8 +362,10 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl @Override public void initialize(ConfigurableApplicationContext applicationContext) { - applicationContext.getBeanFactory().registerSingleton("outerContext", context); + applicationContext.getBeanFactory().registerSingleton("outerContext", + this.context); } + } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderTypeRegistry.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderTypeRegistry.java index 61adae2ed..a0e5881c2 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderTypeRegistry.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderTypeRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. @@ -35,12 +35,12 @@ public class DefaultBinderTypeRegistry implements BinderTypeRegistry { @Override public BinderType get(String name) { - return binderTypes.get(name); + return this.binderTypes.get(name); } @Override public Map getAll() { - return binderTypes; + return this.binderTypes; } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinding.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinding.java index 7d71f4238..9736d06c7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinding.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinding.java @@ -18,7 +18,6 @@ package org.springframework.cloud.stream.binder; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -31,20 +30,19 @@ import org.springframework.util.StringUtils; /** * Default implementation for a {@link Binding}. + * + * @param type of binding * @author Jennifer Hickey * @author Mark Fisher * @author Gary Russell * @author Marius Bogoevici * @author Oleg Zhurakousky - * * @see org.springframework.cloud.stream.annotation.EnableBinding */ -@JsonPropertyOrder({ "name", "group", "pausable", "state"}) +@JsonPropertyOrder({ "name", "group", "pausable", "state" }) @JsonIgnoreProperties("running") public class DefaultBinding implements Binding { - private final Log logger = LogFactory.getLog(this.getClass().getName()); - protected final String name; protected final String group; @@ -53,6 +51,8 @@ public class DefaultBinding implements Binding { protected final Lifecycle lifecycle; + private final Log logger = LogFactory.getLog(this.getClass().getName()); + private boolean paused; private boolean restartable; @@ -60,11 +60,11 @@ public class DefaultBinding implements Binding { /** * Creates an instance that associates a given name, group and binding target with an * optional {@link Lifecycle} component, which will be stopped during unbinding. - * * @param name the name of the binding target * @param group the group (only for input targets) * @param target the binding target - * @param lifecycle {@link Lifecycle} that runs while the binding is active and will be stopped during unbinding + * @param lifecycle {@link Lifecycle} that runs while the binding is active and will + * be stopped during unbinding */ public DefaultBinding(String name, String group, T target, Lifecycle lifecycle) { Assert.notNull(target, "target must not be null"); @@ -116,7 +116,7 @@ public class DefaultBinding implements Binding { this.lifecycle.start(); } else { - logger.warn("Can not re-bind an anonymous binding"); + this.logger.warn("Can not re-bind an anonymous binding"); } } } @@ -131,22 +131,26 @@ public class DefaultBinding implements Binding { @Override public final synchronized void pause() { if (this.lifecycle instanceof Pausable) { - ( (Pausable) this.lifecycle).pause(); + ((Pausable) this.lifecycle).pause(); this.paused = true; } else { - logger.warn("Attempted to pause a component that does not support Pausable " + this.lifecycle); + this.logger + .warn("Attempted to pause a component that does not support Pausable " + + this.lifecycle); } } @Override public final synchronized void resume() { if (this.lifecycle instanceof Pausable) { - ( (Pausable) this.lifecycle).resume(); + ((Pausable) this.lifecycle).resume(); this.paused = false; } else { - logger.warn("Attempted to resume a component that does not support Pausable " + this.lifecycle); + this.logger.warn( + "Attempted to resume a component that does not support Pausable " + + this.lifecycle); } } @@ -179,4 +183,5 @@ public class DefaultBinding implements Binding { private String getRunningState() { return isRunning() ? "running" : "stopped"; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultPollableMessageSource.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultPollableMessageSource.java index abb2b0a42..e3d0f4cfb 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultPollableMessageSource.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultPollableMessageSource.java @@ -62,7 +62,10 @@ import org.springframework.util.Assert; * @since 2.0 * */ -public class DefaultPollableMessageSource implements PollableMessageSource, Lifecycle, RetryListener { +public class DefaultPollableMessageSource + implements PollableMessageSource, Lifecycle, RetryListener { + + protected static final ThreadLocal attributesHolder = new ThreadLocal(); private static final DirectChannel dummyChannel = new DirectChannel(); @@ -70,8 +73,6 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life dummyChannel.setBeanName("dummy.required.by.nonnull.api"); } - protected static final ThreadLocal attributesHolder = new ThreadLocal(); - private final List interceptors = new ArrayList<>(); private final MessagingTemplate messagingTemplate = new MessagingTemplate(); @@ -95,7 +96,8 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life /** * @param messageConverter instance of {@link SmartMessageConverter}. Can be null. */ - public DefaultPollableMessageSource(@Nullable SmartMessageConverter messageConverter) { + public DefaultPollableMessageSource( + @Nullable SmartMessageConverter messageConverter) { this.messageConverter = messageConverter; } @@ -124,7 +126,8 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life } final ReceiveAdvice advice = new ReceiveAdvice(); advice.interceptors.addAll(this.interceptors); - NameMatchMethodPointcutAdvisor sourceAdvisor = new NameMatchMethodPointcutAdvisor(advice); + NameMatchMethodPointcutAdvisor sourceAdvisor = new NameMatchMethodPointcutAdvisor( + advice); sourceAdvisor.addMethodName("receive"); pf.addAdvisor(sourceAdvisor); this.source = (MessageSource) pf.getProxy(); @@ -153,7 +156,8 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life this.errorMessageStrategy = errorMessageStrategy; } - public void setAttributesProvider(BiConsumer> attributesProvider) { + public void setAttributesProvider( + BiConsumer> attributesProvider) { this.attributesProvider = attributesProvider; } @@ -214,8 +218,8 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life } catch (MessagingException e) { if (this.retryTemplate == null && !shouldRequeue(e)) { - this.messagingTemplate - .send(this.errorChannel, this.errorMessageStrategy.buildErrorMessage(e, attributesHolder.get())); + this.messagingTemplate.send(this.errorChannel, this.errorMessageStrategy + .buildErrorMessage(e, attributesHolder.get())); return true; } else if (!ackCallback.isAcknowledged() && shouldRequeue(e)) { @@ -232,8 +236,8 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life } catch (Exception e) { AckUtils.autoNack(ackCallback); - if (e instanceof MessageHandlingException - && ((MessageHandlingException) e).getFailedMessage().equals(message)) { + if (e instanceof MessageHandlingException && ((MessageHandlingException) e) + .getFailedMessage().equals(message)) { throw (MessageHandlingException) e; } throw new MessageHandlingException(message, e); @@ -254,7 +258,8 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life } @Override - public boolean open(RetryContext context, RetryCallback callback) { + public boolean open(RetryContext context, + RetryCallback callback) { if (DefaultPollableMessageSource.this.recoveryCallback != null) { attributesHolder.set(context); } @@ -262,33 +267,36 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life } @Override - public void close(RetryContext context, RetryCallback callback, - Throwable throwable) { + public void close(RetryContext context, + RetryCallback callback, Throwable throwable) { attributesHolder.remove(); } @Override - public void onError(RetryContext context, RetryCallback callback, - Throwable throwable) { + public void onError(RetryContext context, + RetryCallback callback, Throwable throwable) { // Empty } /** - * Receives Message from the source and converts its payload to a provided type. - * Can return null + * Receives Message from the source and converts its payload to a provided type. Can + * return null + * @param type type reference + * @return received message */ private Message receive(ParameterizedTypeReference type) { Message message = this.source.receive(); if (message != null && type != null && this.messageConverter != null) { - Class targetType = type == null ? Object.class : - type.getType() instanceof Class ? (Class) type.getType() : Object.class; + Class targetType = type == null ? Object.class + : type.getType() instanceof Class ? (Class) type.getType() + : Object.class; Object payload = this.messageConverter.fromMessage(message, targetType, type); if (payload == null) { - throw new MessageConversionException(message, "No converter could convert Message"); + throw new MessageConversionException(message, + "No converter could convert Message"); } message = MessageBuilder.withPayload(payload) - .copyHeaders(message.getHeaders()) - .build(); + .copyHeaders(message.getHeaders()).build(); } return message; } @@ -318,7 +326,8 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life if (needAttributes) { AttributeAccessor attributes = attributesHolder.get(); if (attributes != null) { - attributes.setAttribute(ErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEY, message); + attributes.setAttribute(ErrorMessageUtils.INPUT_MESSAGE_CONTEXT_KEY, + message); if (this.attributesProvider != null) { this.attributesProvider.accept(attributes, message); } @@ -330,4 +339,5 @@ public class DefaultPollableMessageSource implements PollableMessageSource, Life setAttributesIfNecessary(message); doHandleMessage(handler, message); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DirectHandler.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DirectHandler.java index c45ade875..0988962c6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DirectHandler.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DirectHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/EmbeddedHeaderUtils.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/EmbeddedHeaderUtils.java index 3eaf622e5..90b75ca88 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/EmbeddedHeaderUtils.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/EmbeddedHeaderUtils.java @@ -42,7 +42,6 @@ import org.springframework.util.ObjectUtils; * @author Gary Russell * @author Ilayaperumal Gopinathan * @author Marius Bogoevici - * * @since 1.2 */ public abstract class EmbeddedHeaderUtils { @@ -50,14 +49,20 @@ public abstract class EmbeddedHeaderUtils { private static final Jackson2JsonObjectMapper objectMapper = new Jackson2JsonObjectMapper(); public static String decodeExceptionMessage(Message requestMessage) { - return "Could not convert message: " + DatatypeConverter.printHexBinary((byte[]) requestMessage.getPayload()); + return "Could not convert message: " + + DatatypeConverter.printHexBinary((byte[]) requestMessage.getPayload()); } /** * Return a new message where some of the original headers of {@code original} have * been embedded into the new message payload. + * @param original original message + * @param headers headers to embedd + * @return a new message + * @throws Exception when message couldn't be generated */ - public static byte[] embedHeaders(MessageValues original, String... headers) throws Exception { + public static byte[] embedHeaders(MessageValues original, String... headers) + throws Exception { byte[][] headerValues = new byte[headers.length][]; int n = 0; int headerCount = 0; @@ -75,7 +80,8 @@ public abstract class EmbeddedHeaderUtils { } } // 0xff, n(1), [ [lenHdr(1), hdr, lenValue(4), value] ... ] - byte[] newPayload = new byte[((byte[]) original.getPayload()).length + headersLength + headerCount * 5 + 2]; + byte[] newPayload = new byte[((byte[]) original.getPayload()).length + + headersLength + headerCount * 5 + 2]; ByteBuffer byteBuffer = ByteBuffer.wrap(newPayload); byteBuffer.put((byte) 0xff); // signal new format byteBuffer.put((byte) headerCount); @@ -96,17 +102,20 @@ public abstract class EmbeddedHeaderUtils { * Return a message where headers, that were originally embedded into the payload, * have been promoted back to actual headers. The new payload is now the original * payload. - * * @param message the message to extract headers * @param copyRequestHeaders boolean value to specify if the request headers should be * copied + * @return wrapped message values + * @throws Exception when extraction failed */ - public static MessageValues extractHeaders(Message message, boolean copyRequestHeaders) throws Exception { - return extractHeaders(message.getPayload(), copyRequestHeaders, message.getHeaders()); + public static MessageValues extractHeaders(Message message, + boolean copyRequestHeaders) throws Exception { + return extractHeaders(message.getPayload(), copyRequestHeaders, + message.getHeaders()); } - private static MessageValues extractHeaders(byte[] payload, boolean copyRequestHeaders, - MessageHeaders requestHeaders) throws Exception { + private static MessageValues extractHeaders(byte[] payload, + boolean copyRequestHeaders, MessageHeaders requestHeaders) throws Exception { ByteBuffer byteBuffer = ByteBuffer.wrap(payload); int headerCount = byteBuffer.get() & 0xff; if (headerCount == 0xff) { @@ -114,20 +123,24 @@ public abstract class EmbeddedHeaderUtils { Map headers = new HashMap(); for (int i = 0; i < headerCount; i++) { int len = byteBuffer.get() & 0xff; - String headerName = new String(payload, byteBuffer.position(), len, "UTF-8"); + String headerName = new String(payload, byteBuffer.position(), len, + "UTF-8"); byteBuffer.position(byteBuffer.position() + len); len = byteBuffer.getInt(); - String headerValue = new String(payload, byteBuffer.position(), len, "UTF-8"); + String headerValue = new String(payload, byteBuffer.position(), len, + "UTF-8"); Object headerContent = objectMapper.fromJson(headerValue, Object.class); headers.put(headerName, headerContent); byteBuffer.position(byteBuffer.position() + len); } byte[] newPayload = new byte[byteBuffer.remaining()]; byteBuffer.get(newPayload); - return buildMessageValues(newPayload, headers, copyRequestHeaders, requestHeaders); + return buildMessageValues(newPayload, headers, copyRequestHeaders, + requestHeaders); } else { - return buildMessageValues(payload, new HashMap<>(), copyRequestHeaders, requestHeaders); + return buildMessageValues(payload, new HashMap<>(), copyRequestHeaders, + requestHeaders); } } @@ -135,17 +148,17 @@ public abstract class EmbeddedHeaderUtils { * Return a message where headers, that were originally embedded into the payload, * have been promoted back to actual headers. The new payload is now the original * payload. - * * @param payload the message payload * @return the message with extracted headers - * @throws Exception + * @throws Exception when extraction failed */ public static MessageValues extractHeaders(byte[] payload) throws Exception { return extractHeaders(payload, false, null); } - private static MessageValues buildMessageValues(byte[] payload, Map headers, - boolean copyRequestHeaders, MessageHeaders requestHeaders) { + private static MessageValues buildMessageValues(byte[] payload, + Map headers, boolean copyRequestHeaders, + MessageHeaders requestHeaders) { MessageValues messageValues = new MessageValues(payload, headers); if (copyRequestHeaders && requestHeaders != null) { messageValues.copyHeadersIfAbsent(requestHeaders); @@ -159,18 +172,19 @@ public abstract class EmbeddedHeaderUtils { headersToMap = BinderHeaders.STANDARD_HEADERS; } else { - String[] combinedHeadersToMap = Arrays.copyOfRange(BinderHeaders.STANDARD_HEADERS, 0, + String[] combinedHeadersToMap = Arrays.copyOfRange( + BinderHeaders.STANDARD_HEADERS, 0, BinderHeaders.STANDARD_HEADERS.length + configuredHeaders.length); - System.arraycopy(configuredHeaders, 0, combinedHeadersToMap, BinderHeaders.STANDARD_HEADERS.length, - configuredHeaders.length); + System.arraycopy(configuredHeaders, 0, combinedHeadersToMap, + BinderHeaders.STANDARD_HEADERS.length, configuredHeaders.length); headersToMap = combinedHeadersToMap; } return headersToMap; } /** - * Return true if the bytes might have embedded headers. - * (First byte is 0xff and long enough for at least one header). + * Return true if the bytes might have embedded headers. (First byte is 0xff and long + * enough for at least one header). * @param bytes the array. * @return true if it may have embedded headers. */ diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedBindingProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedBindingProperties.java index d3537e4ad..c257713bd 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedBindingProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedBindingProperties.java @@ -20,6 +20,8 @@ package org.springframework.cloud.stream.binder; * Properties that extend the common binding properties for a particular binder * implementation. * + * @param consumer properties type + * @param

producer properties type * @author Marius Bogoevici * @author Mark Fisher * @author Soby Chacko @@ -32,14 +34,14 @@ public interface ExtendedBindingProperties { /** * Extended binding properties can define a default prefix to place all the extended - * common producer and consumer properties. For example, if the binder type is foo - * it is convenient to specify common extended properties for the producer or consumer - * across multiple bindings in the form of `spring.cloud.stream.foo.default.producer.x=y` - * or `spring.cloud.stream.foo.default.consumer.x=y`. + * common producer and consumer properties. For example, if the binder type is foo it + * is convenient to specify common extended properties for the producer or consumer + * across multiple bindings in the form of + * `spring.cloud.stream.foo.default.producer.x=y` or + * `spring.cloud.stream.foo.default.consumer.x=y`. * * The binding process will use this defaults prefix to resolve any common extended * producer and consumer properties. - * * @return default prefix for extended properties * @since 2.1.0 */ @@ -47,12 +49,13 @@ public interface ExtendedBindingProperties { /** * - * Extended properties class which should be a subclass of {@link BinderSpecificPropertiesProvider} - * against which default extended producer and consumer properties - * are resolved. - * - * @return extended properties class that contains extended producer/consumer properties + * Extended properties class which should be a subclass of + * {@link BinderSpecificPropertiesProvider} against which default extended producer + * and consumer properties are resolved. + * @return extended properties class that contains extended producer/consumer + * properties * @since 2.1.0 */ Class getExtendedPropertiesEntryClass(); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedConsumerProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedConsumerProperties.java index afa168306..88fac94c4 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedConsumerProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedConsumerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ package org.springframework.cloud.stream.binder; * Extension of {@link ConsumerProperties} to be used with an * {@link ExtendedPropertiesBinder}. * + * @param extension type * @author Marius Bogoevici */ public class ExtendedConsumerProperties extends ConsumerProperties { @@ -31,6 +32,7 @@ public class ExtendedConsumerProperties extends ConsumerProperties { } public T getExtension() { - return extension; + return this.extension; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedProducerProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedProducerProperties.java index 379b93310..ef879f884 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedProducerProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedProducerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-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. @@ -17,6 +17,7 @@ package org.springframework.cloud.stream.binder; /** + * @param extension type * @author Marius Bogoevici */ public class ExtendedProducerProperties extends ProducerProperties { @@ -28,7 +29,7 @@ public class ExtendedProducerProperties extends ProducerProperties { } public T getExtension() { - return extension; + return this.extension; } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinder.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinder.java index 453d2805a..0803bb712 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinder.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,9 @@ package org.springframework.cloud.stream.binder; * operations, it allows the binder to provide values for the additional properties it * expects on the bindings. * + * @param binder type + * @param consumer type + * @param

producer type * @author Marius Bogoevici */ public interface ExtendedPropertiesBinder diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/FinalRethrowingErrorMessageHandler.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/FinalRethrowingErrorMessageHandler.java index 6c0602e7d..397716ddd 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/FinalRethrowingErrorMessageHandler.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/FinalRethrowingErrorMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -23,20 +23,22 @@ import org.springframework.messaging.MessagingException; /** * A MessageHandler that always is the last subscriber (on a {@link BinderErrorChannel}) * that throws an exception if it the only subscriber (aside from the bridge to the global - * error channel). It is typically only used if a binder implementation does not return - * a handled from {@code getErrorMessageHandler()}. + * error channel). It is typically only used if a binder implementation does not return a + * handled from {@code getErrorMessageHandler()}. * * @author Gary Russell * @since 1.3 * */ -class FinalRethrowingErrorMessageHandler implements MessageHandler, LastSubscriberMessageHandler { +class FinalRethrowingErrorMessageHandler + implements MessageHandler, LastSubscriberMessageHandler { private final LastSubscriberAwareChannel errorChannel; private final boolean defaultErrorChannelPresent; - FinalRethrowingErrorMessageHandler(LastSubscriberAwareChannel errorChannel, boolean defaultErrorChannelPresent) { + FinalRethrowingErrorMessageHandler(LastSubscriberAwareChannel errorChannel, + boolean defaultErrorChannelPresent) { this.errorChannel = errorChannel; this.defaultErrorChannelPresent = defaultErrorChannelPresent; } @@ -52,7 +54,8 @@ class FinalRethrowingErrorMessageHandler implements MessageHandler, LastSubscrib throw (MessagingException) message.getPayload(); } else { - throw new MessagingException((Message) null, (Throwable) message.getPayload()); + throw new MessagingException((Message) null, + (Throwable) message.getPayload()); } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/JavaClassMimeTypeUtils.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/JavaClassMimeTypeUtils.java index b80adec4a..e2a2df53a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/JavaClassMimeTypeUtils.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/JavaClassMimeTypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,19 +36,19 @@ public abstract class JavaClassMimeTypeUtils { /** * Convert payload to {@link MimeType} based on the content type on the message. - * * @param payload the payload to convert * @param originalContentType content type on the message * @return converted {@link MimeType} */ - public static MimeType mimeTypeFromObject(Object payload, String originalContentType) { + public static MimeType mimeTypeFromObject(Object payload, + String originalContentType) { Assert.notNull(payload, "payload object cannot be null."); if (payload instanceof byte[]) { return MimeTypeUtils.APPLICATION_OCTET_STREAM; } if (payload instanceof String) { - return MimeTypeUtils.APPLICATION_JSON_VALUE.equals(originalContentType) ? MimeTypeUtils.APPLICATION_JSON - : MimeTypeUtils.TEXT_PLAIN; + return MimeTypeUtils.APPLICATION_JSON_VALUE.equals(originalContentType) + ? MimeTypeUtils.APPLICATION_JSON : MimeTypeUtils.TEXT_PLAIN; } String className = payload.getClass().getName(); MimeType mimeType = mimeTypesCache.get(className); @@ -59,14 +59,17 @@ public abstract class JavaClassMimeTypeUtils { // "[Ljava.lang.String;" or multi-dimensional // "[[[Ljava.lang.String;" if (modifiedClassName.endsWith(";")) { - modifiedClassName = modifiedClassName.substring(0, modifiedClassName.length() - 1); + modifiedClassName = modifiedClassName.substring(0, + modifiedClassName.length() - 1); } // Wrap in quotes to handle the illegal '[' character modifiedClassName = "\"" + modifiedClassName + "\""; } - mimeType = MimeType.valueOf("application/x-java-object;type=" + modifiedClassName); + mimeType = MimeType + .valueOf("application/x-java-object;type=" + modifiedClassName); mimeTypesCache.put(className, mimeType); } return mimeType; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberAwareChannel.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberAwareChannel.java index b0d818f2c..9352d22c7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberAwareChannel.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberAwareChannel.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ package org.springframework.cloud.stream.binder; import org.springframework.messaging.SubscribableChannel; /** - * A channel that can ensure a {@code LastSubscriberMessageHandler} is always - * the last subscriber. + * A channel that can ensure a {@code LastSubscriberMessageHandler} is always the last + * subscriber. * * @author Gary Russell * @since 1.3 diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberMessageHandler.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberMessageHandler.java index 0579a8a2e..5c24ac2f9 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberMessageHandler.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/LastSubscriberMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/MessageValues.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/MessageValues.java index ef6e93e3d..f649e7f84 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/MessageValues.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/MessageValues.java @@ -29,6 +29,7 @@ import org.springframework.util.Assert; /** * A mutable type for allowing {@link Binder} implementations to transform and enrich * message content more efficiently. + * * @author David Turanski * @author Marius Bogoevici */ @@ -58,11 +59,11 @@ public class MessageValues implements Map { * @return the payload */ public Object getPayload() { - return payload; + return this.payload; } /** - * Set the payload + * Set the payload. * @param payload any non null object. */ public void setPayload(Object payload) { @@ -71,7 +72,7 @@ public class MessageValues implements Map { } public Map getHeaders() { - return headers; + return this.headers; } /** @@ -81,7 +82,8 @@ public class MessageValues implements Map { * @return the Message */ public Message toMessage(MessageBuilderFactory messageBuilderFactory) { - return messageBuilderFactory.withPayload(this.payload).copyHeaders(this.headers).build(); + return messageBuilderFactory.withPayload(this.payload).copyHeaders(this.headers) + .build(); } /** @@ -95,62 +97,62 @@ public class MessageValues implements Map { @Override public int size() { - return headers.size(); + return this.headers.size(); } @Override public boolean isEmpty() { - return headers.isEmpty(); + return this.headers.isEmpty(); } @Override public boolean containsKey(Object key) { - return headers.containsKey(key); + return this.headers.containsKey(key); } @Override public boolean containsValue(Object value) { - return headers.containsValue(value); + return this.headers.containsValue(value); } @Override public Object get(Object key) { - return headers.get(key); + return this.headers.get(key); } @Override public Object put(String key, Object value) { - return headers.put(key, value); + return this.headers.put(key, value); } @Override public Object remove(Object key) { - return headers.remove(key); + return this.headers.remove(key); } @Override public void putAll(Map m) { - headers.putAll(m); + this.headers.putAll(m); } @Override public void clear() { - headers.clear(); + this.headers.clear(); } @Override public Set keySet() { - return headers.keySet(); + return this.headers.keySet(); } @Override public Collection values() { - return headers.values(); + return this.headers.values(); } @Override public Set> entrySet() { - return headers.entrySet(); + return this.headers.entrySet(); } public void copyHeadersIfAbsent(Map headersToCopy) { @@ -160,4 +162,5 @@ public class MessageValues implements Map { } } } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionHandler.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionHandler.java index a6370677b..3635bd597 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionHandler.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionHandler.java @@ -46,7 +46,6 @@ public class PartitionHandler { /** * Construct a {@code PartitionHandler}. - * * @param evaluationContext evaluation context for binder * @param properties binder properties * @param partitionKeyExtractorStrategy PartitionKeyExtractor strategy @@ -60,7 +59,7 @@ public class PartitionHandler { this.producerProperties = properties; this.partitionKeyExtractorStrategy = partitionKeyExtractorStrategy; this.partitionSelectorStrategy = partitionSelectorStrategy; - this.partitionCount = producerProperties.getPartitionCount(); + this.partitionCount = this.producerProperties.getPartitionCount(); } /** @@ -71,7 +70,6 @@ public class PartitionHandler { this.partitionCount = partitionCount; } - /** * Determine the partition to which to send this message. *

@@ -85,7 +83,6 @@ public class PartitionHandler { * expression is provided, the key will be passed to the binder partition strategy * along with the {@code partitionCount}. The default partition strategy uses * {@code key.hashCode()}, and the result will be the mod of that value. - * * @param message the message. * @return the partition */ @@ -94,11 +91,12 @@ public class PartitionHandler { int partition; if (this.producerProperties.getPartitionSelectorExpression() != null) { - partition = this.producerProperties.getPartitionSelectorExpression().getValue( - this.evaluationContext, key, Integer.class); + partition = this.producerProperties.getPartitionSelectorExpression() + .getValue(this.evaluationContext, key, Integer.class); } else { - partition = this.partitionSelectorStrategy.selectPartition(key, this.partitionCount); + partition = this.partitionSelectorStrategy.selectPartition(key, + this.partitionCount); } // protection in case a user selector returns a negative. return Math.abs(partition % this.partitionCount); @@ -107,7 +105,8 @@ public class PartitionHandler { private Object extractKey(Message message) { Object key = invokeKeyExtractor(message); if (key == null && this.producerProperties.getPartitionKeyExpression() != null) { - key = this.producerProperties.getPartitionKeyExpression().getValue(this.evaluationContext, message); + key = this.producerProperties.getPartitionKeyExpression() + .getValue(this.evaluationContext, message); } Assert.notNull(key, "Partition key cannot be null"); @@ -115,7 +114,7 @@ public class PartitionHandler { } private Object invokeKeyExtractor(Message message) { - if (partitionKeyExtractorStrategy != null) { + if (this.partitionKeyExtractorStrategy != null) { return this.partitionKeyExtractorStrategy.extractKey(message); } return null; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionKeyExtractorStrategy.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionKeyExtractorStrategy.java index a4b825462..9d1801913 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionKeyExtractorStrategy.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionKeyExtractorStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionSelectorStrategy.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionSelectorStrategy.java index 79eb0cd44..89e4b21c3 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionSelectorStrategy.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PartitionSelectorStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,10 +29,8 @@ public interface PartitionSelectorStrategy { * {@code someValue % partitionCount}. The caller will apply that same modulo * operation (as well as enforcing absolute value) if the value exceeds partitionCount * - 1. - * * @param key the key * @param partitionCount the number of partitions - * * @return the partition */ int selectPartition(Object key, int partitionCount); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableConsumerBinder.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableConsumerBinder.java index ff3e0f58b..3228b7a4c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableConsumerBinder.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableConsumerBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -21,7 +21,6 @@ package org.springframework.cloud.stream.binder; * * @param the polled consumer handler type. * @param the consumer properties type. - * * @author Gary Russell * @since 2.0 * @@ -38,7 +37,8 @@ public interface PollableConsumerBinder { */ default Binding> bindPollableConsumer(String name, String group, PollableSource inboundBindTarget, C consumerProperties) { - throw new UnsupportedOperationException("This binder does not support pollable consumers"); + throw new UnsupportedOperationException( + "This binder does not support pollable consumers"); } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableMessageSource.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableMessageSource.java index 9e765ffa9..e84be09e7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableMessageSource.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableMessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableSource.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableSource.java index b9ecc0f16..3a8a9d9f0 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableSource.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/PollableSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -22,7 +22,6 @@ import org.springframework.core.ParameterizedTypeReference; * A mechanism to poll a consumer. * * @param the handler type to process the result of the poll. - * * @author Gary Russell * @since 2.0 * diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ProducerProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ProducerProperties.java index bd058d00f..6a58f4336 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ProducerProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/ProducerProperties.java @@ -42,7 +42,7 @@ import org.springframework.expression.Expression; public class ProducerProperties { /** - * Signals if this producer needs to be started automatically + * Signals if this producer needs to be started automatically. * * Default: true */ @@ -58,9 +58,8 @@ public class ProducerProperties { private Class partitionKeyExtractorClass; /** - * The name of the bean that implements {@link PartitionKeyExtractorStrategy}\. - * Used to extract a key used to compute the partition id (see 'partitionSelector*') - *
+ * The name of the bean that implements {@link PartitionKeyExtractorStrategy}\. Used + * to extract a key used to compute the partition id (see 'partitionSelector*')
* Mutually exclusive with 'partitionKeyExpression'. */ private String partitionKeyExtractorName; @@ -72,9 +71,8 @@ public class ProducerProperties { private Class partitionSelectorClass; /** - * The name of the bean that implements {@link PartitionSelectorStrategy}\. - * Used to determine partition id based on partition key (see 'partitionKeyExtractor*'). - *
+ * The name of the bean that implements {@link PartitionSelectorStrategy}\. Used to + * determine partition id based on partition key (see 'partitionKeyExtractor*').
* Mutually exclusive with 'partitionSelectorExpression'. */ private String partitionSelectorName; @@ -93,7 +91,7 @@ public class ProducerProperties { private boolean errorChannelEnabled = false; public Expression getPartitionKeyExpression() { - return partitionKeyExpression; + return this.partitionKeyExpression; } public void setPartitionKeyExpression(Expression partitionKeyExpression) { @@ -102,7 +100,7 @@ public class ProducerProperties { @Deprecated public Class getPartitionKeyExtractorClass() { - return partitionKeyExtractorClass; + return this.partitionKeyExtractorClass; } @Deprecated @@ -111,13 +109,14 @@ public class ProducerProperties { } public boolean isPartitioned() { - return this.partitionKeyExpression != null || this.partitionKeyExtractorName != null + return this.partitionKeyExpression != null + || this.partitionKeyExtractorName != null || this.partitionKeyExtractorClass != null; } @Deprecated public Class getPartitionSelectorClass() { - return partitionSelectorClass; + return this.partitionSelectorClass; } @Deprecated @@ -126,7 +125,7 @@ public class ProducerProperties { } public Expression getPartitionSelectorExpression() { - return partitionSelectorExpression; + return this.partitionSelectorExpression; } public void setPartitionSelectorExpression(Expression partitionSelectorExpression) { @@ -135,7 +134,7 @@ public class ProducerProperties { @Min(value = 1, message = "Partition count should be greater than zero.") public int getPartitionCount() { - return partitionCount; + return this.partitionCount; } public void setPartitionCount(int partitionCount) { @@ -143,7 +142,7 @@ public class ProducerProperties { } public String[] getRequiredGroups() { - return requiredGroups; + return this.requiredGroups; } public void setRequiredGroups(String... requiredGroups) { @@ -152,12 +151,14 @@ public class ProducerProperties { @AssertTrue(message = "Partition key expression and partition key extractor class properties are mutually exclusive.") public boolean isValidPartitionKeyProperty() { - return (this.partitionKeyExpression == null) || (this.partitionKeyExtractorClass == null); + return (this.partitionKeyExpression == null) + || (this.partitionKeyExtractorClass == null); } @AssertTrue(message = "Partition selector class and partition selector expression properties are mutually exclusive.") public boolean isValidPartitionSelectorProperty() { - return (this.partitionSelectorClass == null) || (this.partitionSelectorExpression == null); + return (this.partitionSelectorClass == null) + || (this.partitionSelectorExpression == null); } public HeaderMode getHeaderMode() { @@ -185,7 +186,7 @@ public class ProducerProperties { } public String getPartitionKeyExtractorName() { - return partitionKeyExtractorName; + return this.partitionKeyExtractorName; } public void setPartitionKeyExtractorName(String partitionKeyExtractorName) { @@ -193,7 +194,7 @@ public class ProducerProperties { } public String getPartitionSelectorName() { - return partitionSelectorName; + return this.partitionSelectorName; } public void setPartitionSelectorName(String partitionSelectorName) { @@ -201,7 +202,7 @@ public class ProducerProperties { } public boolean isAutoStartup() { - return autoStartup; + return this.autoStartup; } public void setAutoStartup(boolean autoStartup) { @@ -211,11 +212,13 @@ public class ProducerProperties { static class ExpressionSerializer extends JsonSerializer { @Override - public void serialize(Expression expression, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) - throws IOException { + public void serialize(Expression expression, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { if (expression != null) { jsonGenerator.writeString(expression.getExpressionString()); } } + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/RequeueCurrentMessageException.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/RequeueCurrentMessageException.java index 8b58fc5a9..ba5fc37e3 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/RequeueCurrentMessageException.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/RequeueCurrentMessageException.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingLifecycle.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingLifecycle.java index 9841386fd..8bfea0624 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingLifecycle.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingLifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,45 +21,46 @@ import java.util.Map; import org.springframework.context.SmartLifecycle; /** - * Base implementation of lifecycle operations for {@link BindingService} - * aware {@link Bindable}s. - * - * @see InputBindingLifecycle - * @see OutputBindingLifecycle + * Base implementation of lifecycle operations for {@link BindingService} aware + * {@link Bindable}s. * * @author Oleg Zhurakousky + * @see InputBindingLifecycle + * @see OutputBindingLifecycle */ abstract class AbstractBindingLifecycle implements SmartLifecycle { + final BindingService bindingService; private final Map bindables; private volatile boolean running; - AbstractBindingLifecycle(BindingService bindingService, Map bindables) { + AbstractBindingLifecycle(BindingService bindingService, + Map bindables) { this.bindingService = bindingService; this.bindables = bindables; } @Override public void start() { - if (!running) { - bindables.values().forEach(this::doStartWithBindable); + if (!this.running) { + this.bindables.values().forEach(this::doStartWithBindable); this.running = true; } } @Override public void stop() { - if (running) { - bindables.values().forEach(this::doStopWithBindable); + if (this.running) { + this.bindables.values().forEach(this::doStopWithBindable); this.running = false; } } @Override public boolean isRunning() { - return running; + return this.running; } @Override @@ -78,4 +79,5 @@ abstract class AbstractBindingLifecycle implements SmartLifecycle { abstract void doStartWithBindable(Bindable bindable); abstract void doStopWithBindable(Bindable bindable); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingTargetFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingTargetFactory.java index 8c6806a80..8fd11b7d0 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingTargetFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/AbstractBindingTargetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import org.springframework.util.Assert; * A {@link BindingTargetFactory} implementation that restricts the type of binding target * to a specified class and its supertypes. * + * @param type of binding target * @author Marius Bogoevici */ public abstract class AbstractBindingTargetFactory implements BindingTargetFactory { @@ -43,4 +44,5 @@ public abstract class AbstractBindingTargetFactory implements BindingTargetFa @Override public abstract T createOutput(String name); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java index 5dd7a931a..eab6f2ebd 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java @@ -35,6 +35,7 @@ public interface Bindable { /** * Binds all the inputs associated with this instance. * @deprecated as of 2.0 in favor of {@link #createAndBindInputs(BindingService)} + * @param adapter binding service */ @Deprecated default void bindInputs(BindingService adapter) { @@ -55,9 +56,11 @@ public interface Bindable { /** * Binds all the outputs associated with this instance. * @deprecated as of 2.0 in favor of {@link #createAndBindOutputs(BindingService)} + * @param adapter binding service */ @Deprecated - default void bindOutputs(BindingService adapter) {} + default void bindOutputs(BindingService adapter) { + } /** * Binds all the outputs associated with this instance. @@ -72,16 +75,21 @@ public interface Bindable { /** * Unbinds all the inputs associated with this instance. + * @param adapter binding service */ - default void unbindInputs(BindingService adapter) {} + default void unbindInputs(BindingService adapter) { + } /** * Unbinds all the outputs associated with this instance. + * @param adapter binding service */ - default void unbindOutputs(BindingService adapter) {} + default void unbindOutputs(BindingService adapter) { + } /** * Enumerates all the input binding names. + * @return input binding names */ default Set getInputs() { return Collections.emptySet(); @@ -89,6 +97,7 @@ public interface Bindable { /** * Enumerates all the output binding names. + * @return output binding names */ default Set getOutputs() { return Collections.emptySet(); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java index ef1dc244f..90e77a1d0 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java @@ -47,16 +47,16 @@ import org.springframework.util.StringUtils; /** * {@link FactoryBean} for instantiating the interfaces specified via - * {@link EnableBinding} + * {@link EnableBinding}. * * @author Marius Bogoevici * @author David Syer * @author Ilayaperumal Gopinathan * @author Oleg Zhurakousky - * * @see EnableBinding */ -public class BindableProxyFactory implements MethodInterceptor, FactoryBean, Bindable, InitializingBean { +public class BindableProxyFactory + implements MethodInterceptor, FactoryBean, Bindable, InitializingBean { private static Log log = LogFactory.getLog(BindableProxyFactory.class); @@ -88,24 +88,26 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean returnType = method.getReturnType(); - Object sharedBindingTarget = locateSharedBindingTarget(name, returnType); + Object sharedBindingTarget = locateSharedBindingTarget(name, + returnType); if (sharedBindingTarget != null) { BindableProxyFactory.this.inputHolders.put(name, new BoundTargetHolder(sharedBindingTarget, false)); } else { BindableProxyFactory.this.inputHolders.put(name, - new BoundTargetHolder(getBindingTargetFactory(returnType).createInput(name), true)); + new BoundTargetHolder(getBindingTargetFactory(returnType) + .createInput(name), true)); } } } @@ -139,16 +145,19 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean returnType = method.getReturnType(); - Object sharedBindingTarget = locateSharedBindingTarget(name, returnType); + Object sharedBindingTarget = locateSharedBindingTarget(name, + returnType); if (sharedBindingTarget != null) { BindableProxyFactory.this.outputHolders.put(name, new BoundTargetHolder(sharedBindingTarget, false)); } else { BindableProxyFactory.this.outputHolders.put(name, - new BoundTargetHolder(getBindingTargetFactory(returnType).createOutput(name), true)); + new BoundTargetHolder(getBindingTargetFactory(returnType) + .createOutput(name), true)); } } } @@ -164,25 +173,32 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean T locateSharedBindingTarget(String name, Class bindingTargetType) { return this.sharedBindingTargetRegistry != null - ? this.sharedBindingTargetRegistry.get(getNamespacePrefixedBindingTargetName(name), bindingTargetType) + ? this.sharedBindingTargetRegistry.get( + getNamespacePrefixedBindingTargetName(name), bindingTargetType) : null; } @@ -219,19 +235,24 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean> createAndBindInputs(BindingService bindingService) { + public Collection> createAndBindInputs( + BindingService bindingService) { List> bindings = new ArrayList<>(); if (log.isDebugEnabled()) { - log.debug(String.format("Binding inputs for %s:%s", this.namespace, this.type)); + log.debug( + String.format("Binding inputs for %s:%s", this.namespace, this.type)); } - for (Map.Entry boundTargetHolderEntry : this.inputHolders.entrySet()) { + for (Map.Entry boundTargetHolderEntry : this.inputHolders + .entrySet()) { String inputTargetName = boundTargetHolderEntry.getKey(); BoundTargetHolder boundTargetHolder = boundTargetHolderEntry.getValue(); if (boundTargetHolder.isBindable()) { if (log.isDebugEnabled()) { - log.debug(String.format("Binding %s:%s:%s", this.namespace, this.type, inputTargetName)); + log.debug(String.format("Binding %s:%s:%s", this.namespace, this.type, + inputTargetName)); } - bindings.addAll(bindingService.bindConsumer(boundTargetHolder.getBoundTarget(), inputTargetName)); + bindings.addAll(bindingService.bindConsumer( + boundTargetHolder.getBoundTarget(), inputTargetName)); } } return bindings; @@ -247,19 +268,24 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean> createAndBindOutputs(BindingService bindingService) { + public Collection> createAndBindOutputs( + BindingService bindingService) { List> bindings = new ArrayList<>(); if (log.isDebugEnabled()) { - log.debug(String.format("Binding outputs for %s:%s", this.namespace, this.type)); + log.debug(String.format("Binding outputs for %s:%s", this.namespace, + this.type)); } - for (Map.Entry boundTargetHolderEntry : this.outputHolders.entrySet()) { + for (Map.Entry boundTargetHolderEntry : this.outputHolders + .entrySet()) { BoundTargetHolder boundTargetHolder = boundTargetHolderEntry.getValue(); String outputTargetName = boundTargetHolderEntry.getKey(); if (boundTargetHolderEntry.getValue().isBindable()) { if (log.isDebugEnabled()) { - log.debug(String.format("Binding %s:%s:%s", this.namespace, this.type, outputTargetName)); + log.debug(String.format("Binding %s:%s:%s", this.namespace, this.type, + outputTargetName)); } - bindings.add(bindingService.bindProducer(boundTargetHolder.getBoundTarget(), outputTargetName)); + bindings.add(bindingService.bindProducer( + boundTargetHolder.getBoundTarget(), outputTargetName)); } } return bindings; @@ -268,13 +294,15 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean boundTargetHolderEntry : this.inputHolders.entrySet()) { + for (Map.Entry boundTargetHolderEntry : this.inputHolders + .entrySet()) { if (boundTargetHolderEntry.getValue().isBindable()) { if (log.isDebugEnabled()) { - log.debug(String.format("Unbinding %s:%s:%s", this.namespace, this.type, - boundTargetHolderEntry.getKey())); + log.debug(String.format("Unbinding %s:%s:%s", this.namespace, + this.type, boundTargetHolderEntry.getKey())); } bindingService.unbindConsumers(boundTargetHolderEntry.getKey()); } @@ -284,9 +312,11 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean boundTargetHolderEntry : this.outputHolders.entrySet()) { + for (Map.Entry boundTargetHolderEntry : this.outputHolders + .entrySet()) { if (boundTargetHolderEntry.getValue().isBindable()) { if (log.isDebugEnabled()) { log.debug(String.format("Binding %s:%s:%s", this.namespace, this.type, @@ -329,5 +359,7 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean bindingTargetFactory, DynamicDestinationsBindable dynamicDestinationsBindable) { - this(bindingService, bindingTargetFactory, dynamicDestinationsBindable, null, null); + this(bindingService, bindingTargetFactory, dynamicDestinationsBindable, null, + null); } @SuppressWarnings("rawtypes") public BinderAwareChannelResolver(BindingService bindingService, AbstractBindingTargetFactory bindingTargetFactory, - DynamicDestinationsBindable dynamicDestinationsBindable, NewDestinationBindingCallback callback) { - this(bindingService, bindingTargetFactory, dynamicDestinationsBindable, callback, null); + DynamicDestinationsBindable dynamicDestinationsBindable, + NewDestinationBindingCallback callback) { + this(bindingService, bindingTargetFactory, dynamicDestinationsBindable, callback, + null); } /** * @deprecated since GlobalChannelInterceptorProcessor is no longer used + * @param bindingService service to bind inputs and outputs + * @param bindingTargetFactory implementation that restricts the type of binding + * target to a specified class and its supertypes + * @param dynamicDestinationsBindable stores the dynamic destination names and handles + * their unbinding. + * @param callback used to configure a new destination before it is bound. + * @param globalChannelInterceptorProcessor applies global interceptors to message + * channel beans */ @SuppressWarnings("rawtypes") @Deprecated public BinderAwareChannelResolver(BindingService bindingService, AbstractBindingTargetFactory bindingTargetFactory, - DynamicDestinationsBindable dynamicDestinationsBindable, NewDestinationBindingCallback callback, + DynamicDestinationsBindable dynamicDestinationsBindable, + NewDestinationBindingCallback callback, GlobalChannelInterceptorProcessor globalChannelInterceptorProcessor) { this.dynamicDestinationsBindable = dynamicDestinationsBindable; Assert.notNull(bindingService, "'bindingService' cannot be null"); @@ -84,7 +97,8 @@ public class BinderAwareChannelResolver extends BeanFactoryMessageChannelDestina @Override public void setBeanFactory(BeanFactory beanFactory) { super.setBeanFactory(beanFactory); - Assert.isTrue(beanFactory instanceof ConfigurableListableBeanFactory, "'beanFactory' must be an instance of ConfigurableListableBeanFactory"); + Assert.isTrue(beanFactory instanceof ConfigurableListableBeanFactory, + "'beanFactory' must be an instance of ConfigurableListableBeanFactory"); this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } @@ -98,9 +112,12 @@ public class BinderAwareChannelResolver extends BeanFactoryMessageChannelDestina // intentionally empty; will check again while holding the monitor } synchronized (this) { - BindingServiceProperties bindingServiceProperties = this.bindingService.getBindingServiceProperties(); - String[] dynamicDestinations = bindingServiceProperties.getDynamicDestinations(); - boolean dynamicAllowed = ObjectUtils.isEmpty(dynamicDestinations) || ObjectUtils.containsElement(dynamicDestinations, channelName); + BindingServiceProperties bindingServiceProperties = this.bindingService + .getBindingServiceProperties(); + String[] dynamicDestinations = bindingServiceProperties + .getDynamicDestinations(); + boolean dynamicAllowed = ObjectUtils.isEmpty(dynamicDestinations) + || ObjectUtils.containsElement(dynamicDestinations, channelName); try { return super.resolveDestination(channelName); } @@ -113,18 +130,25 @@ public class BinderAwareChannelResolver extends BeanFactoryMessageChannelDestina MessageChannel channel = this.bindingTargetFactory.createOutput(channelName); this.beanFactory.registerSingleton(channelName, channel); - //TODO: Investigate if the following call is necessary. - //initializeBean call on the next line also calling the addMatchingInterceptors method in GlobalChannelInterceptorProcessor - //this.instrumentChannelWithGlobalInterceptors(channel, channelName); + // TODO: Investigate if the following call is necessary. + // initializeBean call on the next line also calling the + // addMatchingInterceptors method in GlobalChannelInterceptorProcessor + // this.instrumentChannelWithGlobalInterceptors(channel, channelName); - channel = (MessageChannel) this.beanFactory.initializeBean(channel, channelName); + channel = (MessageChannel) this.beanFactory.initializeBean(channel, + channelName); if (this.newBindingCallback != null) { - ProducerProperties producerProperties = bindingServiceProperties.getProducerProperties(channelName); - Object extendedProducerProperties = this.bindingService.getExtendedProducerProperties(channel, channelName); - this.newBindingCallback.configure(channelName, channel, producerProperties, extendedProducerProperties); - bindingServiceProperties.updateProducerProperties(channelName, producerProperties); + ProducerProperties producerProperties = bindingServiceProperties + .getProducerProperties(channelName); + Object extendedProducerProperties = this.bindingService + .getExtendedProducerProperties(channel, channelName); + this.newBindingCallback.configure(channelName, channel, + producerProperties, extendedProducerProperties); + bindingServiceProperties.updateProducerProperties(channelName, + producerProperties); } - Binding binding = this.bindingService.bindProducer(channel, channelName); + Binding binding = this.bindingService.bindProducer(channel, + channelName); this.dynamicDestinationsBindable.addOutputBinding(channelName, binding); return channel; @@ -133,9 +157,9 @@ public class BinderAwareChannelResolver extends BeanFactoryMessageChannelDestina /** * Configure a new destination before it is bound. + * * @param the extended properties type. If you need to support dynamic binding * with multiple binders, use {@link Object} and cast as needed. - * * @since 2.0 * */ @@ -148,11 +172,12 @@ public class BinderAwareChannelResolver extends BeanFactoryMessageChannelDestina * @param channel the channel that is about to be bound. * @param producerProperties the producer properties. * @param extendedProducerProperties the extended producer properties (type - * depends on binder type and may be null if the binder doesn't support - * extended properties). + * depends on binder type and may be null if the binder doesn't support extended + * properties). */ - void configure(String channelName, MessageChannel channel, ProducerProperties producerProperties, - T extendedProducerProperties); + void configure(String channelName, MessageChannel channel, + ProducerProperties producerProperties, T extendedProducerProperties); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BinderAwareRouterBeanPostProcessor.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BinderAwareRouterBeanPostProcessor.java index c8c78b58b..35e4d27a0 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BinderAwareRouterBeanPostProcessor.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BinderAwareRouterBeanPostProcessor.java @@ -28,13 +28,14 @@ import org.springframework.messaging.core.DestinationResolver; * @author Mark Fisher * @author Gary Russell * @author Oleg Zhurakousky - * - * @deprecated as of 2.0, will be renamed/replaced as it is no longer a BPP and naming is a bit confusing + * @deprecated as of 2.0, will be renamed/replaced as it is no longer a BPP and naming is + * a bit confusing */ @Deprecated public class BinderAwareRouterBeanPostProcessor { - public BinderAwareRouterBeanPostProcessor(AbstractMappingMessageRouter[] routers, DestinationResolver channelResolver) { + public BinderAwareRouterBeanPostProcessor(AbstractMappingMessageRouter[] routers, + DestinationResolver channelResolver) { if (routers != null) { for (AbstractMappingMessageRouter router : routers) { router.setChannelResolver(channelResolver); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingBeanDefinitionRegistryUtils.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingBeanDefinitionRegistryUtils.java index d6f0d1337..7e64cb384 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingBeanDefinitionRegistryUtils.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingBeanDefinitionRegistryUtils.java @@ -41,73 +41,85 @@ import org.springframework.util.StringUtils; @SuppressWarnings("deprecation") public abstract class BindingBeanDefinitionRegistryUtils { - public static void registerInputBindingTargetBeanDefinition(String qualifierValue, String name, - String bindingTargetInterfaceBeanName, String bindingTargetInterfaceMethodName, - BeanDefinitionRegistry registry) { - registerBindingTargetBeanDefinition(Input.class, qualifierValue, name, bindingTargetInterfaceBeanName, - bindingTargetInterfaceMethodName, registry); + public static void registerInputBindingTargetBeanDefinition(String qualifierValue, + String name, String bindingTargetInterfaceBeanName, + String bindingTargetInterfaceMethodName, BeanDefinitionRegistry registry) { + registerBindingTargetBeanDefinition(Input.class, qualifierValue, name, + bindingTargetInterfaceBeanName, bindingTargetInterfaceMethodName, + registry); } - public static void registerOutputBindingTargetBeanDefinition(String qualifierValue, String name, - String bindingTargetInterfaceBeanName, String bindingTargetInterfaceMethodName, - BeanDefinitionRegistry registry) { - registerBindingTargetBeanDefinition(Output.class, qualifierValue, name, bindingTargetInterfaceBeanName, - bindingTargetInterfaceMethodName, registry); + public static void registerOutputBindingTargetBeanDefinition(String qualifierValue, + String name, String bindingTargetInterfaceBeanName, + String bindingTargetInterfaceMethodName, BeanDefinitionRegistry registry) { + registerBindingTargetBeanDefinition(Output.class, qualifierValue, name, + bindingTargetInterfaceBeanName, bindingTargetInterfaceMethodName, + registry); } - private static void registerBindingTargetBeanDefinition(Class qualifier, - String qualifierValue, String name, String bindingTargetInterfaceBeanName, + private static void registerBindingTargetBeanDefinition( + Class qualifier, String qualifierValue, String name, + String bindingTargetInterfaceBeanName, String bindingTargetInterfaceMethodName, BeanDefinitionRegistry registry) { if (registry.containsBeanDefinition(name)) { throw new BeanDefinitionStoreException(bindingTargetInterfaceBeanName, name, - "bean definition with this name already exists - " + registry.getBeanDefinition(name)); + "bean definition with this name already exists - " + + registry.getBeanDefinition(name)); } RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); rootBeanDefinition.setFactoryBeanName(bindingTargetInterfaceBeanName); rootBeanDefinition.setUniqueFactoryMethodName(bindingTargetInterfaceMethodName); - rootBeanDefinition.addQualifier(new AutowireCandidateQualifier(qualifier, qualifierValue)); + rootBeanDefinition + .addQualifier(new AutowireCandidateQualifier(qualifier, qualifierValue)); registry.registerBeanDefinition(name, rootBeanDefinition); } - public static void registerBindingTargetBeanDefinitions(Class type, final String bindingTargetInterfaceBeanName, + public static void registerBindingTargetBeanDefinitions(Class type, + final String bindingTargetInterfaceBeanName, final BeanDefinitionRegistry registry) { ReflectionUtils.doWithMethods(type, method -> { Input input = AnnotationUtils.findAnnotation(method, Input.class); if (input != null) { String name = getBindingTargetName(input, method); - registerInputBindingTargetBeanDefinition(input.value(), name, bindingTargetInterfaceBeanName, - method.getName(), registry); + registerInputBindingTargetBeanDefinition(input.value(), name, + bindingTargetInterfaceBeanName, method.getName(), registry); } Output output = AnnotationUtils.findAnnotation(method, Output.class); if (output != null) { String name = getBindingTargetName(output, method); - registerOutputBindingTargetBeanDefinition(output.value(), name, bindingTargetInterfaceBeanName, - method.getName(), registry); + registerOutputBindingTargetBeanDefinition(output.value(), name, + bindingTargetInterfaceBeanName, method.getName(), registry); } }); } - public static void registerBindingTargetsQualifiedBeanDefinitions(Class parent, Class type, - final BeanDefinitionRegistry registry) { + public static void registerBindingTargetsQualifiedBeanDefinitions(Class parent, + Class type, final BeanDefinitionRegistry registry) { if (type.isInterface()) { - RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(BindableProxyFactory.class); - rootBeanDefinition.addQualifier(new AutowireCandidateQualifier(Bindings.class, parent)); - rootBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(type); + RootBeanDefinition rootBeanDefinition = new RootBeanDefinition( + BindableProxyFactory.class); + rootBeanDefinition + .addQualifier(new AutowireCandidateQualifier(Bindings.class, parent)); + rootBeanDefinition.getConstructorArgumentValues() + .addGenericArgumentValue(type); registry.registerBeanDefinition(type.getName(), rootBeanDefinition); } else { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(type); - rootBeanDefinition.addQualifier(new AutowireCandidateQualifier(Bindings.class, parent)); + rootBeanDefinition + .addQualifier(new AutowireCandidateQualifier(Bindings.class, parent)); registry.registerBeanDefinition(type.getName(), rootBeanDefinition); } } public static String getBindingTargetName(Annotation annotation, Method method) { - Map attrs = AnnotationUtils.getAnnotationAttributes(annotation, false); - if (attrs.containsKey("value") && StringUtils.hasText((CharSequence) attrs.get("value"))) { + Map attrs = AnnotationUtils.getAnnotationAttributes(annotation, + false); + if (attrs.containsKey("value") + && StringUtils.hasText((CharSequence) attrs.get("value"))) { return (String) attrs.get("value"); } return method.getName(); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java index f7ffd121f..9ca56c520 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java @@ -72,14 +72,12 @@ public class BindingService { private final BinderFactory binderFactory; - public BindingService( - BindingServiceProperties bindingServiceProperties, + public BindingService(BindingServiceProperties bindingServiceProperties, BinderFactory binderFactory) { this(bindingServiceProperties, binderFactory, null); } - public BindingService( - BindingServiceProperties bindingServiceProperties, + public BindingService(BindingServiceProperties bindingServiceProperties, BinderFactory binderFactory, TaskScheduler taskScheduler) { this.bindingServiceProperties = bindingServiceProperties; this.binderFactory = binderFactory; @@ -111,14 +109,18 @@ public class BindingService { .getBindingDestination(inputName); if (consumerProperties.isMultiplex()) { - bindings.add(doBindConsumer(input, inputName, binder, consumerProperties, bindingTarget)); + bindings.add(doBindConsumer(input, inputName, binder, consumerProperties, + bindingTarget)); } else { - String[] bindingTargets = StringUtils.commaDelimitedListToStringArray(bindingTarget); + String[] bindingTargets = StringUtils + .commaDelimitedListToStringArray(bindingTarget); for (String target : bindingTargets) { Binding binding = input instanceof PollableSource - ? doBindPollableConsumer(input, inputName, binder, consumerProperties, target) - : doBindConsumer(input, inputName, binder, consumerProperties, target); + ? doBindPollableConsumer(input, inputName, binder, + consumerProperties, target) + : doBindConsumer(input, inputName, binder, consumerProperties, + target); bindings.add(binding); } @@ -128,9 +130,11 @@ public class BindingService { return bindings; } - public Binding doBindConsumer(T input, String inputName, Binder binder, + public Binding doBindConsumer(T input, String inputName, + Binder binder, ConsumerProperties consumerProperties, String target) { - if (this.taskScheduler == null || this.bindingServiceProperties.getBindingRetryInterval() <= 0) { + if (this.taskScheduler == null + || this.bindingServiceProperties.getBindingRetryInterval() <= 0) { return binder.bindConsumer(target, this.bindingServiceProperties.getGroup(inputName), input, consumerProperties); @@ -143,66 +147,77 @@ public class BindingService { } catch (RuntimeException e) { LateBinding late = new LateBinding(); - rescheduleConsumerBinding(input, inputName, binder, consumerProperties, target, late, e); + rescheduleConsumerBinding(input, inputName, binder, consumerProperties, + target, late, e); return late; } } } public void rescheduleConsumerBinding(final T input, final String inputName, - final Binder binder, final ConsumerProperties consumerProperties, - final String target, final LateBinding late, RuntimeException exception) { + final Binder binder, + final ConsumerProperties consumerProperties, final String target, + final LateBinding late, RuntimeException exception) { assertNotIllegalException(exception); - this.log.error("Failed to create consumer binding; retrying in " + - this.bindingServiceProperties.getBindingRetryInterval() + " seconds", exception); + this.log.error("Failed to create consumer binding; retrying in " + + this.bindingServiceProperties.getBindingRetryInterval() + " seconds", + exception); this.scheduleTask(() -> { try { late.setDelegate(binder.bindConsumer(target, - this.bindingServiceProperties.getGroup(inputName), input, consumerProperties)); + this.bindingServiceProperties.getGroup(inputName), input, + consumerProperties)); } catch (RuntimeException e) { - rescheduleConsumerBinding(input, inputName, binder, consumerProperties, target, late, e); + rescheduleConsumerBinding(input, inputName, binder, consumerProperties, + target, late, e); } }); } @SuppressWarnings({ "rawtypes", "unchecked" }) - public Binding doBindPollableConsumer(T input, String inputName, Binder binder, + public Binding doBindPollableConsumer(T input, String inputName, + Binder binder, ConsumerProperties consumerProperties, String target) { - if (this.taskScheduler == null || this.bindingServiceProperties.getBindingRetryInterval() <= 0) { + if (this.taskScheduler == null + || this.bindingServiceProperties.getBindingRetryInterval() <= 0) { return ((PollableConsumerBinder) binder).bindPollableConsumer(target, - this.bindingServiceProperties.getGroup(inputName), (PollableSource) input, - consumerProperties); + this.bindingServiceProperties.getGroup(inputName), + (PollableSource) input, consumerProperties); } else { try { return ((PollableConsumerBinder) binder).bindPollableConsumer(target, - this.bindingServiceProperties.getGroup(inputName), (PollableSource) input, - consumerProperties); + this.bindingServiceProperties.getGroup(inputName), + (PollableSource) input, consumerProperties); } catch (RuntimeException e) { LateBinding late = new LateBinding(); - reschedulePollableConsumerBinding(input, inputName, binder, consumerProperties, target, late, e); + reschedulePollableConsumerBinding(input, inputName, binder, + consumerProperties, target, late, e); return late; } } } @SuppressWarnings({ "rawtypes", "unchecked" }) - public void reschedulePollableConsumerBinding(final T input, final String inputName, - final Binder binder, final ConsumerProperties consumerProperties, - final String target, final LateBinding late, RuntimeException exception) { + public void reschedulePollableConsumerBinding(final T input, + final String inputName, final Binder binder, + final ConsumerProperties consumerProperties, final String target, + final LateBinding late, RuntimeException exception) { assertNotIllegalException(exception); - this.log.error("Failed to create consumer binding; retrying in " + - this.bindingServiceProperties.getBindingRetryInterval() + " seconds", exception); + this.log.error("Failed to create consumer binding; retrying in " + + this.bindingServiceProperties.getBindingRetryInterval() + " seconds", + exception); this.scheduleTask(() -> { try { - late.setDelegate(((PollableConsumerBinder) binder).bindPollableConsumer(target, - this.bindingServiceProperties.getGroup(inputName), (PollableSource) input, - consumerProperties)); + late.setDelegate(((PollableConsumerBinder) binder).bindPollableConsumer( + target, this.bindingServiceProperties.getGroup(inputName), + (PollableSource) input, consumerProperties)); } catch (RuntimeException e) { - reschedulePollableConsumerBinding(input, inputName, binder, consumerProperties, target, late, e); + reschedulePollableConsumerBinding(input, inputName, binder, + consumerProperties, target, late, e); } }); } @@ -225,23 +240,27 @@ public class BindingService { producerProperties = extendedProducerProperties; } validate(producerProperties); - Binding binding = doBindProducer(output, bindingTarget, binder, producerProperties); + Binding binding = doBindProducer(output, bindingTarget, binder, + producerProperties); this.producerBindings.put(outputName, binding); return binding; } @SuppressWarnings("rawtypes") public Object getExtendedProducerProperties(Object output, String outputName) { - Binder binder = getBinder(outputName, output.getClass()); + Binder binder = getBinder(outputName, output.getClass()); if (binder instanceof ExtendedPropertiesBinder) { - return ((ExtendedPropertiesBinder) binder).getExtendedProducerProperties(outputName); + return ((ExtendedPropertiesBinder) binder) + .getExtendedProducerProperties(outputName); } return null; } - public Binding doBindProducer(T output, String bindingTarget, Binder binder, + public Binding doBindProducer(T output, String bindingTarget, + Binder binder, ProducerProperties producerProperties) { - if (this.taskScheduler == null || this.bindingServiceProperties.getBindingRetryInterval() <= 0) { + if (this.taskScheduler == null + || this.bindingServiceProperties.getBindingRetryInterval() <= 0) { return binder.bindProducer(bindingTarget, output, producerProperties); } else { @@ -250,24 +269,29 @@ public class BindingService { } catch (RuntimeException e) { LateBinding late = new LateBinding(); - rescheduleProducerBinding(output, bindingTarget, binder, producerProperties, late, e); + rescheduleProducerBinding(output, bindingTarget, binder, + producerProperties, late, e); return late; } } } public void rescheduleProducerBinding(final T output, final String bindingTarget, - final Binder binder, final ProducerProperties producerProperties, - final LateBinding late, final RuntimeException exception) { + final Binder binder, + final ProducerProperties producerProperties, final LateBinding late, + final RuntimeException exception) { assertNotIllegalException(exception); - this.log.error("Failed to create producer binding; retrying in " + - this.bindingServiceProperties.getBindingRetryInterval() + " seconds", exception); + this.log.error("Failed to create producer binding; retrying in " + + this.bindingServiceProperties.getBindingRetryInterval() + " seconds", + exception); this.scheduleTask(() -> { try { - late.setDelegate(binder.bindProducer(bindingTarget, output, producerProperties)); + late.setDelegate( + binder.bindProducer(bindingTarget, output, producerProperties)); } catch (RuntimeException e) { - rescheduleProducerBinding(output, bindingTarget, binder, producerProperties, late, e); + rescheduleProducerBinding(output, bindingTarget, binder, + producerProperties, late, e); } }); } @@ -279,8 +303,8 @@ public class BindingService { binding.unbind(); } } - else if (log.isWarnEnabled()) { - log.warn("Trying to unbind '" + inputName + "', but no binding found."); + else if (this.log.isWarnEnabled()) { + this.log.warn("Trying to unbind '" + inputName + "', but no binding found."); } } @@ -289,14 +313,13 @@ public class BindingService { if (binding != null) { binding.unbind(); } - else if (log.isWarnEnabled()) { - log.warn("Trying to unbind '" + outputName + "', but no binding found."); + else if (this.log.isWarnEnabled()) { + this.log.warn("Trying to unbind '" + outputName + "', but no binding found."); } } /** * Provided for backwards compatibility. Will be removed in a future version. - * * @return {@link BindingServiceProperties} */ @Deprecated @@ -309,13 +332,14 @@ public class BindingService { } protected Binder getBinder(String channelName, Class bindableType) { - String binderConfigurationName = this.bindingServiceProperties.getBinder(channelName); - return binderFactory.getBinder(binderConfigurationName, bindableType); + String binderConfigurationName = this.bindingServiceProperties + .getBinder(channelName); + return this.binderFactory.getBinder(binderConfigurationName, bindableType); } private void validate(Object properties) { DataBinder dataBinder = new DataBinder(properties); - dataBinder.setValidator(validator); + dataBinder.setValidator(this.validator); dataBinder.validate(); if (dataBinder.getBindingResult().hasErrors()) { throw new IllegalStateException(dataBinder.getBindingResult().toString()); @@ -323,12 +347,14 @@ public class BindingService { } private void scheduleTask(Runnable task) { - this.taskScheduler.schedule(task, new Date(System.currentTimeMillis() + - this.bindingServiceProperties.getBindingRetryInterval() * 1_000)); + this.taskScheduler.schedule(task, new Date(System.currentTimeMillis() + + this.bindingServiceProperties.getBindingRetryInterval() * 1_000)); } - private void assertNotIllegalException(RuntimeException exception) throws RuntimeException { - if (exception instanceof IllegalStateException || exception instanceof IllegalArgumentException) { + private void assertNotIllegalException(RuntimeException exception) + throws RuntimeException { + if (exception instanceof IllegalStateException + || exception instanceof IllegalArgumentException) { throw exception; } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingTargetFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingTargetFactory.java index 492c776fa..01dd82ad2 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingTargetFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingTargetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/CompositeMessageChannelConfigurer.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/CompositeMessageChannelConfigurer.java index f39177d13..5e94fa192 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/CompositeMessageChannelConfigurer.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/CompositeMessageChannelConfigurer.java @@ -23,13 +23,16 @@ import org.springframework.messaging.MessageChannel; /** * {@link MessageChannelConfigurer} that composes all the message channel configurers. + * * @author Ilayaperumal Gopinathan */ -public class CompositeMessageChannelConfigurer implements MessageChannelAndSourceConfigurer { +public class CompositeMessageChannelConfigurer + implements MessageChannelAndSourceConfigurer { private final List messageChannelConfigurers; - public CompositeMessageChannelConfigurer(List messageChannelConfigurers) { + public CompositeMessageChannelConfigurer( + List messageChannelConfigurers) { this.messageChannelConfigurers = messageChannelConfigurers; } @@ -41,18 +44,19 @@ public class CompositeMessageChannelConfigurer implements MessageChannelAndSourc } @Override - public void configureOutputChannel(MessageChannel messageChannel, String channelName) { + public void configureOutputChannel(MessageChannel messageChannel, + String channelName) { for (MessageChannelConfigurer messageChannelConfigurer : this.messageChannelConfigurers) { messageChannelConfigurer.configureOutputChannel(messageChannel, channelName); } } @Override - public void configurePolledMessageSource(PollableMessageSource binding, - String name) { + public void configurePolledMessageSource(PollableMessageSource binding, String name) { this.messageChannelConfigurers.forEach(cconfigurer -> { if (cconfigurer instanceof MessageChannelAndSourceConfigurer) { - ((MessageChannelAndSourceConfigurer) cconfigurer).configurePolledMessageSource(binding, name); + ((MessageChannelAndSourceConfigurer) cconfigurer) + .configurePolledMessageSource(binding, name); } }); } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/ContextStartAfterRefreshListener.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/ContextStartAfterRefreshListener.java index 752915f5b..22f1f3270 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/ContextStartAfterRefreshListener.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/ContextStartAfterRefreshListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,15 +34,18 @@ public class ContextStartAfterRefreshListener private ApplicationContext applicationContext; @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { this.applicationContext = applicationContext; } @Override public void onApplicationEvent(ContextRefreshedEvent event) { - ConfigurableApplicationContext source = (ConfigurableApplicationContext) event.getSource(); + ConfigurableApplicationContext source = (ConfigurableApplicationContext) event + .getSource(); if (source == this.applicationContext && !source.isRunning()) { source.start(); } } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DispatchingStreamListenerMessageHandler.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DispatchingStreamListenerMessageHandler.java index f7cc0d207..e4cad7235 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DispatchingStreamListenerMessageHandler.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DispatchingStreamListenerMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,13 +29,14 @@ import org.springframework.util.Assert; /** * An {@link AbstractReplyProducingMessageHandler} that delegates to a collection of - * internal {@link ConditionalStreamListenerMessageHandlerWrapper} instances, executing the ones that - * match the given expression. + * internal {@link ConditionalStreamListenerMessageHandlerWrapper} instances, executing + * the ones that match the given expression. * * @author Marius Bogoevici * @since 1.2 */ -final class DispatchingStreamListenerMessageHandler extends AbstractReplyProducingMessageHandler { +final class DispatchingStreamListenerMessageHandler + extends AbstractReplyProducingMessageHandler { private final List handlerMethods; @@ -43,10 +44,12 @@ final class DispatchingStreamListenerMessageHandler extends AbstractReplyProduci private final EvaluationContext evaluationContext; - DispatchingStreamListenerMessageHandler(Collection handlerMethods, + DispatchingStreamListenerMessageHandler( + Collection handlerMethods, EvaluationContext evaluationContext) { Assert.notEmpty(handlerMethods, "'handlerMethods' cannot be empty"); - this.handlerMethods = Collections.unmodifiableList(new ArrayList<>(handlerMethods)); + this.handlerMethods = Collections + .unmodifiableList(new ArrayList<>(handlerMethods)); boolean evaluateExpressions = false; for (ConditionalStreamListenerMessageHandlerWrapper handlerMethod : handlerMethods) { if (handlerMethod.getCondition() != null) { @@ -56,7 +59,8 @@ final class DispatchingStreamListenerMessageHandler extends AbstractReplyProduci } this.evaluateExpressions = evaluateExpressions; if (evaluateExpressions) { - Assert.notNull(evaluationContext, "'evaluationContext' cannot be null if conditions are used"); + Assert.notNull(evaluationContext, + "'evaluationContext' cannot be null if conditions are used"); } this.evaluationContext = evaluationContext; } @@ -68,38 +72,44 @@ final class DispatchingStreamListenerMessageHandler extends AbstractReplyProduci @Override protected Object handleRequestMessage(Message requestMessage) { - List matchingHandlers = this.evaluateExpressions ? findMatchingHandlers(requestMessage) : this.handlerMethods; + List matchingHandlers = this.evaluateExpressions + ? findMatchingHandlers(requestMessage) : this.handlerMethods; if (matchingHandlers.size() == 0) { - if (logger.isWarnEnabled()) { - logger.warn("Cannot find a @StreamListener matching for message with id: " - + requestMessage.getHeaders().getId()); + if (this.logger.isWarnEnabled()) { + this.logger.warn( + "Cannot find a @StreamListener matching for message with id: " + + requestMessage.getHeaders().getId()); } return null; } else if (matchingHandlers.size() > 1) { for (ConditionalStreamListenerMessageHandlerWrapper matchingMethod : matchingHandlers) { - matchingMethod.getStreamListenerMessageHandler().handleMessage(requestMessage); + matchingMethod.getStreamListenerMessageHandler() + .handleMessage(requestMessage); } return null; } else { - final ConditionalStreamListenerMessageHandlerWrapper singleMatchingHandler = matchingHandlers.get(0); - singleMatchingHandler.getStreamListenerMessageHandler().handleMessage(requestMessage); + final ConditionalStreamListenerMessageHandlerWrapper singleMatchingHandler = matchingHandlers + .get(0); + singleMatchingHandler.getStreamListenerMessageHandler() + .handleMessage(requestMessage); return null; } } - private List findMatchingHandlers(Message message) { + private List findMatchingHandlers( + Message message) { ArrayList matchingMethods = new ArrayList<>(); - for (ConditionalStreamListenerMessageHandlerWrapper conditionalStreamListenerMessageHandlerWrapperMethod : this.handlerMethods) { - if (conditionalStreamListenerMessageHandlerWrapperMethod.getCondition() == null) { - matchingMethods.add(conditionalStreamListenerMessageHandlerWrapperMethod); + for (ConditionalStreamListenerMessageHandlerWrapper wrapper : this.handlerMethods) { + if (wrapper.getCondition() == null) { + matchingMethods.add(wrapper); } else { - boolean conditionMetOnMessage = conditionalStreamListenerMessageHandlerWrapperMethod.getCondition().getValue( - this.evaluationContext, message, Boolean.class); + boolean conditionMetOnMessage = wrapper.getCondition() + .getValue(this.evaluationContext, message, Boolean.class); if (conditionMetOnMessage) { - matchingMethods.add(conditionalStreamListenerMessageHandlerWrapperMethod); + matchingMethods.add(wrapper); } } } @@ -114,7 +124,8 @@ final class DispatchingStreamListenerMessageHandler extends AbstractReplyProduci ConditionalStreamListenerMessageHandlerWrapper(Expression condition, StreamListenerMessageHandler streamListenerMessageHandler) { - Assert.notNull(streamListenerMessageHandler, "the message handler cannot be null"); + Assert.notNull(streamListenerMessageHandler, + "the message handler cannot be null"); Assert.isTrue(condition == null || streamListenerMessageHandler.isVoid(), "cannot specify a condition and a return value at the same time"); this.condition = condition; @@ -122,7 +133,7 @@ final class DispatchingStreamListenerMessageHandler extends AbstractReplyProduci } public Expression getCondition() { - return condition; + return this.condition; } public boolean isVoid() { @@ -130,7 +141,9 @@ final class DispatchingStreamListenerMessageHandler extends AbstractReplyProduci } public StreamListenerMessageHandler getStreamListenerMessageHandler() { - return streamListenerMessageHandler; + return this.streamListenerMessageHandler; } + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DynamicDestinationsBindable.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DynamicDestinationsBindable.java index 8feb319fb..ccf0373f3 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DynamicDestinationsBindable.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/DynamicDestinationsBindable.java @@ -27,7 +27,6 @@ import org.springframework.cloud.stream.binder.Binding; * A {@link Bindable} that stores the dynamic destination names and handles their * unbinding. * - * * @author Ilayaperumal Gopinathan * @author Oleg Zhurakousky */ @@ -44,14 +43,15 @@ public final class DynamicDestinationsBindable implements Bindable { @Override public synchronized Set getOutputs() { - return Collections.unmodifiableSet(outputBindings.keySet()); + return Collections.unmodifiableSet(this.outputBindings.keySet()); } @Override public synchronized void unbindOutputs(BindingService adapter) { - for (Map.Entry> entry : outputBindings.entrySet()) { + for (Map.Entry> entry : this.outputBindings.entrySet()) { entry.getValue().unbind(); } - outputBindings.clear(); + this.outputBindings.clear(); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java index e84eff42a..13b8698bc 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java @@ -26,6 +26,7 @@ import org.springframework.util.CollectionUtils; /** * Coordinates binding/unbinding of input binding targets in accordance to the lifecycle * of the host context. + * * @author Marius Bogoevici * @author Ilayaperumal Gopinathan * @author Oleg Zhurakousky @@ -33,10 +34,12 @@ import org.springframework.util.CollectionUtils; public class InputBindingLifecycle extends AbstractBindingLifecycle { @SuppressWarnings("unused") - //It is actually used reflectively since at the moment we do not want to expose it via public method + // It is actually used reflectively since at the moment we do not want to expose it + // via public method private Collection> inputBindings = new ArrayList>(); - public InputBindingLifecycle(BindingService bindingService, Map bindables) { + public InputBindingLifecycle(BindingService bindingService, + Map bindables) { super(bindingService, bindables); } @@ -51,7 +54,8 @@ public class InputBindingLifecycle extends AbstractBindingLifecycle { @Override void doStartWithBindable(Bindable bindable) { - Collection> bindableBindings = bindable.createAndBindInputs(bindingService); + Collection> bindableBindings = bindable + .createAndBindInputs(this.bindingService); if (!CollectionUtils.isEmpty(bindableBindings)) { this.inputBindings.addAll(bindableBindings); } @@ -59,6 +63,7 @@ public class InputBindingLifecycle extends AbstractBindingLifecycle { @Override void doStopWithBindable(Bindable bindable) { - bindable.unbindInputs(bindingService); + bindable.unbindInputs(this.bindingService); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelAndSourceConfigurer.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelAndSourceConfigurer.java index 7a9739940..0d2ed9fe3 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelAndSourceConfigurer.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelAndSourceConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelConfigurer.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelConfigurer.java index ffd6d40fa..23d02df23 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelConfigurer.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.springframework.messaging.MessageChannel; /** * Interface to be implemented by the classes that configure the {@link Bindable} message * channels. + * * @author Ilayaperumal Gopinathan */ public interface MessageChannelConfigurer { @@ -38,4 +39,5 @@ public interface MessageChannelConfigurer { * @param channelName name of the message channel */ void configureOutputChannel(MessageChannel messageChannel, String channelName); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelStreamListenerResultAdapter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelStreamListenerResultAdapter.java index 15052613b..e3bde3eb5 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelStreamListenerResultAdapter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageChannelStreamListenerResultAdapter.java @@ -41,7 +41,8 @@ public class MessageChannelStreamListenerResultAdapter } @Override - public Closeable adapt(MessageChannel streamListenerResult, MessageChannel bindingTarget) { + public Closeable adapt(MessageChannel streamListenerResult, + MessageChannel bindingTarget) { BridgeHandler handler = new BridgeHandler(); handler.setOutputChannel(bindingTarget); handler.afterPropertiesSet(); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageConverterConfigurer.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageConverterConfigurer.java index 3ed170bb2..44cdf9e5e 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageConverterConfigurer.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageConverterConfigurer.java @@ -73,7 +73,8 @@ import org.springframework.util.StringUtils; * @author Soby Chacko * @author Oleg Zhurakousky */ -public class MessageConverterConfigurer implements MessageChannelAndSourceConfigurer, BeanFactoryAware { +public class MessageConverterConfigurer + implements MessageChannelAndSourceConfigurer, BeanFactoryAware { private final Log logger = LogFactory.getLog(getClass()); @@ -83,10 +84,10 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig private final BindingServiceProperties bindingServiceProperties; - private ConfigurableListableBeanFactory beanFactory; - private final Field headersField; + private ConfigurableListableBeanFactory beanFactory; + public MessageConverterConfigurer(BindingServiceProperties bindingServiceProperties, CompositeMessageConverterFactory compositeMessageConverterFactory) { Assert.notNull(compositeMessageConverterFactory, @@ -95,7 +96,7 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig this.compositeMessageConverterFactory = compositeMessageConverterFactory; this.headersField = ReflectionUtils.findField(MessageHeaders.class, "headers"); - headersField.setAccessible(true); + this.headersField.setAccessible(true); } @Override @@ -116,105 +117,137 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig @Override public void configurePolledMessageSource(PollableMessageSource binding, String name) { - BindingProperties bindingProperties = this.bindingServiceProperties.getBindingProperties(name); + BindingProperties bindingProperties = this.bindingServiceProperties + .getBindingProperties(name); String contentType = bindingProperties.getContentType(); ConsumerProperties consumerProperties = bindingProperties.getConsumer(); if ((consumerProperties == null || !consumerProperties.isUseNativeDecoding()) && binding instanceof DefaultPollableMessageSource) { - ((DefaultPollableMessageSource) binding).addInterceptor(new InboundContentTypeEnhancingInterceptor(contentType)); + ((DefaultPollableMessageSource) binding).addInterceptor( + new InboundContentTypeEnhancingInterceptor(contentType)); } } /** * Setup data-type and message converters for the given message channel. - * * @param channel message channel to set the data-type and message converters * @param channelName the channel name * @param inbound inbound (i.e., "input") or outbound channel */ - private void configureMessageChannel(MessageChannel channel, String channelName, boolean inbound) { + private void configureMessageChannel(MessageChannel channel, String channelName, + boolean inbound) { Assert.isAssignable(AbstractMessageChannel.class, channel.getClass()); AbstractMessageChannel messageChannel = (AbstractMessageChannel) channel; - BindingProperties bindingProperties = this.bindingServiceProperties.getBindingProperties(channelName); + BindingProperties bindingProperties = this.bindingServiceProperties + .getBindingProperties(channelName); String contentType = bindingProperties.getContentType(); ProducerProperties producerProperties = bindingProperties.getProducer(); - if (!inbound && producerProperties != null && producerProperties.isPartitioned()) { + if (!inbound && producerProperties != null + && producerProperties.isPartitioned()) { messageChannel.addInterceptor(new PartitioningInterceptor(bindingProperties, getPartitionKeyExtractorStrategy(producerProperties), getPartitionSelectorStrategy(producerProperties))); } ConsumerProperties consumerProperties = bindingProperties.getConsumer(); - if (this.isNativeEncodingNotSet(producerProperties, consumerProperties, inbound)) { + if (this.isNativeEncodingNotSet(producerProperties, consumerProperties, + inbound)) { if (inbound) { - messageChannel.addInterceptor(new InboundContentTypeEnhancingInterceptor(contentType)); + messageChannel.addInterceptor( + new InboundContentTypeEnhancingInterceptor(contentType)); } else { - messageChannel.addInterceptor(new OutboundContentTypeConvertingInterceptor(contentType, this.compositeMessageConverterFactory - .getMessageConverterForAllRegistered())); + messageChannel.addInterceptor( + new OutboundContentTypeConvertingInterceptor(contentType, + this.compositeMessageConverterFactory + .getMessageConverterForAllRegistered())); } } } - private boolean isNativeEncodingNotSet(ProducerProperties producerProperties, ConsumerProperties consumerProperties, boolean input) { + private boolean isNativeEncodingNotSet(ProducerProperties producerProperties, + ConsumerProperties consumerProperties, boolean input) { if (input) { - return consumerProperties == null || !consumerProperties.isUseNativeDecoding(); + return consumerProperties == null + || !consumerProperties.isUseNativeDecoding(); } else { - return producerProperties == null || !producerProperties.isUseNativeEncoding(); + return producerProperties == null + || !producerProperties.isUseNativeEncoding(); } } @SuppressWarnings("deprecation") - private PartitionKeyExtractorStrategy getPartitionKeyExtractorStrategy(ProducerProperties producerProperties) { + private PartitionKeyExtractorStrategy getPartitionKeyExtractorStrategy( + ProducerProperties producerProperties) { PartitionKeyExtractorStrategy partitionKeyExtractor; if (producerProperties.getPartitionKeyExtractorClass() != null) { - logger.warn("'partitionKeyExtractorClass' option is deprecated as of v2.0. Please configure partition " - + "key extractor as a @Bean that implements 'PartitionKeyExtractorStrategy'. Additionally you can " - + "specify 'spring.cloud.stream.bindings.output.producer.partitionKeyExtractorName' to specify which " - + "bean to use in the event there are more then one."); - partitionKeyExtractor = instantiate(producerProperties.getPartitionKeyExtractorClass(), PartitionKeyExtractorStrategy.class); + this.logger.warn( + "'partitionKeyExtractorClass' option is deprecated as of v2.0. Please configure partition " + + "key extractor as a @Bean that implements 'PartitionKeyExtractorStrategy'. Additionally you can " + + "specify 'spring.cloud.stream.bindings.output.producer.partitionKeyExtractorName' to specify which " + + "bean to use in the event there are more then one."); + partitionKeyExtractor = instantiate( + producerProperties.getPartitionKeyExtractorClass(), + PartitionKeyExtractorStrategy.class); } else if (StringUtils.hasText(producerProperties.getPartitionKeyExtractorName())) { - partitionKeyExtractor = this.beanFactory.getBean(producerProperties.getPartitionKeyExtractorName(), PartitionKeyExtractorStrategy.class); - Assert.notNull(partitionKeyExtractor, "PartitionKeyExtractorStrategy bean with the name '" + producerProperties.getPartitionKeyExtractorName() - + "' can not be found. Has it been configured (e.g., @Bean)?"); + partitionKeyExtractor = this.beanFactory.getBean( + producerProperties.getPartitionKeyExtractorName(), + PartitionKeyExtractorStrategy.class); + Assert.notNull(partitionKeyExtractor, + "PartitionKeyExtractorStrategy bean with the name '" + + producerProperties.getPartitionKeyExtractorName() + + "' can not be found. Has it been configured (e.g., @Bean)?"); } else { - Map extractors = this.beanFactory.getBeansOfType(PartitionKeyExtractorStrategy.class); + Map extractors = this.beanFactory + .getBeansOfType(PartitionKeyExtractorStrategy.class); Assert.isTrue(extractors.size() <= 1, - "Multiple beans of type 'PartitionKeyExtractorStrategy' found. " + extractors + ". Please " + "Multiple beans of type 'PartitionKeyExtractorStrategy' found. " + + extractors + ". Please " + "use 'spring.cloud.stream.bindings.output.producer.partitionKeyExtractorName' property to specify " + "the name of the bean to be used."); - partitionKeyExtractor = CollectionUtils.isEmpty(extractors) ? null : extractors.values().iterator().next(); + partitionKeyExtractor = CollectionUtils.isEmpty(extractors) ? null + : extractors.values().iterator().next(); } return partitionKeyExtractor; } @SuppressWarnings("deprecation") - private PartitionSelectorStrategy getPartitionSelectorStrategy(ProducerProperties producerProperties) { + private PartitionSelectorStrategy getPartitionSelectorStrategy( + ProducerProperties producerProperties) { PartitionSelectorStrategy partitionSelector; if (producerProperties.getPartitionSelectorClass() != null) { - logger.warn("'partitionSelectorClass' option is deprecated as of v2.0. Please configure partition " - + "selector as a @Bean that implements 'PartitionSelectorStrategy'. Additionally you can " - + "specify 'spring.cloud.stream.bindings.output.producer.partitionSelectorName' to specify which " - + "bean to use in the event there are more then one."); - partitionSelector = instantiate(producerProperties.getPartitionSelectorClass(), + this.logger.warn( + "'partitionSelectorClass' option is deprecated as of v2.0. Please configure partition " + + "selector as a @Bean that implements 'PartitionSelectorStrategy'. Additionally you can " + + "specify 'spring.cloud.stream.bindings.output.producer.partitionSelectorName' to specify which " + + "bean to use in the event there are more then one."); + partitionSelector = instantiate( + producerProperties.getPartitionSelectorClass(), PartitionSelectorStrategy.class); } else if (StringUtils.hasText(producerProperties.getPartitionSelectorName())) { - partitionSelector = this.beanFactory.getBean(producerProperties.getPartitionSelectorName(), PartitionSelectorStrategy.class); + partitionSelector = this.beanFactory.getBean( + producerProperties.getPartitionSelectorName(), + PartitionSelectorStrategy.class); Assert.notNull(partitionSelector, - "PartitionSelectorStrategy bean with the name '" + producerProperties.getPartitionSelectorName() + "PartitionSelectorStrategy bean with the name '" + + producerProperties.getPartitionSelectorName() + "' can not be found. Has it been configured (e.g., @Bean)?"); } else { - Map selectors = this.beanFactory.getBeansOfType(PartitionSelectorStrategy.class); + Map selectors = this.beanFactory + .getBeansOfType(PartitionSelectorStrategy.class); Assert.isTrue(selectors.size() <= 1, - "Multiple beans of type 'PartitionSelectorStrategy' found. " + selectors + ". Please " - + "use 'spring.cloud.stream.bindings.output.producer.partitionSelectorName' property to specify " - + "the name of the bean to be used."); - partitionSelector = CollectionUtils.isEmpty(selectors) ? new DefaultPartitionSelector() : selectors.values().iterator().next(); + "Multiple beans of type 'PartitionSelectorStrategy' found. " + + selectors + ". Please " + + "use 'spring.cloud.stream.bindings.output.producer.partitionSelectorName' property to specify " + + "the name of the bean to be used."); + partitionSelector = CollectionUtils.isEmpty(selectors) + ? new DefaultPartitionSelector() + : selectors.values().iterator().next(); } return partitionSelector; } @@ -225,7 +258,8 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig return (T) implClass.newInstance(); } catch (Exception e) { - throw new BinderException("Failed to instantiate class: " + implClass.getName(), e); + throw new BinderException( + "Failed to instantiate class: " + implClass.getName(), e); } } @@ -243,16 +277,19 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig } return Math.abs(hashCode); } + } /** - * Primary purpose of this interceptor is to enhance/enrich Message that sent to the *inbound* - * channel with 'contentType' header for cases where 'contentType' is not present in the Message - * itself but set on such channel via {@link BindingProperties#setContentType(String)}. - *
- * Secondary purpose of this interceptor is to provide backward compatibility with previous versions of SCSt. + * Primary purpose of this interceptor is to enhance/enrich Message that sent to the + * *inbound* channel with 'contentType' header for cases where 'contentType' is not + * present in the Message itself but set on such channel via + * {@link BindingProperties#setContentType(String)}.
+ * Secondary purpose of this interceptor is to provide backward compatibility with + * previous versions of SCSt. */ - private final class InboundContentTypeEnhancingInterceptor extends AbstractContentTypeInterceptor { + private final class InboundContentTypeEnhancingInterceptor + extends AbstractContentTypeInterceptor { private InboundContentTypeEnhancingInterceptor(String contentType) { super(contentType); @@ -261,15 +298,21 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig @Override public Message doPreSend(Message message, MessageChannel channel) { @SuppressWarnings("unchecked") - Map headersMap = (Map) ReflectionUtils.getField(MessageConverterConfigurer.this.headersField, message.getHeaders()); + Map headersMap = (Map) ReflectionUtils + .getField(MessageConverterConfigurer.this.headersField, + message.getHeaders()); MimeType contentType = this.mimeType; /* - * NOTE: The below code for BINDER_ORIGINAL_CONTENT_TYPE is to support legacy message format established - * in 1.x version of the framework and should/will no longer be supported in 3.x + * NOTE: The below code for BINDER_ORIGINAL_CONTENT_TYPE is to support legacy + * message format established in 1.x version of the framework and should/will + * no longer be supported in 3.x */ - if (message.getHeaders().containsKey(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)) { - Object ct = message.getHeaders().get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); - contentType = ct instanceof String ? MimeType.valueOf((String)ct) : (ct == null ? this.mimeType : (MimeType)ct); + if (message.getHeaders() + .containsKey(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)) { + Object ct = message.getHeaders() + .get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); + contentType = ct instanceof String ? MimeType.valueOf((String) ct) + : (ct == null ? this.mimeType : (MimeType) ct); headersMap.put(MessageHeaders.CONTENT_TYPE, contentType); headersMap.remove(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE); } @@ -278,25 +321,31 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig if (!message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) { headersMap.put(MessageHeaders.CONTENT_TYPE, contentType); } - else if (message.getHeaders().get(MessageHeaders.CONTENT_TYPE) instanceof String) { - headersMap.put(MessageHeaders.CONTENT_TYPE, MimeType.valueOf((String)message.getHeaders().get(MessageHeaders.CONTENT_TYPE))); + else if (message.getHeaders() + .get(MessageHeaders.CONTENT_TYPE) instanceof String) { + headersMap.put(MessageHeaders.CONTENT_TYPE, MimeType.valueOf( + (String) message.getHeaders().get(MessageHeaders.CONTENT_TYPE))); } return message; } + } /** - * Unlike INBOUND where the target type is known and conversion is typically done by argument - * resolvers of {@link InvocableHandlerMethod} for the OUTBOUND case it is not known so we simply - * rely on provided MessageConverters that will use the provided 'contentType' and convert messages - * to a type dictated by the Binders (i.e., byte[]). + * Unlike INBOUND where the target type is known and conversion is typically done by + * argument resolvers of {@link InvocableHandlerMethod} for the OUTBOUND case it is + * not known so we simply rely on provided MessageConverters that will use the + * provided 'contentType' and convert messages to a type dictated by the Binders + * (i.e., byte[]). */ - private final class OutboundContentTypeConvertingInterceptor extends AbstractContentTypeInterceptor { + private final class OutboundContentTypeConvertingInterceptor + extends AbstractContentTypeInterceptor { private final MessageConverter messageConverter; - private OutboundContentTypeConvertingInterceptor(String contentType, CompositeMessageConverter messageConverter) { + private OutboundContentTypeConvertingInterceptor(String contentType, + CompositeMessageConverter messageConverter) { super(contentType); this.messageConverter = messageConverter; } @@ -304,52 +353,64 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig @Override public Message doPreSend(Message message, MessageChannel channel) { - // If handler is a function, FunctionInvoker will already perform message conversion. - // In fact in the future we should consider propagating knowledge of the default content type - //to MessageConverters instead of interceptors - if (message.getPayload() instanceof byte[] && message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) { + // If handler is a function, FunctionInvoker will already perform message + // conversion. + // In fact in the future we should consider propagating knowledge of the + // default content type + // to MessageConverters instead of interceptors + if (message.getPayload() instanceof byte[] + && message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) { return message; } - // ===== 1.3 backward compatibility code part-1 === - String oct = message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE) ? message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString() : null; + String oct = message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE) + ? message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString() + : null; String ct = message.getPayload() instanceof String - ? ct = JavaClassMimeTypeUtils.mimeTypeFromObject(message.getPayload(), ObjectUtils.nullSafeToString(oct)).toString() - : oct; + ? JavaClassMimeTypeUtils.mimeTypeFromObject(message.getPayload(), + ObjectUtils.nullSafeToString(oct)).toString() + : oct; // ===== END 1.3 backward compatibility code part-1 === - if (!message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) { @SuppressWarnings("unchecked") - Map headersMap = (Map) ReflectionUtils.getField(MessageConverterConfigurer.this.headersField, message.getHeaders()); + Map headersMap = (Map) ReflectionUtils + .getField(MessageConverterConfigurer.this.headersField, + message.getHeaders()); headersMap.put(MessageHeaders.CONTENT_TYPE, this.mimeType); } @SuppressWarnings("unchecked") Message outboundMessage = message.getPayload() instanceof byte[] - ? (Message)message : (Message) this.messageConverter.toMessage(message.getPayload(), message.getHeaders()); + ? (Message) message : (Message) this.messageConverter + .toMessage(message.getPayload(), message.getHeaders()); if (outboundMessage == null) { - throw new IllegalStateException("Failed to convert message: '" + message + "' to outbound message."); + throw new IllegalStateException("Failed to convert message: '" + message + + "' to outbound message."); } /// ===== 1.3 backward compatibility code part-2 === if (ct != null && !ct.equals(oct) && oct != null) { @SuppressWarnings("unchecked") - Map headersMap = (Map) ReflectionUtils.getField(MessageConverterConfigurer.this.headersField, - outboundMessage.getHeaders()); + Map headersMap = (Map) ReflectionUtils + .getField(MessageConverterConfigurer.this.headersField, + outboundMessage.getHeaders()); headersMap.put(MessageHeaders.CONTENT_TYPE, MimeType.valueOf(ct)); - headersMap.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, MimeType.valueOf(oct)); + headersMap.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, + MimeType.valueOf(oct)); } // ===== END 1.3 backward compatibility code part-2 === return outboundMessage; } + } /** * */ private abstract class AbstractContentTypeInterceptor implements ChannelInterceptor { + final MimeType mimeType; private AbstractContentTypeInterceptor(String contentType) { @@ -358,12 +419,18 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig @Override public Message preSend(Message message, MessageChannel channel) { - return message instanceof ErrorMessage ? message : this.doPreSend(message, channel); + return message instanceof ErrorMessage ? message + : this.doPreSend(message, channel); } - protected abstract Message doPreSend(Message message, MessageChannel channel); + protected abstract Message doPreSend(Message message, + MessageChannel channel); + } + /** + * Partitioning channel interceptor. + */ public final class PartitioningInterceptor implements ChannelInterceptor { private final BindingProperties bindingProperties; @@ -402,6 +469,7 @@ public class MessageConverterConfigurer implements MessageChannelAndSourceConfig .removeHeader(BinderHeaders.PARTITION_OVERRIDE).build(); } } + } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageSourceBindingTargetFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageSourceBindingTargetFactory.java index 03c5aec4c..a6f9f5962 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageSourceBindingTargetFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/MessageSourceBindingTargetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -34,16 +34,19 @@ public class MessageSourceBindingTargetFactory private final SmartMessageConverter messageConverter; - public MessageSourceBindingTargetFactory(SmartMessageConverter messageConverter, MessageChannelConfigurer messageSourceConfigurer) { + public MessageSourceBindingTargetFactory(SmartMessageConverter messageConverter, + MessageChannelConfigurer messageSourceConfigurer) { super(PollableMessageSource.class); - Assert.isInstanceOf(MessageChannelAndSourceConfigurer.class, messageSourceConfigurer); + Assert.isInstanceOf(MessageChannelAndSourceConfigurer.class, + messageSourceConfigurer); this.messageSourceConfigurer = (MessageChannelAndSourceConfigurer) messageSourceConfigurer; this.messageConverter = messageConverter; } @Override public PollableMessageSource createInput(String name) { - DefaultPollableMessageSource binding = new DefaultPollableMessageSource(this.messageConverter); + DefaultPollableMessageSource binding = new DefaultPollableMessageSource( + this.messageConverter); this.messageSourceConfigurer.configurePolledMessageSource(binding, name); return binding; } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java index f8640de84..85f5f6d4c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java @@ -34,10 +34,12 @@ import org.springframework.util.CollectionUtils; public class OutputBindingLifecycle extends AbstractBindingLifecycle { @SuppressWarnings("unused") - //It is actually used reflectively since at the moment we do not want to expose it via public method + // It is actually used reflectively since at the moment we do not want to expose it + // via public method private Collection> outputBindings = new ArrayList>(); - public OutputBindingLifecycle(BindingService bindingService, Map bindables) { + public OutputBindingLifecycle(BindingService bindingService, + Map bindables) { super(bindingService, bindables); } @@ -52,7 +54,8 @@ public class OutputBindingLifecycle extends AbstractBindingLifecycle { @Override void doStartWithBindable(Bindable bindable) { - Collection> bindableBindings = bindable.createAndBindOutputs(bindingService); + Collection> bindableBindings = bindable + .createAndBindOutputs(this.bindingService); if (!CollectionUtils.isEmpty(bindableBindings)) { this.outputBindings.addAll(bindableBindings); } @@ -60,6 +63,7 @@ public class OutputBindingLifecycle extends AbstractBindingLifecycle { @Override void doStopWithBindable(Bindable bindable) { - bindable.unbindOutputs(bindingService); + bindable.unbindOutputs(this.bindingService); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SingleBindingTargetBindable.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SingleBindingTargetBindable.java index e71e17f5d..5e3813088 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SingleBindingTargetBindable.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SingleBindingTargetBindable.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,10 +29,11 @@ import org.springframework.cloud.stream.binder.Binding; * binding targets outside the {@link org.springframework.cloud.stream.annotation.Input} * and {@link org.springframework.cloud.stream.annotation.Output} annotated interfaces. * + * @param type of binding target * @author Ilayaperumal Gopinathan * @author Marius Bogoevici - * - * @deprecated This class is no longer used by the framework and maybe removed in a future release. + * @deprecated This class is no longer used by the framework and maybe removed in a future + * release. */ @Deprecated public class SingleBindingTargetBindable implements Bindable { @@ -52,17 +53,20 @@ public class SingleBindingTargetBindable implements Bindable { } @Override - public Collection> createAndBindOutputs(BindingService bindingService) { - return Collections.singletonList(bindingService.bindProducer(bindingTarget, name)); + public Collection> createAndBindOutputs( + BindingService bindingService) { + return Collections.singletonList( + bindingService.bindProducer(this.bindingTarget, this.name)); } @Override public void unbindOutputs(BindingService bindingService) { - bindingService.unbindProducers(name); + bindingService.unbindProducers(this.name); } @Override public Set getOutputs() { - return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(name))); + return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(this.name))); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationCommonMethodUtils.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationCommonMethodUtils.java index 55febce0c..adbc8dc36 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationCommonMethodUtils.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationCommonMethodUtils.java @@ -37,14 +37,18 @@ public abstract class StreamAnnotationCommonMethodUtils { public static String getOutboundBindingTargetName(Method method) { SendTo sendTo = AnnotationUtils.findAnnotation(method, SendTo.class); if (sendTo != null) { - Assert.isTrue(!ObjectUtils.isEmpty(sendTo.value()), StreamAnnotationErrorMessages.ATLEAST_ONE_OUTPUT); - Assert.isTrue(sendTo.value().length == 1, StreamAnnotationErrorMessages.SEND_TO_MULTIPLE_DESTINATIONS); - Assert.hasText(sendTo.value()[0], StreamAnnotationErrorMessages.SEND_TO_EMPTY_DESTINATION); + Assert.isTrue(!ObjectUtils.isEmpty(sendTo.value()), + StreamAnnotationErrorMessages.ATLEAST_ONE_OUTPUT); + Assert.isTrue(sendTo.value().length == 1, + StreamAnnotationErrorMessages.SEND_TO_MULTIPLE_DESTINATIONS); + Assert.hasText(sendTo.value()[0], + StreamAnnotationErrorMessages.SEND_TO_EMPTY_DESTINATION); return sendTo.value()[0]; } Output output = AnnotationUtils.findAnnotation(method, Output.class); if (output != null) { - Assert.isTrue(StringUtils.hasText(output.value()), StreamAnnotationErrorMessages.ATLEAST_ONE_OUTPUT); + Assert.isTrue(StringUtils.hasText(output.value()), + StreamAnnotationErrorMessages.ATLEAST_ONE_OUTPUT); return output.value(); } return null; @@ -52,12 +56,15 @@ public abstract class StreamAnnotationCommonMethodUtils { public static int outputAnnotationCount(Method method) { int outputAnnotationCount = 0; - for (int parameterIndex = 0; parameterIndex < method.getParameterTypes().length; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + for (int parameterIndex = 0; parameterIndex < method + .getParameterTypes().length; parameterIndex++) { + MethodParameter methodParameter = MethodParameter.forExecutable(method, + parameterIndex); if (methodParameter.hasParameterAnnotation(Output.class)) { outputAnnotationCount++; } } return outputAnnotationCount; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationErrorMessages.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationErrorMessages.java index 01e38d635..ae3205c2c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationErrorMessages.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamAnnotationErrorMessages.java @@ -21,12 +21,24 @@ package org.springframework.cloud.stream.binding; */ public abstract class StreamAnnotationErrorMessages { + /** + * Annotation error message when no output was passed. + */ public static final String ATLEAST_ONE_OUTPUT = "At least one output must be specified"; + /** + * Annotation error message when multiple destinations were set. + */ public static final String SEND_TO_MULTIPLE_DESTINATIONS = "Multiple destinations cannot be specified"; + /** + * Annotation error message when an empty destination was specified. + */ public static final String SEND_TO_EMPTY_DESTINATION = "An empty destination cannot be specified"; + /** + * Annotation error message when an invalid outbound name was set. + */ public static final String INVALID_OUTBOUND_NAME = "The @Output annotation must have the name of an input as value"; } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerAnnotationBeanPostProcessor.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerAnnotationBeanPostProcessor.java index ca349f29a..553f1e96f 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerAnnotationBeanPostProcessor.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerAnnotationBeanPostProcessor.java @@ -69,21 +69,26 @@ import org.springframework.util.StringUtils; * @author Soby Chacko * @author Oleg Zhurakousky */ -public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, SmartInitializingSingleton { +public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProcessor, + ApplicationContextAware, SmartInitializingSingleton { private static final SpelExpressionParser SPEL_EXPRESSION_PARSER = new SpelExpressionParser(); + // @checkstyle:off private final MultiValueMap mappedListenerMethods = new LinkedMultiValueMap<>(); - // == dependencies that are injected in 'afterSingletonsInstantiated' to avoid early initialization + // @checkstyle:on + + private final Set streamListenerCallbacks = new HashSet<>(); + + // == dependencies that are injected in 'afterSingletonsInstantiated' to avoid early + // initialization private DestinationResolver binderAwareChannelResolver; private MessageHandlerMethodFactory messageHandlerMethodFactory; - private SpringIntegrationProperties springIntegrationProperties; // == end dependencies - - private final Set streamListenerCallbacks = new HashSet<>(); + private SpringIntegrationProperties springIntegrationProperties; private ConfigurableApplicationContext applicationContext; @@ -94,35 +99,49 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces private Set streamListenerSetupMethodOrchestrators = new LinkedHashSet<>(); @Override - public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public final void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { this.applicationContext = (ConfigurableApplicationContext) applicationContext; - this.resolver = this.applicationContext.getBeanFactory().getBeanExpressionResolver(); - this.expressionContext = new BeanExpressionContext(this.applicationContext.getBeanFactory(), null); + this.resolver = this.applicationContext.getBeanFactory() + .getBeanExpressionResolver(); + this.expressionContext = new BeanExpressionContext( + this.applicationContext.getBeanFactory(), null); } @Override public final void afterSingletonsInstantiated() { this.injectAndPostProcessDependencies(); - EvaluationContext evaluationContext = IntegrationContextUtils.getEvaluationContext(this.applicationContext.getBeanFactory()); - for (Map.Entry> mappedBindingEntry : mappedListenerMethods + EvaluationContext evaluationContext = IntegrationContextUtils + .getEvaluationContext(this.applicationContext.getBeanFactory()); + for (Map.Entry> mappedBindingEntry : this.mappedListenerMethods .entrySet()) { - ArrayList handlers = new ArrayList<>(); - for (StreamListenerHandlerMethodMapping mapping : mappedBindingEntry.getValue()) { + ArrayList handlers; + handlers = new ArrayList<>(); + for (StreamListenerHandlerMethodMapping mapping : mappedBindingEntry + .getValue()) { final InvocableHandlerMethod invocableHandlerMethod = this.messageHandlerMethodFactory .createInvocableHandlerMethod(mapping.getTargetBean(), checkProxy(mapping.getMethod(), mapping.getTargetBean())); StreamListenerMessageHandler streamListenerMessageHandler = new StreamListenerMessageHandler( - invocableHandlerMethod, resolveExpressionAsBoolean(mapping.getCopyHeaders(), "copyHeaders"), - springIntegrationProperties.getMessageHandlerNotPropagatedHeaders()); - streamListenerMessageHandler.setApplicationContext(this.applicationContext); - streamListenerMessageHandler.setBeanFactory(this.applicationContext.getBeanFactory()); + invocableHandlerMethod, + resolveExpressionAsBoolean(mapping.getCopyHeaders(), + "copyHeaders"), + this.springIntegrationProperties + .getMessageHandlerNotPropagatedHeaders()); + streamListenerMessageHandler + .setApplicationContext(this.applicationContext); + streamListenerMessageHandler + .setBeanFactory(this.applicationContext.getBeanFactory()); if (StringUtils.hasText(mapping.getDefaultOutputChannel())) { - streamListenerMessageHandler.setOutputChannelName(mapping.getDefaultOutputChannel()); + streamListenerMessageHandler + .setOutputChannelName(mapping.getDefaultOutputChannel()); } streamListenerMessageHandler.afterPropertiesSet(); if (StringUtils.hasText(mapping.getCondition())) { - String conditionAsString = resolveExpressionAsString(mapping.getCondition(), "condition"); - Expression condition = SPEL_EXPRESSION_PARSER.parseExpression(conditionAsString); + String conditionAsString = resolveExpressionAsString( + mapping.getCondition(), "condition"); + Expression condition = SPEL_EXPRESSION_PARSER + .parseExpression(conditionAsString); handlers.add( new DispatchingStreamListenerMessageHandler.ConditionalStreamListenerMessageHandlerWrapper( condition, streamListenerMessageHandler)); @@ -135,13 +154,15 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces } if (handlers.size() > 1) { for (DispatchingStreamListenerMessageHandler.ConditionalStreamListenerMessageHandlerWrapper handler : handlers) { - Assert.isTrue(handler.isVoid(), StreamListenerErrorMessages.MULTIPLE_VALUE_RETURNING_METHODS); + Assert.isTrue(handler.isVoid(), + StreamListenerErrorMessages.MULTIPLE_VALUE_RETURNING_METHODS); } } AbstractReplyProducingMessageHandler handler; if (handlers.size() > 1 || handlers.get(0).getCondition() != null) { - handler = new DispatchingStreamListenerMessageHandler(handlers, evaluationContext); + handler = new DispatchingStreamListenerMessageHandler(handlers, + evaluationContext); } else { handler = handlers.get(0).getStreamListenerMessageHandler(); @@ -149,21 +170,29 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces handler.setApplicationContext(this.applicationContext); handler.setChannelResolver(this.binderAwareChannelResolver); handler.afterPropertiesSet(); - this.applicationContext.getBeanFactory().registerSingleton(handler.getClass().getSimpleName() + handler.hashCode(), handler); - applicationContext.getBean(mappedBindingEntry.getKey(), SubscribableChannel.class).subscribe(handler); + this.applicationContext.getBeanFactory().registerSingleton( + handler.getClass().getSimpleName() + handler.hashCode(), handler); + this.applicationContext + .getBean(mappedBindingEntry.getKey(), SubscribableChannel.class) + .subscribe(handler); } this.mappedListenerMethods.clear(); } @Override - public final Object postProcessAfterInitialization(Object bean, final String beanName) throws BeansException { - Class targetClass = AopUtils.isAopProxy(bean) ? AopUtils.getTargetClass(bean) : bean.getClass(); - Method[] uniqueDeclaredMethods = ReflectionUtils.getUniqueDeclaredMethods(targetClass); + public final Object postProcessAfterInitialization(Object bean, final String beanName) + throws BeansException { + Class targetClass = AopUtils.isAopProxy(bean) ? AopUtils.getTargetClass(bean) + : bean.getClass(); + Method[] uniqueDeclaredMethods = ReflectionUtils + .getUniqueDeclaredMethods(targetClass); for (Method method : uniqueDeclaredMethods) { - StreamListener streamListener = AnnotatedElementUtils.findMergedAnnotation(method, StreamListener.class); + StreamListener streamListener = AnnotatedElementUtils + .findMergedAnnotation(method, StreamListener.class); if (streamListener != null && !method.isBridge()) { - streamListenerCallbacks.add(() -> { - Assert.isTrue(method.getAnnotation(Input.class) == null, StreamListenerErrorMessages.INPUT_AT_STREAM_LISTENER); + this.streamListenerCallbacks.add(() -> { + Assert.isTrue(method.getAnnotation(Input.class) == null, + StreamListenerErrorMessages.INPUT_AT_STREAM_LISTENER); this.doPostProcess(streamListener, method, bean); }); } @@ -174,25 +203,27 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces /** * Extension point, allowing subclasses to customize the {@link StreamListener} * annotation detected by the postprocessor. - * * @param originalAnnotation the original annotation * @param annotatedMethod the method on which the annotation has been found * @return the postprocessed {@link StreamListener} annotation */ - protected StreamListener postProcessAnnotation(StreamListener originalAnnotation, Method annotatedMethod) { + protected StreamListener postProcessAnnotation(StreamListener originalAnnotation, + Method annotatedMethod) { return originalAnnotation; } - private void doPostProcess(StreamListener streamListener, Method method, Object bean) { + private void doPostProcess(StreamListener streamListener, Method method, + Object bean) { streamListener = postProcessAnnotation(streamListener, method); - Optional streamListenerSetupMethodOrchestratorAvailable = - streamListenerSetupMethodOrchestrators.stream() - .filter(t -> t.supports(method)) - .findFirst(); - Assert.isTrue(streamListenerSetupMethodOrchestratorAvailable.isPresent(), + Optional orchestratorOptional; + orchestratorOptional = this.streamListenerSetupMethodOrchestrators.stream() + .filter(t -> t.supports(method)).findFirst(); + Assert.isTrue(orchestratorOptional.isPresent(), "A matching StreamListenerSetupMethodOrchestrator must be present"); - StreamListenerSetupMethodOrchestrator streamListenerSetupMethodOrchestrator = streamListenerSetupMethodOrchestratorAvailable.get(); - streamListenerSetupMethodOrchestrator.orchestrateStreamListenerSetupMethod(streamListener, method, bean); + StreamListenerSetupMethodOrchestrator streamListenerSetupMethodOrchestrator = orchestratorOptional + .get(); + streamListenerSetupMethodOrchestrator + .orchestrateStreamListenerSetupMethod(streamListener, method, bean); } private Method checkProxy(Method methodArg, Object bean) { @@ -202,11 +233,13 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces // Found a @StreamListener method on the target class for this JDK proxy // -> // is it also present on the proxy itself? - method = bean.getClass().getMethod(method.getName(), method.getParameterTypes()); + method = bean.getClass().getMethod(method.getName(), + method.getParameterTypes()); Class[] proxiedInterfaces = ((Advised) bean).getProxiedInterfaces(); for (Class iface : proxiedInterfaces) { try { - method = iface.getMethod(method.getName(), method.getParameterTypes()); + method = iface.getMethod(method.getName(), + method.getParameterTypes()); break; } catch (NoSuchMethodException noMethod) { @@ -222,7 +255,8 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces + "but not found in any interface(s) for bean JDK proxy. Either " + "pull the method up to an interface or switch to subclass (CGLIB) " + "proxies by setting proxy-target-class/proxyTargetClass attribute to 'true'", - method.getName(), method.getDeclaringClass().getSimpleName()), ex); + method.getName(), method.getDeclaringClass().getSimpleName()), + ex); } } return method; @@ -234,8 +268,8 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces return (String) resolved; } else { - throw new IllegalStateException("Resolved " + property + " to [" + resolved.getClass() - + "] instead of String for [" + value + "]"); + throw new IllegalStateException("Resolved " + property + " to [" + + resolved.getClass() + "] instead of String for [" + value + "]"); } } @@ -251,36 +285,47 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces return (Boolean) resolved; } else { - throw new IllegalStateException("Resolved " + property + " to [" + resolved.getClass() - + "] instead of String or Boolean for [" + value + "]"); + throw new IllegalStateException( + "Resolved " + property + " to [" + resolved.getClass() + + "] instead of String or Boolean for [" + value + "]"); } } private String resolveExpression(String value) { - String resolvedValue = this.applicationContext.getBeanFactory().resolveEmbeddedValue(value); + String resolvedValue = this.applicationContext.getBeanFactory() + .resolveEmbeddedValue(value); if (resolvedValue.startsWith("#{") && value.endsWith("}")) { - resolvedValue = (String) this.resolver.evaluate(resolvedValue, this.expressionContext); + resolvedValue = (String) this.resolver.evaluate(resolvedValue, + this.expressionContext); } return resolvedValue; } /** - * This operations ensures that required dependencies are not accidentally injected early given that this bean is BPP. + * This operations ensures that required dependencies are not accidentally injected + * early given that this bean is BPP. */ @SuppressWarnings({ "unchecked", "rawtypes" }) private void injectAndPostProcessDependencies() { - Collection streamListenerParameterAdapters = this.applicationContext.getBeansOfType(StreamListenerParameterAdapter.class).values(); - Collection streamListenerResultAdapters = this.applicationContext.getBeansOfType(StreamListenerResultAdapter.class).values(); - this.binderAwareChannelResolver = this.applicationContext.getBean(DestinationResolver.class); - this.messageHandlerMethodFactory = this.applicationContext.getBean(MessageHandlerMethodFactory.class); - this.springIntegrationProperties = this.applicationContext.getBean(SpringIntegrationProperties.class); + Collection streamListenerParameterAdapters = this.applicationContext + .getBeansOfType(StreamListenerParameterAdapter.class).values(); + Collection streamListenerResultAdapters = this.applicationContext + .getBeansOfType(StreamListenerResultAdapter.class).values(); + this.binderAwareChannelResolver = this.applicationContext + .getBean(DestinationResolver.class); + this.messageHandlerMethodFactory = this.applicationContext + .getBean(MessageHandlerMethodFactory.class); + this.springIntegrationProperties = this.applicationContext + .getBean(SpringIntegrationProperties.class); - this.streamListenerSetupMethodOrchestrators.addAll( - this.applicationContext.getBeansOfType(StreamListenerSetupMethodOrchestrator.class).values()); + this.streamListenerSetupMethodOrchestrators.addAll(this.applicationContext + .getBeansOfType(StreamListenerSetupMethodOrchestrator.class).values()); - //Default orchestrator for StreamListener method invocation is added last into the LinkedHashSet. - this.streamListenerSetupMethodOrchestrators.add(new DefaultStreamListenerSetupMethodOrchestrator(this.applicationContext, - streamListenerParameterAdapters, streamListenerResultAdapters)); + // Default orchestrator for StreamListener method invocation is added last into + // the LinkedHashSet. + this.streamListenerSetupMethodOrchestrators.add( + new DefaultStreamListenerSetupMethodOrchestrator(this.applicationContext, + streamListenerParameterAdapters, streamListenerResultAdapters)); this.streamListenerCallbacks.forEach(Runnable::run); } @@ -297,8 +342,8 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces private final String copyHeaders; - StreamListenerHandlerMethodMapping(Object targetBean, Method method, String condition, - String defaultOutputChannel, String copyHeaders) { + StreamListenerHandlerMethodMapping(Object targetBean, Method method, + String condition, String defaultOutputChannel, String copyHeaders) { this.targetBean = targetBean; this.method = method; this.condition = condition; @@ -307,28 +352,30 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces } Object getTargetBean() { - return targetBean; + return this.targetBean; } Method getMethod() { - return method; + return this.method; } String getCondition() { - return condition; + return this.condition; } String getDefaultOutputChannel() { - return defaultOutputChannel; + return this.defaultOutputChannel; } public String getCopyHeaders() { return this.copyHeaders; } + } @SuppressWarnings("rawtypes") - private class DefaultStreamListenerSetupMethodOrchestrator implements StreamListenerSetupMethodOrchestrator { + private final class DefaultStreamListenerSetupMethodOrchestrator + implements StreamListenerSetupMethodOrchestrator { private final ConfigurableApplicationContext applicationContext; @@ -336,59 +383,77 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces private final Collection streamListenerResultAdapters; - private DefaultStreamListenerSetupMethodOrchestrator(ConfigurableApplicationContext applicationContext, Collection streamListenerParameterAdapters, Collection streamListenerResultAdapters) { + private DefaultStreamListenerSetupMethodOrchestrator( + ConfigurableApplicationContext applicationContext, + Collection streamListenerParameterAdapters, + Collection streamListenerResultAdapters) { this.applicationContext = applicationContext; this.streamListenerParameterAdapters = streamListenerParameterAdapters; this.streamListenerResultAdapters = streamListenerResultAdapters; } @Override - public void orchestrateStreamListenerSetupMethod(StreamListener streamListener, Method method, Object bean) { + public void orchestrateStreamListenerSetupMethod(StreamListener streamListener, + Method method, Object bean) { String methodAnnotatedInboundName = streamListener.value(); - String methodAnnotatedOutboundName = StreamListenerMethodUtils.getOutboundBindingTargetName(method); - int inputAnnotationCount = StreamListenerMethodUtils.inputAnnotationCount(method); - int outputAnnotationCount = StreamListenerMethodUtils.outputAnnotationCount(method); - boolean isDeclarative = checkDeclarativeMethod(method, methodAnnotatedInboundName, methodAnnotatedOutboundName); + String methodAnnotatedOutboundName = StreamListenerMethodUtils + .getOutboundBindingTargetName(method); + int inputAnnotationCount = StreamListenerMethodUtils + .inputAnnotationCount(method); + int outputAnnotationCount = StreamListenerMethodUtils + .outputAnnotationCount(method); + boolean isDeclarative = checkDeclarativeMethod(method, + methodAnnotatedInboundName, methodAnnotatedOutboundName); StreamListenerMethodUtils.validateStreamListenerMethod(method, inputAnnotationCount, outputAnnotationCount, methodAnnotatedInboundName, methodAnnotatedOutboundName, isDeclarative, streamListener.condition()); if (isDeclarative) { - StreamListenerParameterAdapter[] toSlpaArray = new StreamListenerParameterAdapter[this.streamListenerParameterAdapters.size()]; - Object[] adaptedInboundArguments = adaptAndRetrieveInboundArguments(method, methodAnnotatedInboundName, - this.applicationContext, + StreamListenerParameterAdapter[] toSlpaArray; + toSlpaArray = new StreamListenerParameterAdapter[this.streamListenerParameterAdapters + .size()]; + Object[] adaptedInboundArguments = adaptAndRetrieveInboundArguments( + method, methodAnnotatedInboundName, this.applicationContext, this.streamListenerParameterAdapters.toArray(toSlpaArray)); - invokeStreamListenerResultAdapter(method, bean, methodAnnotatedOutboundName, adaptedInboundArguments); - } else { + invokeStreamListenerResultAdapter(method, bean, + methodAnnotatedOutboundName, adaptedInboundArguments); + } + else { registerHandlerMethodOnListenedChannel(method, streamListener, bean); } } @Override public boolean supports(Method method) { - //default catch all orchestrator + // default catch all orchestrator return true; } @SuppressWarnings("unchecked") - private void invokeStreamListenerResultAdapter(Method method, Object bean, String outboundName, Object... arguments) { + private void invokeStreamListenerResultAdapter(Method method, Object bean, + String outboundName, Object... arguments) { try { if (Void.TYPE.equals(method.getReturnType())) { method.invoke(bean, arguments); - } else { + } + else { Object result = method.invoke(bean, arguments); if (!StringUtils.hasText(outboundName)) { - for (int parameterIndex = 0; parameterIndex < method.getParameterTypes().length; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + for (int parameterIndex = 0; parameterIndex < method + .getParameterTypes().length; parameterIndex++) { + MethodParameter methodParameter = MethodParameter + .forExecutable(method, parameterIndex); if (methodParameter.hasParameterAnnotation(Output.class)) { - outboundName = methodParameter.getParameterAnnotation(Output.class).value(); + outboundName = methodParameter + .getParameterAnnotation(Output.class).value(); } } } Object targetBean = this.applicationContext.getBean(outboundName); for (StreamListenerResultAdapter streamListenerResultAdapter : this.streamListenerResultAdapters) { - if (streamListenerResultAdapter.supports(result.getClass(), targetBean.getClass())) { + if (streamListenerResultAdapter.supports(result.getClass(), + targetBean.getClass())) { streamListenerResultAdapter.adapt(result, targetBean); break; } @@ -396,16 +461,20 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces } } catch (Exception e) { - throw new BeanInitializationException("Cannot setup StreamListener for " + method, e); + throw new BeanInitializationException( + "Cannot setup StreamListener for " + method, e); } } - private void registerHandlerMethodOnListenedChannel(Method method, StreamListener streamListener, Object bean) { + private void registerHandlerMethodOnListenedChannel(Method method, + StreamListener streamListener, Object bean) { Assert.hasText(streamListener.value(), "The binding name cannot be null"); if (!StringUtils.hasText(streamListener.value())) { - throw new BeanInitializationException("A bound component name must be specified"); + throw new BeanInitializationException( + "A bound component name must be specified"); } - final String defaultOutputChannel = StreamListenerMethodUtils.getOutboundBindingTargetName(method); + final String defaultOutputChannel = StreamListenerMethodUtils + .getOutboundBindingTargetName(method); if (Void.TYPE.equals(method.getReturnType())) { Assert.isTrue(StringUtils.isEmpty(defaultOutputChannel), "An output channel cannot be specified for a method that does not return a value"); @@ -415,65 +484,83 @@ public class StreamListenerAnnotationBeanPostProcessor implements BeanPostProces "An output channel must be specified for a method that can return a value"); } StreamListenerMethodUtils.validateStreamListenerMessageHandler(method); - mappedListenerMethods.add(streamListener.value(), - new StreamListenerHandlerMethodMapping(bean, method, streamListener.condition(), defaultOutputChannel, + StreamListenerAnnotationBeanPostProcessor.this.mappedListenerMethods.add( + streamListener.value(), + new StreamListenerHandlerMethodMapping(bean, method, + streamListener.condition(), defaultOutputChannel, streamListener.copyHeaders())); } - private boolean checkDeclarativeMethod(Method method, String methodAnnotatedInboundName, String methodAnnotatedOutboundName) { + private boolean checkDeclarativeMethod(Method method, + String methodAnnotatedInboundName, String methodAnnotatedOutboundName) { int methodArgumentsLength = method.getParameterTypes().length; for (int parameterIndex = 0; parameterIndex < methodArgumentsLength; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + MethodParameter methodParameter = MethodParameter.forExecutable(method, + parameterIndex); if (methodParameter.hasParameterAnnotation(Input.class)) { - String inboundName = (String) AnnotationUtils - .getValue(methodParameter.getParameterAnnotation(Input.class)); - Assert.isTrue(StringUtils.hasText(inboundName), StreamListenerErrorMessages.INVALID_INBOUND_NAME); - Assert.isTrue(isDeclarativeMethodParameter(inboundName, methodParameter), + String inboundName = (String) AnnotationUtils.getValue( + methodParameter.getParameterAnnotation(Input.class)); + Assert.isTrue(StringUtils.hasText(inboundName), + StreamListenerErrorMessages.INVALID_INBOUND_NAME); + Assert.isTrue( + isDeclarativeMethodParameter(inboundName, methodParameter), StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); return true; } else if (methodParameter.hasParameterAnnotation(Output.class)) { - String outboundName = (String) AnnotationUtils - .getValue(methodParameter.getParameterAnnotation(Output.class)); - Assert.isTrue(StringUtils.hasText(outboundName), StreamListenerErrorMessages.INVALID_OUTBOUND_NAME); - Assert.isTrue(isDeclarativeMethodParameter(outboundName, methodParameter), + String outboundName = (String) AnnotationUtils.getValue( + methodParameter.getParameterAnnotation(Output.class)); + Assert.isTrue(StringUtils.hasText(outboundName), + StreamListenerErrorMessages.INVALID_OUTBOUND_NAME); + Assert.isTrue( + isDeclarativeMethodParameter(outboundName, methodParameter), StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); return true; } else if (StringUtils.hasText(methodAnnotatedOutboundName)) { - return isDeclarativeMethodParameter(methodAnnotatedOutboundName, methodParameter); + return isDeclarativeMethodParameter(methodAnnotatedOutboundName, + methodParameter); } else if (StringUtils.hasText(methodAnnotatedInboundName)) { - return isDeclarativeMethodParameter(methodAnnotatedInboundName, methodParameter); + return isDeclarativeMethodParameter(methodAnnotatedInboundName, + methodParameter); } } return false; } /** - * Determines if method parameters signify an imperative or declarative listener definition. - *
- * Imperative - where handler method is invoked on each message by the handler infrastructure provided - * by the framework - *
- * Declarative - where handler is provided by the method itself. - *
- * Declarative method parameter could either be {@link MessageChannel} or any other Object for which - * there is a {@link StreamListenerParameterAdapter} (i.e., {@link reactor.core.publisher.Flux}). Declarative method is invoked only - * once during initialization phase. + * Determines if method parameters signify an imperative or declarative listener + * definition.
+ * Imperative - where handler method is invoked on each message by the handler + * infrastructure provided by the framework
+ * Declarative - where handler is provided by the method itself.
+ * Declarative method parameter could either be {@link MessageChannel} or any + * other Object for which there is a {@link StreamListenerParameterAdapter} (i.e., + * {@link reactor.core.publisher.Flux}). Declarative method is invoked only once + * during initialization phase. + * @param targetBeanName name of the bean + * @param methodParameter method parameter + * @return {@code true} when the method parameter is declarative */ @SuppressWarnings("unchecked") - private boolean isDeclarativeMethodParameter(String targetBeanName, MethodParameter methodParameter) { + private boolean isDeclarativeMethodParameter(String targetBeanName, + MethodParameter methodParameter) { boolean declarative = false; - if (!methodParameter.getParameterType().isAssignableFrom(Object.class) && this.applicationContext.containsBean(targetBeanName)) { - declarative = MessageChannel.class.isAssignableFrom(methodParameter.getParameterType()); + if (!methodParameter.getParameterType().isAssignableFrom(Object.class) + && this.applicationContext.containsBean(targetBeanName)) { + declarative = MessageChannel.class + .isAssignableFrom(methodParameter.getParameterType()); if (!declarative) { - Class targetBeanClass = this.applicationContext.getType(targetBeanName); - declarative = this.streamListenerParameterAdapters.stream() - .anyMatch(slpa -> slpa.supports(targetBeanClass, methodParameter)); + Class targetBeanClass = this.applicationContext + .getType(targetBeanName); + declarative = this.streamListenerParameterAdapters.stream().anyMatch( + slpa -> slpa.supports(targetBeanClass, methodParameter)); } } return declarative; } + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerErrorMessages.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerErrorMessages.java index 09b670247..d255b82f7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerErrorMessages.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerErrorMessages.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,49 +21,113 @@ package org.springframework.cloud.stream.binding; */ public abstract class StreamListenerErrorMessages { + /** + * Error message when the inbound name was invalid. + */ public static final String INVALID_INBOUND_NAME = "The @Input annotation must have the name of an input as value"; + /** + * Error message when the outbound name was invalid. + */ public static final String INVALID_OUTBOUND_NAME = "The @Output annotation must have the name of an input as value"; + /** + * Error message when there were no outputs specified. + */ public static final String ATLEAST_ONE_OUTPUT = "At least one output must be specified"; + /** + * Error message when multiple destinations were specified. + */ public static final String SEND_TO_MULTIPLE_DESTINATIONS = "Multiple destinations cannot be specified"; + /** + * Error message when empty destination was provided. + */ public static final String SEND_TO_EMPTY_DESTINATION = "An empty destination cannot be specified"; - public static final String INVALID_INPUT_OUTPUT_METHOD_PARAMETERS = "@Input or @Output annotations are not permitted on " + /** + * Error message when the input or output annotation got placed on a method parameter. + */ + public static final String INVALID_INPUT_OUTPUT_METHOD_PARAMETERS = "@Input or @Output annotations " + + "are not permitted on " + "method parameters while using the @StreamListener value and a method-level output specification"; - public static final String NO_INPUT_DESTINATION = "No input destination is configured. Use either the @StreamListener value or @Input"; + /** + * Error message when no input destination was provided. + */ + public static final String NO_INPUT_DESTINATION = "No input destination is configured. " + + "Use either the @StreamListener value or @Input"; - public static final String AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS = "Ambiguous method arguments for the StreamListener method"; + /** + * Error message when an ambiguous message handler method argument was found. + */ + public static final String AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS = "Ambiguous method arguments " + + "for the StreamListener method"; - public static final String INVALID_INPUT_VALUES = "Cannot set both @StreamListener value and @Input annotation as method parameter"; + /** + * Error message when invalid input values where set. + */ + public static final String INVALID_INPUT_VALUES = "Cannot set both @StreamListener " + + "value and @Input annotation as method parameter"; - public static final String INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM = "Setting the @StreamListener value when using" - + " @Output annotation as method parameter is not permitted. Use @Input method parameter annotation to specify inbound value instead"; + /** + * Error message when invalid input value with output method parameter was set. + */ + public static final String INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM = "Setting the @StreamListener " + + "value when using @Output annotation as method parameter is not permitted. " + + "Use @Input method parameter annotation to specify inbound value instead"; + /** + * Error message when invalid output values were set. + */ public static final String INVALID_OUTPUT_VALUES = "Cannot set both output (@Output/@SendTo) method annotation value" + " and @Output annotation as a method parameter"; - public static final String CONDITION_ON_DECLARATIVE_METHOD = "Cannot set a condition when using @StreamListener in declarative mode"; + /** + * Error message when condition was set in declarative mode. + */ + public static final String CONDITION_ON_DECLARATIVE_METHOD = "Cannot set a condition when " + + "using @StreamListener in declarative mode"; - public static final String CONDITION_ON_METHOD_RETURNING_VALUE = "Cannot set a condition for methods that return a value"; + /** + * Error message when condition was set for methods that return a value. + */ + public static final String CONDITION_ON_METHOD_RETURNING_VALUE = "Cannot set a condition " + + "for methods that return a value"; - public static final String MULTIPLE_VALUE_RETURNING_METHODS = "If multiple @StreamListener methods are listening to the same binding target, none of them may return a value"; + /** + * Error message when multiple value returning methods were provided. + */ + public static final String MULTIPLE_VALUE_RETURNING_METHODS = "If multiple @StreamListener " + + "methods are listening to the same binding target, none of them may return a value"; private static final String PREFIX = "A method annotated with @StreamListener "; + /** + * Error message when @StreamListener was used with @Input. + */ public static final String INPUT_AT_STREAM_LISTENER = PREFIX + "may never be annotated with @Input. " + "If it should listen to a specific input, use the value of @StreamListener instead"; + /** + * Error message when invalid input value with output method parameter was set. + */ public static final String RETURN_TYPE_NO_OUTBOUND_SPECIFIED = PREFIX + "having a return type should also have an outbound target specified"; + /** + * Error message when return type was specified for multiple outbound targets. + */ public static final String RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED = PREFIX + "having a return type should have only one outbound target specified"; + /** + * Error message when invalid declarative method parameters were set. + */ public static final String INVALID_DECLARATIVE_METHOD_PARAMETERS = PREFIX - + "may use @Input or @Output annotations only in declarative mode and for parameters that are binding targets or convertible from binding targets."; + + "may use @Input or @Output annotations only in declarative mode " + + "and for parameters that are binding targets or convertible from binding targets."; + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMessageHandler.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMessageHandler.java index fcace8939..435dae125 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMessageHandler.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,8 +32,8 @@ public class StreamListenerMessageHandler extends AbstractReplyProducingMessageH private final boolean copyHeaders; - StreamListenerMessageHandler(InvocableHandlerMethod invocableHandlerMethod, boolean copyHeaders, - String[] notPropagatedHeaders) { + StreamListenerMessageHandler(InvocableHandlerMethod invocableHandlerMethod, + boolean copyHeaders, String[] notPropagatedHeaders) { super(); this.invocableHandlerMethod = invocableHandlerMethod; this.copyHeaders = copyHeaders; @@ -46,7 +46,7 @@ public class StreamListenerMessageHandler extends AbstractReplyProducingMessageH } public boolean isVoid() { - return invocableHandlerMethod.isVoid(); + return this.invocableHandlerMethod.isVoid(); } @Override @@ -60,8 +60,11 @@ public class StreamListenerMessageHandler extends AbstractReplyProducingMessageH } else { throw new MessagingException(requestMessage, - "Exception thrown while invoking " + this.invocableHandlerMethod.getShortLogMessage(), e); + "Exception thrown while invoking " + + this.invocableHandlerMethod.getShortLogMessage(), + e); } } } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMethodUtils.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMethodUtils.java index 3169579aa..10108eb1d 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMethodUtils.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerMethodUtils.java @@ -35,12 +35,18 @@ import org.springframework.util.StringUtils; * * @author Ilayaperumal Gopinathan */ -public class StreamListenerMethodUtils { +public final class StreamListenerMethodUtils { + + private StreamListenerMethodUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } protected static int inputAnnotationCount(Method method) { int inputAnnotationCount = 0; - for (int parameterIndex = 0; parameterIndex < method.getParameterTypes().length; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + for (int parameterIndex = 0; parameterIndex < method + .getParameterTypes().length; parameterIndex++) { + MethodParameter methodParameter = MethodParameter.forExecutable(method, + parameterIndex); if (methodParameter.hasParameterAnnotation(Input.class)) { inputAnnotationCount++; } @@ -50,8 +56,10 @@ public class StreamListenerMethodUtils { protected static int outputAnnotationCount(Method method) { int outputAnnotationCount = 0; - for (int parameterIndex = 0; parameterIndex < method.getParameterTypes().length; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + for (int parameterIndex = 0; parameterIndex < method + .getParameterTypes().length; parameterIndex++) { + MethodParameter methodParameter = MethodParameter.forExecutable(method, + parameterIndex); if (methodParameter.hasParameterAnnotation(Output.class)) { outputAnnotationCount++; } @@ -59,28 +67,33 @@ public class StreamListenerMethodUtils { return outputAnnotationCount; } - protected static void validateStreamListenerMethod(Method method, int inputAnnotationCount, - int outputAnnotationCount, String methodAnnotatedInboundName, String methodAnnotatedOutboundName, + protected static void validateStreamListenerMethod(Method method, + int inputAnnotationCount, int outputAnnotationCount, + String methodAnnotatedInboundName, String methodAnnotatedOutboundName, boolean isDeclarative, String condition) { int methodArgumentsLength = method.getParameterTypes().length; if (!isDeclarative) { Assert.isTrue(inputAnnotationCount == 0 && outputAnnotationCount == 0, StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); } - if (StringUtils.hasText(methodAnnotatedInboundName) && StringUtils.hasText(methodAnnotatedOutboundName)) { + if (StringUtils.hasText(methodAnnotatedInboundName) + && StringUtils.hasText(methodAnnotatedOutboundName)) { Assert.isTrue(inputAnnotationCount == 0 && outputAnnotationCount == 0, StreamListenerErrorMessages.INVALID_INPUT_OUTPUT_METHOD_PARAMETERS); } if (StringUtils.hasText(methodAnnotatedInboundName)) { - Assert.isTrue(inputAnnotationCount == 0, StreamListenerErrorMessages.INVALID_INPUT_VALUES); + Assert.isTrue(inputAnnotationCount == 0, + StreamListenerErrorMessages.INVALID_INPUT_VALUES); Assert.isTrue(outputAnnotationCount == 0, StreamListenerErrorMessages.INVALID_INPUT_VALUE_WITH_OUTPUT_METHOD_PARAM); } else { - Assert.isTrue(inputAnnotationCount >= 1, StreamListenerErrorMessages.NO_INPUT_DESTINATION); + Assert.isTrue(inputAnnotationCount >= 1, + StreamListenerErrorMessages.NO_INPUT_DESTINATION); } if (StringUtils.hasText(methodAnnotatedOutboundName)) { - Assert.isTrue(outputAnnotationCount == 0, StreamListenerErrorMessages.INVALID_OUTPUT_VALUES); + Assert.isTrue(outputAnnotationCount == 0, + StreamListenerErrorMessages.INVALID_OUTPUT_VALUES); } if (!Void.TYPE.equals(method.getReturnType())) { Assert.isTrue(!StringUtils.hasText(condition), @@ -90,20 +103,25 @@ public class StreamListenerMethodUtils { Assert.isTrue(!StringUtils.hasText(condition), StreamListenerErrorMessages.CONDITION_ON_DECLARATIVE_METHOD); for (int parameterIndex = 0; parameterIndex < methodArgumentsLength; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + MethodParameter methodParameter = MethodParameter.forExecutable(method, + parameterIndex); if (methodParameter.hasParameterAnnotation(Input.class)) { - String inboundName = (String) AnnotationUtils - .getValue(methodParameter.getParameterAnnotation(Input.class)); - Assert.isTrue(StringUtils.hasText(inboundName), StreamListenerErrorMessages.INVALID_INBOUND_NAME); + String inboundName = (String) AnnotationUtils.getValue( + methodParameter.getParameterAnnotation(Input.class)); + Assert.isTrue(StringUtils.hasText(inboundName), + StreamListenerErrorMessages.INVALID_INBOUND_NAME); } if (methodParameter.hasParameterAnnotation(Output.class)) { - String outboundName = (String) AnnotationUtils - .getValue(methodParameter.getParameterAnnotation(Output.class)); - Assert.isTrue(StringUtils.hasText(outboundName), StreamListenerErrorMessages.INVALID_OUTBOUND_NAME); + String outboundName = (String) AnnotationUtils.getValue( + methodParameter.getParameterAnnotation(Output.class)); + Assert.isTrue(StringUtils.hasText(outboundName), + StreamListenerErrorMessages.INVALID_OUTBOUND_NAME); } } if (methodArgumentsLength > 1) { - Assert.isTrue(inputAnnotationCount + outputAnnotationCount == methodArgumentsLength, + Assert.isTrue( + inputAnnotationCount + + outputAnnotationCount == methodArgumentsLength, StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); } } @@ -111,9 +129,11 @@ public class StreamListenerMethodUtils { if (!method.getReturnType().equals(Void.TYPE)) { if (!StringUtils.hasText(methodAnnotatedOutboundName)) { if (outputAnnotationCount == 0) { - throw new IllegalArgumentException(StreamListenerErrorMessages.RETURN_TYPE_NO_OUTBOUND_SPECIFIED); + throw new IllegalArgumentException( + StreamListenerErrorMessages.RETURN_TYPE_NO_OUTBOUND_SPECIFIED); } - Assert.isTrue((outputAnnotationCount == 1), StreamListenerErrorMessages.RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED); + Assert.isTrue((outputAnnotationCount == 1), + StreamListenerErrorMessages.RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED); } } } @@ -124,7 +144,8 @@ public class StreamListenerMethodUtils { int numAnnotatedMethodParameters = 0; int numPayloadAnnotations = 0; for (int parameterIndex = 0; parameterIndex < methodArgumentsLength; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + MethodParameter methodParameter = MethodParameter.forExecutable(method, + parameterIndex); if (methodParameter.hasParameterAnnotations()) { numAnnotatedMethodParameters++; } @@ -133,7 +154,9 @@ public class StreamListenerMethodUtils { } } if (numPayloadAnnotations > 0) { - Assert.isTrue(methodArgumentsLength == numAnnotatedMethodParameters && numPayloadAnnotations <= 1, + Assert.isTrue( + methodArgumentsLength == numAnnotatedMethodParameters + && numPayloadAnnotations <= 1, StreamListenerErrorMessages.AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS); } } @@ -142,16 +165,21 @@ public class StreamListenerMethodUtils { protected static String getOutboundBindingTargetName(Method method) { SendTo sendTo = AnnotationUtils.findAnnotation(method, SendTo.class); if (sendTo != null) { - Assert.isTrue(!ObjectUtils.isEmpty(sendTo.value()), StreamListenerErrorMessages.ATLEAST_ONE_OUTPUT); - Assert.isTrue(sendTo.value().length == 1, StreamListenerErrorMessages.SEND_TO_MULTIPLE_DESTINATIONS); - Assert.hasText(sendTo.value()[0], StreamListenerErrorMessages.SEND_TO_EMPTY_DESTINATION); + Assert.isTrue(!ObjectUtils.isEmpty(sendTo.value()), + StreamListenerErrorMessages.ATLEAST_ONE_OUTPUT); + Assert.isTrue(sendTo.value().length == 1, + StreamListenerErrorMessages.SEND_TO_MULTIPLE_DESTINATIONS); + Assert.hasText(sendTo.value()[0], + StreamListenerErrorMessages.SEND_TO_EMPTY_DESTINATION); return sendTo.value()[0]; } Output output = AnnotationUtils.findAnnotation(method, Output.class); if (output != null) { - Assert.isTrue(StringUtils.hasText(output.value()), StreamListenerErrorMessages.ATLEAST_ONE_OUTPUT); + Assert.isTrue(StringUtils.hasText(output.value()), + StreamListenerErrorMessages.ATLEAST_ONE_OUTPUT); return output.value(); } return null; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerParameterAdapter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerParameterAdapter.java index ba80d4eb7..c40db720b 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerParameterAdapter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerParameterAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,9 @@ import org.springframework.core.MethodParameter; * {@link org.springframework.messaging.MessageChannel}) supported by an existing binder. * * This is a framework extension and is not primarily intended for use by end-users. + * + * @param adapter type + * @param binding result type * @author Marius Bogoevici */ public interface StreamListenerParameterAdapter { @@ -48,4 +51,5 @@ public interface StreamListenerParameterAdapter { * @return an instance of the parameter type, which will be passed to the method */ A adapt(B bindingTarget, MethodParameter parameter); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerResultAdapter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerResultAdapter.java index 5283ad428..68a222cf6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerResultAdapter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerResultAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,9 @@ import java.io.Closeable; * * Used when the {@link org.springframework.cloud.stream.annotation.StreamListener} * annotated method is operating in declarative mode. + * + * @param stream listener result type + * @param binding target type * @author Marius Bogoevici */ public interface StreamListenerResultAdapter { @@ -42,6 +45,7 @@ public interface StreamListenerResultAdapter { * Adapts the result to the binding target. * @param streamListenerResult the result of invoking the method. * @param bindingTarget the binding target. + * @return an adapted result */ Closeable adapt(R streamListenerResult, B bindingTarget); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerSetupMethodOrchestrator.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerSetupMethodOrchestrator.java index 5b06d9e35..0f6398759 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerSetupMethodOrchestrator.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/StreamListenerSetupMethodOrchestrator.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -30,30 +30,32 @@ import org.springframework.util.StringUtils; /** * Orchestrator used for invoking the {@link StreamListener} setup method. * - * By default {@link StreamListenerAnnotationBeanPostProcessor} will use an internal implementation - * of this interface to invoke {@link StreamListenerParameterAdapter}s and {@link StreamListenerResultAdapter}s - * or handler mappings on the method annotated with {@link StreamListener}. + * By default {@link StreamListenerAnnotationBeanPostProcessor} will use an internal + * implementation of this interface to invoke {@link StreamListenerParameterAdapter}s and + * {@link StreamListenerResultAdapter}s or handler mappings on the method annotated with + * {@link StreamListener}. * - * By providing a different implementation of this interface and registering it as a Spring Bean in the - * context, one can override the default invocation strategies used by the {@link StreamListenerAnnotationBeanPostProcessor}. - * A typical usecase for such overriding can happen when a downstream {@link org.springframework.cloud.stream.binder.Binder} - * implementation wants to change the way in which any of the default StreamListener handling needs to be changed in a + * By providing a different implementation of this interface and registering it as a + * Spring Bean in the context, one can override the default invocation strategies used by + * the {@link StreamListenerAnnotationBeanPostProcessor}. A typical usecase for such + * overriding can happen when a downstream + * {@link org.springframework.cloud.stream.binder.Binder} implementation wants to change + * the way in which any of the default StreamListener handling needs to be changed in a * custom manner. * - * When beans of this interface are present in the context, they get priority in the {@link StreamListenerAnnotationBeanPostProcessor} - * before falling back to the default implementation. - * - * @see StreamListener - * @see StreamListenerAnnotationBeanPostProcessor + * When beans of this interface are present in the context, they get priority in the + * {@link StreamListenerAnnotationBeanPostProcessor} before falling back to the default + * implementation. * * @author Soby Chacko + * @see StreamListener + * @see StreamListenerAnnotationBeanPostProcessor */ public interface StreamListenerSetupMethodOrchestrator { /** - * Checks the method annotated with {@link StreamListener} to see if this implementation - * can successfully orchestrate this method. - * + * Checks the method annotated with {@link StreamListener} to see if this + * implementation can successfully orchestrate this method. * @param method annotated with {@link StreamListener} * @return true if this implementation can orchestrate this method, false otherwise */ @@ -61,18 +63,19 @@ public interface StreamListenerSetupMethodOrchestrator { /** * Method that allows custom orchestration on the {@link StreamListener} setup method. - * - * @param streamListener reference to the {@link StreamListener} annotation on the method + * @param streamListener reference to the {@link StreamListener} annotation on the + * method * @param method annotated with {@link StreamListener} * @param bean that contains the StreamListener method * */ - void orchestrateStreamListenerSetupMethod(StreamListener streamListener, Method method, Object bean); + void orchestrateStreamListenerSetupMethod(StreamListener streamListener, + Method method, Object bean); /** - * Default implementation for adapting each of the incoming method arguments using an available - * {@link StreamListenerParameterAdapter} and provide the adapted collection of arguments back to the caller. - * + * Default implementation for adapting each of the incoming method arguments using an + * available {@link StreamListenerParameterAdapter} and provide the adapted collection + * of arguments back to the caller. * @param method annotated with {@link StreamListener} * @param inboundName inbound binding * @param applicationContext spring application context @@ -81,40 +84,51 @@ public interface StreamListenerSetupMethodOrchestrator { */ @SuppressWarnings({ "rawtypes", "unchecked" }) default Object[] adaptAndRetrieveInboundArguments(Method method, String inboundName, - ApplicationContext applicationContext, - StreamListenerParameterAdapter... streamListenerParameterAdapters) { + ApplicationContext applicationContext, + StreamListenerParameterAdapter... streamListenerParameterAdapters) { Object[] arguments = new Object[method.getParameterTypes().length]; for (int parameterIndex = 0; parameterIndex < arguments.length; parameterIndex++) { - MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex); + MethodParameter methodParameter = MethodParameter.forExecutable(method, + parameterIndex); Class parameterType = methodParameter.getParameterType(); Object targetReferenceValue = null; if (methodParameter.hasParameterAnnotation(Input.class)) { - targetReferenceValue = AnnotationUtils.getValue(methodParameter.getParameterAnnotation(Input.class)); + targetReferenceValue = AnnotationUtils + .getValue(methodParameter.getParameterAnnotation(Input.class)); } else if (methodParameter.hasParameterAnnotation(Output.class)) { - targetReferenceValue = AnnotationUtils.getValue(methodParameter.getParameterAnnotation(Output.class)); + targetReferenceValue = AnnotationUtils + .getValue(methodParameter.getParameterAnnotation(Output.class)); } else if (arguments.length == 1 && StringUtils.hasText(inboundName)) { targetReferenceValue = inboundName; } if (targetReferenceValue != null) { - Assert.isInstanceOf(String.class, targetReferenceValue, "Annotation value must be a String"); - Object targetBean = applicationContext.getBean((String) targetReferenceValue); + Assert.isInstanceOf(String.class, targetReferenceValue, + "Annotation value must be a String"); + Object targetBean = applicationContext + .getBean((String) targetReferenceValue); // Iterate existing parameter adapters first for (StreamListenerParameterAdapter streamListenerParameterAdapter : streamListenerParameterAdapters) { - if (streamListenerParameterAdapter.supports(targetBean.getClass(), methodParameter)) { - arguments[parameterIndex] = streamListenerParameterAdapter.adapt(targetBean, methodParameter); + if (streamListenerParameterAdapter.supports(targetBean.getClass(), + methodParameter)) { + arguments[parameterIndex] = streamListenerParameterAdapter + .adapt(targetBean, methodParameter); break; } } - if (arguments[parameterIndex] == null && parameterType.isAssignableFrom(targetBean.getClass())) { + if (arguments[parameterIndex] == null + && parameterType.isAssignableFrom(targetBean.getClass())) { arguments[parameterIndex] = targetBean; } - Assert.notNull(arguments[parameterIndex], "Cannot convert argument " + parameterIndex + " of " + method - + "from " + targetBean.getClass() + " to " + parameterType); + Assert.notNull(arguments[parameterIndex], + "Cannot convert argument " + parameterIndex + " of " + method + + "from " + targetBean.getClass() + " to " + + parameterType); } else { - throw new IllegalStateException(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); + throw new IllegalStateException( + StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS); } } return arguments; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SubscribableChannelBindingTargetFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SubscribableChannelBindingTargetFactory.java index 8e31a90e9..c91aec5d7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SubscribableChannelBindingTargetFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/SubscribableChannelBindingTargetFactory.java @@ -30,11 +30,13 @@ import org.springframework.messaging.SubscribableChannel; * @author Ilayaperumal Gopinathan * @author Oleg Zhurakousky */ -public class SubscribableChannelBindingTargetFactory extends AbstractBindingTargetFactory { +public class SubscribableChannelBindingTargetFactory + extends AbstractBindingTargetFactory { private final MessageChannelConfigurer messageChannelConfigurer; - public SubscribableChannelBindingTargetFactory(MessageChannelConfigurer messageChannelConfigurer) { + public SubscribableChannelBindingTargetFactory( + MessageChannelConfigurer messageChannelConfigurer) { super(SubscribableChannel.class); this.messageChannelConfigurer = messageChannelConfigurer; } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java index 3e657f18c..f76535aa3 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java @@ -73,28 +73,28 @@ import org.springframework.validation.Validator; * @author Oleg Zhurakousky * @author Soby Chacko * @author David Harrigan - * - * @deprecated since it really represents 'auto-configuration' it will be renamed/restructured in the next release. + * @deprecated since it really represents 'auto-configuration' it will be + * renamed/restructured in the next release. */ @Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) @EnableConfigurationProperties({ BindingServiceProperties.class }) -@Import({ContentTypeConfiguration.class}) +@Import({ ContentTypeConfiguration.class }) @Deprecated public class BinderFactoryConfiguration { - protected final Log logger = LogFactory.getLog(getClass()); - private static final String SPRING_CLOUD_STREAM_INTERNAL_PREFIX = "spring.cloud.stream.internal"; private static final String SELF_CONTAINED_APP_PROPERTY_NAME = SPRING_CLOUD_STREAM_INTERNAL_PREFIX + ".selfContained"; + protected final Log logger = LogFactory.getLog(getClass()); + @Value("${" + SELF_CONTAINED_APP_PROPERTY_NAME + ":}") private String selfContained; - static Collection parseBinderConfigurations(ClassLoader classLoader, Resource resource) - throws IOException, ClassNotFoundException { + static Collection parseBinderConfigurations(ClassLoader classLoader, + Resource resource) throws IOException, ClassNotFoundException { Properties properties = PropertiesLoaderUtils.loadProperties(resource); Collection parsedBinderConfigurations = new ArrayList<>(); for (Map.Entry entry : properties.entrySet()) { @@ -104,29 +104,83 @@ public class BinderFactoryConfiguration { Class[] binderConfigurationClasses = new Class[binderConfigurationClassNames.length]; int i = 0; for (String binderConfigurationClassName : binderConfigurationClassNames) { - binderConfigurationClasses[i++] = ClassUtils.forName(binderConfigurationClassName, classLoader); + binderConfigurationClasses[i++] = ClassUtils + .forName(binderConfigurationClassName, classLoader); } - parsedBinderConfigurations.add(new BinderType(binderType, binderConfigurationClasses)); + parsedBinderConfigurations + .add(new BinderType(binderType, binderConfigurationClasses)); } return parsedBinderConfigurations; } @Bean - public BinderTypeRegistry binderTypeRegistry(ConfigurableApplicationContext configurableApplicationContext) { + public static MessageHandlerMethodFactory messageHandlerMethodFactory( + CompositeMessageConverterFactory compositeMessageConverterFactory, + @Qualifier(IntegrationContextUtils.ARGUMENT_RESOLVERS_BEAN_NAME) HandlerMethodArgumentResolversHolder ahmar, + @Nullable Validator validator, ConfigurableListableBeanFactory clbf) { + + DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory(); + messageHandlerMethodFactory.setMessageConverter( + compositeMessageConverterFactory.getMessageConverterForAllRegistered()); + + /* + * We essentially do the same thing as the + * DefaultMessageHandlerMethodFactory.initArgumentResolvers(..). We can't do it as + * custom resolvers for two reasons. 1. We would have two duplicate (compatible) + * resolvers, so they would need to be ordered properly to ensure these new + * resolvers take precedence. 2. + * DefaultMessageHandlerMethodFactory.initArgumentResolvers(..) puts + * MessageMethodArgumentResolver before custom converters thus not allowing an + * override which kind of proves #1. + * + * In all, all this will be obsolete once https://jira.spring.io/browse/SPR-17503 + * is addressed and we can fall back on core resolvers + */ + List resolvers = new LinkedList<>(); + resolvers.add(new SmartPayloadArgumentResolver( + compositeMessageConverterFactory.getMessageConverterForAllRegistered(), + validator)); + resolvers.add(new SmartMessageMethodArgumentResolver( + compositeMessageConverterFactory.getMessageConverterForAllRegistered())); + resolvers.add(new HeaderMethodArgumentResolver(null, clbf)); + resolvers.add(new HeadersMethodArgumentResolver()); + resolvers.addAll(ahmar.getResolvers()); + + // modify HandlerMethodArgumentResolversHolder + Field field = ReflectionUtils + .findField(HandlerMethodArgumentResolversHolder.class, "resolvers"); + field.setAccessible(true); + ((List) ReflectionUtils.getField(field, ahmar)).clear(); + resolvers.forEach(ahmar::addResolver); + // -- + + messageHandlerMethodFactory.setArgumentResolvers(resolvers); + messageHandlerMethodFactory.setValidator(validator); + return messageHandlerMethodFactory; + } + + @Bean + public BinderTypeRegistry binderTypeRegistry( + ConfigurableApplicationContext configurableApplicationContext) { Map binderTypes = new HashMap<>(); ClassLoader classLoader = configurableApplicationContext.getClassLoader(); - // the above can never be null since it will default to ClassUtils.getDefaultClassLoader(..) + // the above can never be null since it will default to + // ClassUtils.getDefaultClassLoader(..) try { - Enumeration resources = classLoader.getResources("META-INF/spring.binders"); - if (!Boolean.valueOf(this.selfContained) && (resources == null || !resources.hasMoreElements())) { - this.logger.debug("Failed to locate 'META-INF/spring.binders' resources on the classpath." - + " Assuming standard boot 'META-INF/spring.factories' configuration is used"); + Enumeration resources = classLoader + .getResources("META-INF/spring.binders"); + if (!Boolean.valueOf(this.selfContained) + && (resources == null || !resources.hasMoreElements())) { + this.logger.debug( + "Failed to locate 'META-INF/spring.binders' resources on the classpath." + + " Assuming standard boot 'META-INF/spring.factories' configuration is used"); } else { while (resources.hasMoreElements()) { URL url = resources.nextElement(); UrlResource resource = new UrlResource(url); - for (BinderType binderType : parseBinderConfigurations(classLoader, resource)) { + for (BinderType binderType : parseBinderConfigurations(classLoader, + resource)) { binderTypes.put(binderType.getDefaultName(), binderType); } } @@ -140,21 +194,27 @@ public class BinderFactoryConfiguration { } @Bean - public MessageConverterConfigurer messageConverterConfigurer(BindingServiceProperties bindingServiceProperties, - CompositeMessageConverterFactory compositeMessageConverterFactory) { - return new MessageConverterConfigurer(bindingServiceProperties, compositeMessageConverterFactory); + public MessageConverterConfigurer messageConverterConfigurer( + BindingServiceProperties bindingServiceProperties, + CompositeMessageConverterFactory compositeMessageConverterFactory) { + return new MessageConverterConfigurer(bindingServiceProperties, + compositeMessageConverterFactory); } @Bean public SubscribableChannelBindingTargetFactory channelFactory( CompositeMessageChannelConfigurer compositeMessageChannelConfigurer) { - return new SubscribableChannelBindingTargetFactory(compositeMessageChannelConfigurer); + return new SubscribableChannelBindingTargetFactory( + compositeMessageChannelConfigurer); } @Bean - public MessageSourceBindingTargetFactory messageSourceFactory(CompositeMessageConverterFactory compositeMessageConverterFactory, - CompositeMessageChannelConfigurer compositeMessageChannelConfigurer) { - return new MessageSourceBindingTargetFactory(compositeMessageConverterFactory.getMessageConverterForAllRegistered(), compositeMessageChannelConfigurer); + public MessageSourceBindingTargetFactory messageSourceFactory( + CompositeMessageConverterFactory compositeMessageConverterFactory, + CompositeMessageChannelConfigurer compositeMessageChannelConfigurer) { + return new MessageSourceBindingTargetFactory( + compositeMessageConverterFactory.getMessageConverterForAllRegistered(), + compositeMessageChannelConfigurer); } @Bean @@ -165,43 +225,4 @@ public class BinderFactoryConfiguration { return new CompositeMessageChannelConfigurer(configurerList); } - @Bean - public static MessageHandlerMethodFactory messageHandlerMethodFactory(CompositeMessageConverterFactory compositeMessageConverterFactory, - @Qualifier(IntegrationContextUtils.ARGUMENT_RESOLVERS_BEAN_NAME) HandlerMethodArgumentResolversHolder ahmar, - @Nullable Validator validator, ConfigurableListableBeanFactory clbf) { - - DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory(); - messageHandlerMethodFactory.setMessageConverter(compositeMessageConverterFactory.getMessageConverterForAllRegistered()); - - /* - * We essentially do the same thing as the DefaultMessageHandlerMethodFactory.initArgumentResolvers(..). - * We can't do it as custom resolvers for two reasons. - * 1. We would have two duplicate (compatible) resolvers, so they would need to be ordered properly - * to ensure these new resolvers take precedence. - * 2. DefaultMessageHandlerMethodFactory.initArgumentResolvers(..) puts MessageMethodArgumentResolver - * before custom converters thus not allowing an override which kind of proves #1. - * - * In all, all this will be obsolete once https://jira.spring.io/browse/SPR-17503 is addressed and we can fall back on - * core resolvers - */ - List resolvers = new LinkedList<>(); - resolvers.add(new SmartPayloadArgumentResolver(compositeMessageConverterFactory.getMessageConverterForAllRegistered(), validator)); - resolvers.add(new SmartMessageMethodArgumentResolver(compositeMessageConverterFactory.getMessageConverterForAllRegistered())); - resolvers.add(new HeaderMethodArgumentResolver(null, clbf)); - resolvers.add(new HeadersMethodArgumentResolver()); - resolvers.addAll(ahmar.getResolvers()); - - // modify HandlerMethodArgumentResolversHolder - Field field = ReflectionUtils.findField(HandlerMethodArgumentResolversHolder.class, "resolvers"); - field.setAccessible(true); - ((List) ReflectionUtils.getField(field, ahmar)).clear(); - resolvers.forEach(ahmar::addResolver); - // -- - - messageHandlerMethodFactory.setArgumentResolvers(resolvers); - messageHandlerMethodFactory.setValidator(validator); - return messageHandlerMethodFactory; - } - - } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderProperties.java index 56d60540a..16ca7d1f9 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderProperties.java @@ -31,29 +31,31 @@ public class BinderProperties { /** * The binder type. It typically references one of the binders found on the classpath, - * in particular a key in a META-INF/spring.binders file. - * By default, it has the same value as the configuration name. + * in particular a key in a META-INF/spring.binders file. By default, it has the same + * value as the configuration name. */ private String type; /** - * Root for a set of properties that can be used to customize the environment of the binder. + * Root for a set of properties that can be used to customize the environment of the + * binder. */ private Map environment = new HashMap<>(); /** - * Whether the configuration will inherit the environment of the application itself. Default: true + * Whether the configuration will inherit the environment of the application itself. + * Default: true */ private boolean inheritEnvironment = true; /** - * Whether the binder configuration is a candidate for being considered a default binder, - * or can be used only when explicitly referenced. Defaulys: true + * Whether the binder configuration is a candidate for being considered a default + * binder, or can be used only when explicitly referenced. Defaulys: true */ private boolean defaultCandidate = true; public String getType() { - return type; + return this.type; } public void setType(String name) { @@ -61,16 +63,18 @@ public class BinderProperties { } public Map getEnvironment() { - return environment; + return this.environment; } /** * @deprecated in 2.0.0 in preference to {@link #setEnvironment(Map)} + * @param environment properties to which stream props will be added */ @Deprecated public void setEnvironment(Properties environment) { this.environment.clear(); - this.environment.putAll(environment.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue()))); + this.environment.putAll(environment.entrySet().stream().collect( + Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue()))); } public void setEnvironment(Map environment) { @@ -78,7 +82,7 @@ public class BinderProperties { } public boolean isInheritEnvironment() { - return inheritEnvironment; + return this.inheritEnvironment; } public void setInheritEnvironment(boolean inheritEnvironment) { @@ -86,10 +90,11 @@ public class BinderProperties { } public boolean isDefaultCandidate() { - return defaultCandidate; + return this.defaultCandidate; } public void setDefaultCandidate(boolean defaultCandidate) { this.defaultCandidate = defaultCandidate; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindersHealthIndicatorAutoConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindersHealthIndicatorAutoConfiguration.java index 4ee533dfa..d30e6a5d2 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindersHealthIndicatorAutoConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindersHealthIndicatorAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -52,7 +52,8 @@ public class BindersHealthIndicatorAutoConfiguration { @Bean @ConditionalOnMissingBean(name = "bindersHealthIndicator") public CompositeHealthIndicator bindersHealthIndicator() { - return new CompositeHealthIndicator(new OrderedHealthAggregator(), new DefaultHealthIndicatorRegistry()); + return new CompositeHealthIndicator(new OrderedHealthAggregator(), + new DefaultHealthIndicatorRegistry()); } @Bean @@ -67,7 +68,8 @@ public class BindersHealthIndicatorAutoConfiguration { * * @author Ilayaperumal Gopinathan */ - private static class BindersHealthIndicatorListener implements DefaultBinderFactory.Listener { + private static class BindersHealthIndicatorListener + implements DefaultBinderFactory.Listener { private final CompositeHealthIndicator bindersHealthIndicator; @@ -80,13 +82,16 @@ public class BindersHealthIndicatorAutoConfiguration { ConfigurableApplicationContext binderContext) { if (this.bindersHealthIndicator != null) { OrderedHealthAggregator healthAggregator = new OrderedHealthAggregator(); - Map indicators = binderContext.getBeansOfType(HealthIndicator.class); + Map indicators = binderContext + .getBeansOfType(HealthIndicator.class); // if there are no health indicators in the child context, we just mark // the binder's health as unknown // this can happen due to the fact that configuration is inherited - HealthIndicator binderHealthIndicator = indicators.isEmpty() ? new DefaultHealthIndicator() + HealthIndicator binderHealthIndicator = indicators.isEmpty() + ? new DefaultHealthIndicator() : new CompositeHealthIndicator(healthAggregator, indicators); - bindersHealthIndicator.getRegistry().register(binderConfigurationName, binderHealthIndicator); + this.bindersHealthIndicator.getRegistry() + .register(binderConfigurationName, binderHealthIndicator); } } @@ -96,6 +101,9 @@ public class BindersHealthIndicatorAutoConfiguration { protected void doHealthCheck(Health.Builder builder) throws Exception { builder.unknown(); } + } + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingBeansRegistrar.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingBeansRegistrar.java index f5b780e04..43fba6b8f 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingBeansRegistrar.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingBeansRegistrar.java @@ -27,7 +27,6 @@ import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.ClassUtils; /** - * * @author Marius Bogoevici * @author Dave Syer * @author Artem Bilan @@ -42,11 +41,12 @@ public class BindingBeansRegistrar implements ImportBeanDefinitionRegistrar { EnableBinding.class); for (Class type : collectClasses(attrs, metadata.getClassName())) { if (!registry.containsBeanDefinition(type.getName())) { - BindingBeanDefinitionRegistryUtils.registerBindingTargetBeanDefinitions(type, - type.getName(), registry); - BindingBeanDefinitionRegistryUtils.registerBindingTargetsQualifiedBeanDefinitions( - ClassUtils.resolveClassName(metadata.getClassName(), null), type, - registry); + BindingBeanDefinitionRegistryUtils.registerBindingTargetBeanDefinitions( + type, type.getName(), registry); + BindingBeanDefinitionRegistryUtils + .registerBindingTargetsQualifiedBeanDefinitions(ClassUtils + .resolveClassName(metadata.getClassName(), null), type, + registry); } } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingHandlerAdvise.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingHandlerAdvise.java index 432a1179b..a823e8815 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingHandlerAdvise.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingHandlerAdvise.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -32,33 +32,35 @@ import org.springframework.util.CollectionUtils; import org.springframework.validation.Validator; /** - * * @author Oleg Zhurakousky - * * @since 2.1 * */ -public class BindingHandlerAdvise implements ConfigurationPropertiesBindHandlerAdvisor{ +public class BindingHandlerAdvise implements ConfigurationPropertiesBindHandlerAdvisor { private final Map mappings; - + private final Validator[] validator; - BindingHandlerAdvise(Map additionalMappings, @Nullable Validator validator) { + BindingHandlerAdvise( + Map additionalMappings, + @Nullable Validator validator) { this.mappings = new LinkedHashMap<>(); this.mappings.put(ConfigurationPropertyName.of("spring.cloud.stream.bindings"), ConfigurationPropertyName.of("spring.cloud.stream.default")); if (!CollectionUtils.isEmpty(additionalMappings)) { this.mappings.putAll(additionalMappings); } - this.validator = validator != null ? new Validator[] {validator} : new Validator[] {}; + this.validator = validator != null ? new Validator[] { validator } + : new Validator[] {}; } @Override public BindHandler apply(BindHandler bindHandler) { - BindHandler handler = new ValidationBindHandler(validator) { + BindHandler handler = new ValidationBindHandler(this.validator) { @Override - public Bindable onStart(ConfigurationPropertyName name, Bindable target, BindContext context) { + public Bindable onStart(ConfigurationPropertyName name, + Bindable target, BindContext context) { ConfigurationPropertyName defaultName = getDefaultName(name); if (defaultName != null) { BindResult result = context.getBinder().bind(defaultName, target); @@ -73,12 +75,15 @@ public class BindingHandlerAdvise implements ConfigurationPropertiesBindHandlerA } private ConfigurationPropertyName getDefaultName(ConfigurationPropertyName name) { - for (Map.Entry mapping : this.mappings.entrySet()) { + for (Map.Entry mapping : this.mappings + .entrySet()) { ConfigurationPropertyName from = mapping.getKey(); ConfigurationPropertyName to = mapping.getValue(); - if ((from.isAncestorOf(name) && name.getNumberOfElements() > from.getNumberOfElements())) { + if ((from.isAncestorOf(name) + && name.getNumberOfElements() > from.getNumberOfElements())) { ConfigurationPropertyName defaultName = to; - for (int i = from.getNumberOfElements() + 1; i < name.getNumberOfElements(); i++) { + for (int i = from.getNumberOfElements() + 1; i < name + .getNumberOfElements(); i++) { defaultName = defaultName.append(name.getElement(i, Form.UNIFORM)); } return defaultName; @@ -87,7 +92,13 @@ public class BindingHandlerAdvise implements ConfigurationPropertiesBindHandlerA return null; } + /** + * Provides mappings including the default mappings. + */ public interface MappingsProvider { + Map getDefaultMappings(); + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingProperties.java index 9c407d231..da5b34e6a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingProperties.java @@ -29,6 +29,7 @@ import org.springframework.validation.annotation.Validated; /** * Contains the properties of a binding. + * * @author Marius Bogoevici * @author Ilayaperumal Gopinathan * @author Gary Russell @@ -37,8 +38,11 @@ import org.springframework.validation.annotation.Validated; */ @JsonInclude(Include.NON_DEFAULT) @Validated -public class BindingProperties { +public class BindingProperties { + /** + * Default content type for bindings. + */ public static final MimeType DEFAULT_CONTENT_TYPE = MimeTypeUtils.APPLICATION_JSON; private static final String COMMA = ","; @@ -61,27 +65,27 @@ public class BindingProperties { // Properties for both input and output bindings /** - * Specifies content-type that will be used by this binding in the event - * it is not specified in Message headers. Default: 'application/json'. + * Specifies content-type that will be used by this binding in the event it is not + * specified in Message headers. Default: 'application/json'. */ private String contentType = DEFAULT_CONTENT_TYPE.toString(); /** - * The name of the binder to use for this binding in the event multiple binders available (e.g., 'rabbit'); + * The name of the binder to use for this binding in the event multiple binders + * available (e.g., 'rabbit'). */ private String binder; /** - * Additional consumer specific properties (see {@link ConsumerProperties}) + * Additional consumer specific properties (see {@link ConsumerProperties}). */ private ConsumerProperties consumer; /** - * Additional producer specific properties (see {@link ProducerProperties}) + * Additional producer specific properties (see {@link ProducerProperties}). */ private ProducerProperties producer; - public String getDestination() { return this.destination; } @@ -91,7 +95,7 @@ public class BindingProperties { } public String getGroup() { - return group; + return this.group; } public void setGroup(String group) { @@ -107,7 +111,7 @@ public class BindingProperties { } public String getBinder() { - return binder; + return this.binder; } public void setBinder(String binder) { @@ -115,7 +119,7 @@ public class BindingProperties { } public ConsumerProperties getConsumer() { - return consumer; + return this.consumer; } public void setConsumer(ConsumerProperties consumer) { @@ -123,7 +127,7 @@ public class BindingProperties { } public ProducerProperties getProducer() { - return producer; + return this.producer; } public void setProducer(ProducerProperties producer) { @@ -132,7 +136,7 @@ public class BindingProperties { @AssertTrue(message = "A binding must not set both producer and consumer properties.") public boolean onlyOneOfProducerOrConsumerSet() { - return consumer == null || producer == null; + return this.consumer == null || this.producer == null; } @Override @@ -153,4 +157,5 @@ public class BindingProperties { sb.deleteCharAt(sb.lastIndexOf(COMMA)); return "BindingProperties{" + sb.toString() + "}"; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java index 39bf9037a..549818f05 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java @@ -65,7 +65,6 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.validation.Validator; - /** * Configuration class that provides necessary beans for {@link MessageChannel} binding. * @@ -80,20 +79,91 @@ import org.springframework.validation.Validator; * @author Soby Chacko */ @Configuration -@EnableConfigurationProperties({ BindingServiceProperties.class, SpringIntegrationProperties.class, StreamFunctionProperties.class }) -@Import({ DestinationPublishingMetricsAutoConfiguration.class, SpelExpressionConverterConfiguration.class }) +@EnableConfigurationProperties({ BindingServiceProperties.class, + SpringIntegrationProperties.class, StreamFunctionProperties.class }) +@Import({ DestinationPublishingMetricsAutoConfiguration.class, + SpelExpressionConverterConfiguration.class }) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) @ConditionalOnBean(value = BinderTypeRegistry.class, search = SearchStrategy.CURRENT) public class BindingServiceConfiguration { - public static final String STREAM_LISTENER_ANNOTATION_BEAN_POST_PROCESSOR_NAME = - "streamListenerAnnotationBeanPostProcessor"; + // @checkstyle:off + /** + * Name of the Spring Cloud Stream stream listener annotation bean post processor. + */ + public static final String STREAM_LISTENER_ANNOTATION_BEAN_POST_PROCESSOR_NAME = "streamListenerAnnotationBeanPostProcessor"; + + // @checkstyle:on @Autowired(required = false) private Collection binderFactoryListeners; + private static Map getBinderConfigurations( + BinderTypeRegistry binderTypeRegistry, + BindingServiceProperties bindingServiceProperties) { + + Map binderConfigurations = new HashMap<>(); + Map declaredBinders = bindingServiceProperties + .getBinders(); + boolean defaultCandidatesExist = false; + Iterator> binderPropertiesIterator = declaredBinders + .entrySet().iterator(); + while (!defaultCandidatesExist && binderPropertiesIterator.hasNext()) { + defaultCandidatesExist = binderPropertiesIterator.next().getValue() + .isDefaultCandidate(); + } + List existingBinderConfigurations = new ArrayList<>(); + for (Map.Entry binderEntry : declaredBinders + .entrySet()) { + BinderProperties binderProperties = binderEntry.getValue(); + if (binderTypeRegistry.get(binderEntry.getKey()) != null) { + binderConfigurations.put(binderEntry.getKey(), + new BinderConfiguration(binderEntry.getKey(), + binderProperties.getEnvironment(), + binderProperties.isInheritEnvironment(), + binderProperties.isDefaultCandidate())); + existingBinderConfigurations.add(binderEntry.getKey()); + } + else { + Assert.hasText(binderProperties.getType(), + "No 'type' property present for custom binder " + + binderEntry.getKey()); + binderConfigurations.put(binderEntry.getKey(), + new BinderConfiguration(binderProperties.getType(), + binderProperties.getEnvironment(), + binderProperties.isInheritEnvironment(), + binderProperties.isDefaultCandidate())); + existingBinderConfigurations.add(binderEntry.getKey()); + } + } + for (Map.Entry configurationEntry : binderConfigurations + .entrySet()) { + if (configurationEntry.getValue().isDefaultCandidate()) { + defaultCandidatesExist = true; + } + } + if (!defaultCandidatesExist) { + for (Map.Entry binderEntry : binderTypeRegistry.getAll() + .entrySet()) { + if (!existingBinderConfigurations.contains(binderEntry.getKey())) { + binderConfigurations.put(binderEntry.getKey(), + new BinderConfiguration(binderEntry.getKey(), new HashMap<>(), + true, true)); + } + } + } + return binderConfigurations; + } + + @Bean(name = STREAM_LISTENER_ANNOTATION_BEAN_POST_PROCESSOR_NAME) + @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) + public static StreamListenerAnnotationBeanPostProcessor streamListenerAnnotationBeanPostProcessor() { + return new StreamListenerAnnotationBeanPostProcessor(); + } + @Bean - public BindingHandlerAdvise BindingHandlerAdvise(@Nullable MappingsProvider[] providers, @Nullable Validator validator) { + public BindingHandlerAdvise BindingHandlerAdvise( + @Nullable MappingsProvider[] providers, @Nullable Validator validator) { Map additionalMappings = new HashMap<>(); if (!ObjectUtils.isEmpty(providers)) { for (int i = 0; i < providers.length; i++) { @@ -110,75 +180,26 @@ public class BindingServiceConfiguration { BindingServiceProperties bindingServiceProperties) { DefaultBinderFactory binderFactory = new DefaultBinderFactory( - getBinderConfigurations(binderTypeRegistry, bindingServiceProperties), binderTypeRegistry); + getBinderConfigurations(binderTypeRegistry, bindingServiceProperties), + binderTypeRegistry); binderFactory.setDefaultBinder(bindingServiceProperties.getDefaultBinder()); - binderFactory.setListeners(binderFactoryListeners); + binderFactory.setListeners(this.binderFactoryListeners); return binderFactory; } - private static Map getBinderConfigurations(BinderTypeRegistry binderTypeRegistry, - BindingServiceProperties bindingServiceProperties) { - - Map binderConfigurations = new HashMap<>(); - Map declaredBinders = bindingServiceProperties.getBinders(); - boolean defaultCandidatesExist = false; - Iterator> binderPropertiesIterator = declaredBinders.entrySet().iterator(); - while (!defaultCandidatesExist && binderPropertiesIterator.hasNext()) { - defaultCandidatesExist = binderPropertiesIterator.next().getValue().isDefaultCandidate(); - } - List existingBinderConfigurations = new ArrayList<>(); - for (Map.Entry binderEntry : declaredBinders.entrySet()) { - BinderProperties binderProperties = binderEntry.getValue(); - if (binderTypeRegistry.get(binderEntry.getKey()) != null) { - binderConfigurations.put(binderEntry.getKey(), - new BinderConfiguration(binderEntry.getKey(), - binderProperties.getEnvironment(), binderProperties.isInheritEnvironment(), - binderProperties.isDefaultCandidate())); - existingBinderConfigurations.add(binderEntry.getKey()); - } - else { - Assert.hasText(binderProperties.getType(), - "No 'type' property present for custom binder " + binderEntry.getKey()); - binderConfigurations.put(binderEntry.getKey(), - new BinderConfiguration(binderProperties.getType(), binderProperties.getEnvironment(), - binderProperties.isInheritEnvironment(), binderProperties.isDefaultCandidate())); - existingBinderConfigurations.add(binderEntry.getKey()); - } - } - for (Map.Entry configurationEntry : binderConfigurations.entrySet()) { - if (configurationEntry.getValue().isDefaultCandidate()) { - defaultCandidatesExist = true; - } - } - if (!defaultCandidatesExist) { - for (Map.Entry binderEntry : binderTypeRegistry.getAll().entrySet()) { - if (!existingBinderConfigurations.contains(binderEntry.getKey())) { - binderConfigurations.put(binderEntry.getKey(), new BinderConfiguration(binderEntry.getKey(), - new HashMap<>(), true, true)); - } - } - } - return binderConfigurations; - } - @Bean public MessageChannelStreamListenerResultAdapter messageChannelStreamListenerResultAdapter() { return new MessageChannelStreamListenerResultAdapter(); } - @Bean(name = STREAM_LISTENER_ANNOTATION_BEAN_POST_PROCESSOR_NAME) - @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) - public static StreamListenerAnnotationBeanPostProcessor streamListenerAnnotationBeanPostProcessor() { - return new StreamListenerAnnotationBeanPostProcessor(); - } - @Bean // This conditional is intentionally not in an autoconfig (usually a bad idea) because // it is used to detect a BindingService in the parent context (which we know // already exists). @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) - public BindingService bindingService(BindingServiceProperties bindingServiceProperties, - BinderFactory binderFactory, TaskScheduler taskScheduler) { + public BindingService bindingService( + BindingServiceProperties bindingServiceProperties, + BinderFactory binderFactory, TaskScheduler taskScheduler) { return new BindingService(bindingServiceProperties, binderFactory, taskScheduler); } @@ -193,7 +214,8 @@ public class BindingServiceConfiguration { @Bean @DependsOn("bindingService") - public InputBindingLifecycle inputBindingLifecycle(BindingService bindingService, Map bindables) { + public InputBindingLifecycle inputBindingLifecycle(BindingService bindingService, + Map bindables) { return new InputBindingLifecycle(bindingService, bindables); } @@ -205,12 +227,14 @@ public class BindingServiceConfiguration { @SuppressWarnings("rawtypes") @Bean - public BinderAwareChannelResolver binderAwareChannelResolver(BindingService bindingService, + public BinderAwareChannelResolver binderAwareChannelResolver( + BindingService bindingService, AbstractBindingTargetFactory bindingTargetFactory, DynamicDestinationsBindable dynamicDestinationsBindable, @Nullable BinderAwareChannelResolver.NewDestinationBindingCallback callback) { - return new BinderAwareChannelResolver(bindingService, bindingTargetFactory, dynamicDestinationsBindable, callback); + return new BinderAwareChannelResolver(bindingService, bindingTargetFactory, + dynamicDestinationsBindable, callback); } @Bean @@ -225,18 +249,23 @@ public class BindingServiceConfiguration { @Autowired(required = false) AbstractMappingMessageRouter[] routers, @Autowired(required = false) DestinationResolver channelResolver) { - return new org.springframework.cloud.stream.binding.BinderAwareRouterBeanPostProcessor(routers, channelResolver); + return new org.springframework.cloud.stream.binding.BinderAwareRouterBeanPostProcessor( + routers, channelResolver); } @Bean - public ApplicationListener appListener(SpringIntegrationProperties springIntegrationProperties) { + public ApplicationListener appListener( + SpringIntegrationProperties springIntegrationProperties) { return new ApplicationListener() { @Override public void onApplicationEvent(ContextRefreshedEvent event) { - event.getApplicationContext().getBeansOfType(AbstractReplyProducingMessageHandler.class).values() - .forEach(mh -> mh.addNotPropagatedHeaders(springIntegrationProperties - .getMessageHandlerNotPropagatedHeaders())); + event.getApplicationContext() + .getBeansOfType(AbstractReplyProducingMessageHandler.class) + .values() + .forEach(mh -> mh + .addNotPropagatedHeaders(springIntegrationProperties + .getMessageHandlerNotPropagatedHeaders())); } }; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceProperties.java index 4294cffd1..231b79a6c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceProperties.java @@ -52,53 +52,56 @@ import org.springframework.util.Assert; */ @ConfigurationProperties("spring.cloud.stream") @JsonInclude(Include.NON_DEFAULT) -public class BindingServiceProperties implements ApplicationContextAware, InitializingBean { +public class BindingServiceProperties + implements ApplicationContextAware, InitializingBean { private static final int DEFAULT_BINDING_RETRY_INTERVAL = 30; /** - * The instance id of the application: a number from 0 to instanceCount-1. - * Used for partitioning and with Kafka. - * NOTE: Could also be managed per individual binding - * "spring.cloud.stream.bindings.foo.consumer.instance-index" where 'foo' is - * the name of the binding. + * The instance id of the application: a number from 0 to instanceCount-1. Used for + * partitioning and with Kafka. NOTE: Could also be managed per individual binding + * "spring.cloud.stream.bindings.foo.consumer.instance-index" where 'foo' is the name + * of the binding. */ @Value("${INSTANCE_INDEX:${CF_INSTANCE_INDEX:0}}") private int instanceIndex; /** - * The number of deployed instances of an application. - * Default: 1. - * NOTE: Could also be managed per individual binding - * "spring.cloud.stream.bindings.foo.consumer.instance-count" where 'foo' is - * the name of the binding. + * The number of deployed instances of an application. Default: 1. NOTE: Could also be + * managed per individual binding + * "spring.cloud.stream.bindings.foo.consumer.instance-count" where 'foo' is the name + * of the binding. */ private int instanceCount = 1; /** - * Additional binding properties (see {@link BinderProperties}) per binding name (e.g., 'input`). + * Additional binding properties (see {@link BinderProperties}) per binding name + * (e.g., 'input`). * - * For example; This sets the content-type for the 'input' binding of a Sink application: - * 'spring.cloud.stream.bindings.input.contentType=text/plain' + * For example; This sets the content-type for the 'input' binding of a Sink + * application: 'spring.cloud.stream.bindings.input.contentType=text/plain' */ private Map bindings = new TreeMap<>( String.CASE_INSENSITIVE_ORDER); /** - * Additional per-binder properties (see {@link BinderProperties}) if more then one binder of the same type is used - * (i.e., connect to multiple instances of RabbitMq). Here you can specify multiple - * binder configurations, each with different environment settings. For example; - * spring.cloud.stream.binders.rabbit1.environment. . . , spring.cloud.stream.binders.rabbit2.environment. . . + * Additional per-binder properties (see {@link BinderProperties}) if more then one + * binder of the same type is used (i.e., connect to multiple instances of RabbitMq). + * Here you can specify multiple binder configurations, each with different + * environment settings. For example; spring.cloud.stream.binders.rabbit1.environment. + * . . , spring.cloud.stream.binders.rabbit2.environment. . . */ private Map binders = new HashMap<>(); /** - * The name of the binder to use by all bindings in the event multiple binders available (e.g., 'rabbit'); + * The name of the binder to use by all bindings in the event multiple binders + * available (e.g., 'rabbit'). */ private String defaultBinder; /** - * A list of destinations that can be bound dynamically. If set, only listed destinations can be bound. + * A list of destinations that can be bound dynamically. If set, only listed + * destinations can be bound. */ private String[] dynamicDestinations = new String[0]; @@ -163,9 +166,11 @@ public class BindingServiceProperties implements ApplicationContextAware, Initia public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = (ConfigurableApplicationContext) applicationContext; - GenericConversionService cs = (GenericConversionService) IntegrationUtils.getConversionService(this.applicationContext.getBeanFactory()); + GenericConversionService cs = (GenericConversionService) IntegrationUtils + .getConversionService(this.applicationContext.getBeanFactory()); if (this.applicationContext.containsBean("spelConverter")) { - Converter converter = (Converter) this.applicationContext.getBean("spelConverter"); + Converter converter = (Converter) this.applicationContext + .getBean("spelConverter"); cs.addConverter(converter); } } @@ -260,7 +265,8 @@ public class BindingServiceProperties implements ApplicationContextAware, Initia this.bindingRetryInterval = bindingRetryInterval; } - public void updateProducerProperties(String bindingName, ProducerProperties producerProperties) { + public void updateProducerProperties(String bindingName, + ProducerProperties producerProperties) { if (this.bindings.containsKey(bindingName)) { this.bindings.get(bindingName).setProducer(producerProperties); } @@ -270,17 +276,24 @@ public class BindingServiceProperties implements ApplicationContextAware, Initia * The "necessary" implies the scenario where only defaults are defined. */ private void bindIfNecessary(String bindingName) { - if (!bindings.containsKey(bindingName)) { + if (!this.bindings.containsKey(bindingName)) { this.bindToDefault(bindingName); } } private void bindToDefault(String binding) { BindingProperties bindingPropertiesTarget = new BindingProperties(); - Binder binder = new Binder(ConfigurationPropertySources.get(applicationContext.getEnvironment()), - new PropertySourcesPlaceholdersResolver(applicationContext.getEnvironment()), - IntegrationUtils.getConversionService(applicationContext.getBeanFactory()), null); - binder.bind("spring.cloud.stream.default", Bindable.ofInstance(bindingPropertiesTarget)); + Binder binder = new Binder( + ConfigurationPropertySources + .get(this.applicationContext.getEnvironment()), + new PropertySourcesPlaceholdersResolver( + this.applicationContext.getEnvironment()), + IntegrationUtils.getConversionService( + this.applicationContext.getBeanFactory()), + null); + binder.bind("spring.cloud.stream.default", + Bindable.ofInstance(bindingPropertiesTarget)); this.bindings.put(binding, bindingPropertiesTarget); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingsEndpointAutoConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingsEndpointAutoConfiguration.java index ccb5f1b2b..751313e1c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingsEndpointAutoConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingsEndpointAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -31,17 +31,19 @@ import org.springframework.context.annotation.Configuration; /** * @author Oleg Zhurakousky - * * @since 2.0 */ @Configuration -@ConditionalOnClass(name = {"org.springframework.boot.actuate.endpoint.annotation.Endpoint"}) +@ConditionalOnClass(name = { + "org.springframework.boot.actuate.endpoint.annotation.Endpoint" }) @ConditionalOnBean(BindingService.class) @AutoConfigureAfter(EndpointAutoConfiguration.class) public class BindingsEndpointAutoConfiguration { @Bean - public BindingsEndpoint bindingsEndpoint(List inputBindings, List outputBindings) { + public BindingsEndpoint bindingsEndpoint(List inputBindings, + List outputBindings) { return new BindingsEndpoint(inputBindings, outputBindings); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java index 17a4af0c0..2ce332f5a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java @@ -47,4 +47,5 @@ public class ChannelBindingAutoConfiguration { public PollerMetadata defaultPoller() { return this.poller.getPollerMetadata(); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelsEndpointAutoConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelsEndpointAutoConfiguration.java index 48b2014e9..ba21764d0 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelsEndpointAutoConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelsEndpointAutoConfiguration.java @@ -47,4 +47,5 @@ public class ChannelsEndpointAutoConfiguration { public ChannelsEndpoint channelsEndpoint(BindingServiceProperties properties) { return new ChannelsEndpoint(this.adapters, properties); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ContentTypeConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ContentTypeConfiguration.java index ff5ba0255..37bcd0316 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ContentTypeConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ContentTypeConfiguration.java @@ -52,7 +52,8 @@ class ContentTypeConfiguration { public ConfigurableCompositeMessageConverter configurableCompositeMessageConverter( CompositeMessageConverterFactory factory) { - return new ConfigurableCompositeMessageConverter(factory.getMessageConverterForAllRegistered().getConverters()); + return new ConfigurableCompositeMessageConverter( + factory.getMessageConverterForAllRegistered().getConverters()); } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/DefaultPollerProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/DefaultPollerProperties.java index 608992aa8..57e4277d7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/DefaultPollerProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/DefaultPollerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ListenerContainerCustomizer.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ListenerContainerCustomizer.java index 20e469271..f74bc4c8f 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ListenerContainerCustomizer.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ListenerContainerCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -17,16 +17,14 @@ package org.springframework.cloud.stream.config; /** - * If a single bean of this type is in the application context, listener - * containers created by the binder can be further customized after all - * the properties are set. For example, to configure less-common - * properties. + * If a single bean of this type is in the application context, listener containers + * created by the binder can be further customized after all the properties are set. For + * example, to configure less-common properties. * + * @param container type * @author Gary Russell * @author Oleg Zhurakousky - * * @since 2.1 - * */ @FunctionalInterface public interface ListenerContainerCustomizer { diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartMessageMethodArgumentResolver.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartMessageMethodArgumentResolver.java index be51a4b02..31b036793 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartMessageMethodArgumentResolver.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartMessageMethodArgumentResolver.java @@ -32,16 +32,14 @@ import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** - * * @author Oleg Zhurakousky - * * @deprecated will be removed once https://jira.spring.io/browse/SPR-17503 is addressed */ @Deprecated class SmartMessageMethodArgumentResolver extends MessageMethodArgumentResolver { - + private final MessageConverter messageConverter; - + SmartMessageMethodArgumentResolver() { this(null); } @@ -56,14 +54,16 @@ class SmartMessageMethodArgumentResolver extends MessageMethodArgumentResolver { } @Override - public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { + public Object resolveArgument(MethodParameter parameter, Message message) + throws Exception { Class targetMessageType = parameter.getParameterType(); Class targetPayloadType = getPayloadType(parameter); if (!targetMessageType.isAssignableFrom(message.getClass())) { - throw new MethodArgumentTypeMismatchException(message, parameter, "Actual message type '" + - ClassUtils.getDescriptiveType(message) + "' does not match expected type '" + - ClassUtils.getQualifiedName(targetMessageType) + "'"); + throw new MethodArgumentTypeMismatchException(message, parameter, + "Actual message type '" + ClassUtils.getDescriptiveType(message) + + "' does not match expected type '" + + ClassUtils.getQualifiedName(targetMessageType) + "'"); } Class payloadClass = message.getPayload().getClass(); @@ -73,21 +73,25 @@ class SmartMessageMethodArgumentResolver extends MessageMethodArgumentResolver { } Object payload = message.getPayload(); if (isEmptyPayload(payload)) { - throw new MessageConversionException(message, "Cannot convert from actual payload type '" + - ClassUtils.getDescriptiveType(payload) + "' to expected payload type '" + - ClassUtils.getQualifiedName(targetPayloadType) + "' when payload is empty"); + throw new MessageConversionException(message, + "Cannot convert from actual payload type '" + + ClassUtils.getDescriptiveType(payload) + + "' to expected payload type '" + + ClassUtils.getQualifiedName(targetPayloadType) + + "' when payload is empty"); } payload = convertPayload(message, parameter, targetPayloadType); return MessageBuilder.createMessage(payload, message.getHeaders()); } - + private Class getPayloadType(MethodParameter parameter) { Type genericParamType = parameter.getGenericParameterType(); - ResolvableType resolvableType = ResolvableType.forType(genericParamType).as(Message.class); + ResolvableType resolvableType = ResolvableType.forType(genericParamType) + .as(Message.class); return resolvableType.getGeneric().toClass(); } - + protected boolean isEmptyPayload(@Nullable Object payload) { if (payload == null) { return true; @@ -102,8 +106,9 @@ class SmartMessageMethodArgumentResolver extends MessageMethodArgumentResolver { return false; } } - - private Object convertPayload(Message message, MethodParameter parameter, Class targetPayloadType) { + + private Object convertPayload(Message message, MethodParameter parameter, + Class targetPayloadType) { Object result = null; if (this.messageConverter instanceof SmartMessageConverter) { SmartMessageConverter smartConverter = (SmartMessageConverter) this.messageConverter; @@ -114,10 +119,13 @@ class SmartMessageMethodArgumentResolver extends MessageMethodArgumentResolver { } if (result == null) { - throw new MessageConversionException(message, "No converter found from actual payload type '" + - ClassUtils.getDescriptiveType(message.getPayload()) + "' to expected payload type '" + - ClassUtils.getQualifiedName(targetPayloadType) + "'"); + throw new MessageConversionException(message, + "No converter found from actual payload type '" + + ClassUtils.getDescriptiveType(message.getPayload()) + + "' to expected payload type '" + + ClassUtils.getQualifiedName(targetPayloadType) + "'"); } return result; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartPayloadArgumentResolver.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartPayloadArgumentResolver.java index 47739eba7..b83791653 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartPayloadArgumentResolver.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SmartPayloadArgumentResolver.java @@ -36,14 +36,12 @@ import org.springframework.validation.ObjectError; import org.springframework.validation.Validator; /** - * * @author Oleg Zhurakousky - * * @deprecated will be removed once https://jira.spring.io/browse/SPR-17503 is addressed */ @Deprecated class SmartPayloadArgumentResolver extends PayloadArgumentResolver { - + private final MessageConverter messageConverter; SmartPayloadArgumentResolver(MessageConverter messageConverter) { @@ -61,30 +59,35 @@ class SmartPayloadArgumentResolver extends PayloadArgumentResolver { super(messageConverter, validator, useDefaultResolution); this.messageConverter = messageConverter; } - + @Override public boolean supportsParameter(MethodParameter parameter) { - return (!Message.class.isAssignableFrom(parameter.getParameterType()) - && !MessageHeaders.class.isAssignableFrom(parameter.getParameterType()) - && !parameter.hasParameterAnnotation(Header.class) + return (!Message.class.isAssignableFrom(parameter.getParameterType()) + && !MessageHeaders.class.isAssignableFrom(parameter.getParameterType()) + && !parameter.hasParameterAnnotation(Header.class) && !parameter.hasParameterAnnotation(Headers.class)); } - + @Override @Nullable - public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { + public Object resolveArgument(MethodParameter parameter, Message message) + throws Exception { Payload ann = parameter.getParameterAnnotation(Payload.class); if (ann != null && StringUtils.hasText(ann.expression())) { - throw new IllegalStateException("@Payload SpEL expressions not supported by this resolver"); + throw new IllegalStateException( + "@Payload SpEL expressions not supported by this resolver"); } Object payload = message.getPayload(); if (isEmptyPayload(payload)) { if (ann == null || ann.required()) { String paramName = getParameterName(parameter); - BindingResult bindingResult = new BeanPropertyBindingResult(payload, paramName); - bindingResult.addError(new ObjectError(paramName, "Payload value must not be empty")); - throw new MethodArgumentNotValidException(message, parameter, bindingResult); + BindingResult bindingResult = new BeanPropertyBindingResult(payload, + paramName); + bindingResult.addError( + new ObjectError(paramName, "Payload value must not be empty")); + throw new MethodArgumentNotValidException(message, parameter, + bindingResult); } else { return null; @@ -106,16 +109,18 @@ class SmartPayloadArgumentResolver extends PayloadArgumentResolver { payload = this.messageConverter.fromMessage(message, targetClass); } if (payload == null) { - throw new MessageConversionException(message, "Cannot convert from [" + - payloadClass.getName() + "] to [" + targetClass.getName() + "] for " + message); + throw new MessageConversionException(message, + "Cannot convert from [" + payloadClass.getName() + "] to [" + + targetClass.getName() + "] for " + message); } validate(message, parameter, payload); return payload; } } - + private String getParameterName(MethodParameter param) { String paramName = param.getParameterName(); return (paramName != null ? paramName : "Arg " + param.getParameterIndex()); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java index b3ffcd45b..d6a58e15a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java @@ -49,9 +49,9 @@ import org.springframework.tuple.spel.TuplePropertyAccessor; public class SpelExpressionConverterConfiguration { /** - * Provide a {@link SpelPropertyAccessorRegistrar} supplied - * with the {@link JsonPropertyAccessor} and {@link TuplePropertyAccessor}. - * This bean is used to customize an + * Provide a {@link SpelPropertyAccessorRegistrar} supplied with the + * {@link JsonPropertyAccessor} and {@link TuplePropertyAccessor}. This bean is used + * to customize an * {@link org.springframework.integration.config.IntegrationEvaluationContextFactoryBean}. * for additional {@link org.springframework.expression.PropertyAccessor}s. * @return the SpelPropertyAccessorRegistrar bean @@ -60,8 +60,12 @@ public class SpelExpressionConverterConfiguration { @Bean public static SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() { return new SpelPropertyAccessorRegistrar() - .add(Introspector.decapitalize(JsonPropertyAccessor.class.getSimpleName()), new JsonPropertyAccessor()) - .add(Introspector.decapitalize(TuplePropertyAccessor.class.getSimpleName()), new TuplePropertyAccessor()); + .add(Introspector + .decapitalize(JsonPropertyAccessor.class.getSimpleName()), + new JsonPropertyAccessor()) + .add(Introspector + .decapitalize(TuplePropertyAccessor.class.getSimpleName()), + new TuplePropertyAccessor()); } @Bean @@ -88,16 +92,19 @@ public class SpelExpressionConverterConfiguration { @Override public Expression convert(String source) { try { - Expression expression = parser.parseExpression(source); + Expression expression = this.parser.parseExpression(source); if (expression instanceof SpelExpression) { - ((SpelExpression) expression).setEvaluationContext(evaluationContext); + ((SpelExpression) expression) + .setEvaluationContext(this.evaluationContext); } return expression; } catch (ParseException e) { - throw new IllegalArgumentException( - String.format("Could not convert '%s' into a SpEL expression", source), e); + throw new IllegalArgumentException(String.format( + "Could not convert '%s' into a SpEL expression", source), e); } } + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpringIntegrationProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpringIntegrationProperties.java index 1bf8e4c8b..5e94fdc74 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpringIntegrationProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpringIntegrationProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -23,7 +23,6 @@ import org.springframework.messaging.MessageHeaders; * Contains properties for Spring Integration settings. * * @author Marius Bogoevici - * * @since 1.2.3 */ @ConfigurationProperties("spring.cloud.stream.integration") @@ -32,13 +31,16 @@ public class SpringIntegrationProperties { /** * Message header names that will NOT be copied from the inbound message. */ - private String[] messageHandlerNotPropagatedHeaders = new String[] { MessageHeaders.CONTENT_TYPE }; + private String[] messageHandlerNotPropagatedHeaders = new String[] { + MessageHeaders.CONTENT_TYPE }; public String[] getMessageHandlerNotPropagatedHeaders() { return this.messageHandlerNotPropagatedHeaders; } - public void setMessageHandlerNotPropagatedHeaders(String[] messageHandlerNotPropagatedHeaders) { + public void setMessageHandlerNotPropagatedHeaders( + String[] messageHandlerNotPropagatedHeaders) { this.messageHandlerNotPropagatedHeaders = messageHandlerNotPropagatedHeaders; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ApplicationJsonMessageMarshallingConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ApplicationJsonMessageMarshallingConverter.java index dd9cdc765..05ea13509 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ApplicationJsonMessageMarshallingConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ApplicationJsonMessageMarshallingConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -35,14 +35,12 @@ import org.springframework.messaging.converter.MessageConversionException; /** * Variation of {@link MappingJackson2MessageConverter} to support marshalling and - * unmarshalling of Messages's payload from 'String' or 'byte[]' to an instance of a 'targetClass' - * and and back to 'byte[]' - * + * unmarshalling of Messages's payload from 'String' or 'byte[]' to an instance of a + * 'targetClass' and and back to 'byte[]'. * * @author Oleg Zhurakousky * @author Gary Russell * @since 2.0 - * */ class ApplicationJsonMessageMarshallingConverter extends MappingJackson2MessageConverter { @@ -55,12 +53,13 @@ class ApplicationJsonMessageMarshallingConverter extends MappingJackson2MessageC } @Override - protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { + protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, + @Nullable Object conversionHint) { if (payload instanceof byte[]) { return payload; } else if (payload instanceof String) { - return ((String)payload).getBytes(StandardCharsets.UTF_8); + return ((String) payload).getBytes(StandardCharsets.UTF_8); } else { return super.convertToInternal(payload, headers, conversionHint); @@ -68,30 +67,39 @@ class ApplicationJsonMessageMarshallingConverter extends MappingJackson2MessageC } @Override - protected Object convertFromInternal(Message message, Class targetClass, @Nullable Object conversionHint) { + protected Object convertFromInternal(Message message, Class targetClass, + @Nullable Object conversionHint) { Object result = null; if (conversionHint instanceof MethodParameter) { - Class conversionHintType = ((MethodParameter)conversionHint).getParameterType(); + Class conversionHintType = ((MethodParameter) conversionHint) + .getParameterType(); if (Message.class.isAssignableFrom(conversionHintType)) { /* - * Ensures that super won't attempt to create Message as a result of conversion - * and stays at payload conversion only. - * The Message will eventually be created in MessageMethodArgumentResolver.resolveArgument(..) + * Ensures that super won't attempt to create Message as a result of + * conversion and stays at payload conversion only. The Message will + * eventually be created in + * MessageMethodArgumentResolver.resolveArgument(..) */ conversionHint = null; } - else if (((MethodParameter)conversionHint).getGenericParameterType() instanceof ParameterizedType) { - ParameterizedTypeReference forType = ParameterizedTypeReference.forType(((MethodParameter)conversionHint).getGenericParameterType()); + else if (((MethodParameter) conversionHint) + .getGenericParameterType() instanceof ParameterizedType) { + ParameterizedTypeReference forType = ParameterizedTypeReference + .forType(((MethodParameter) conversionHint) + .getGenericParameterType()); result = convertParameterizedType(message, targetClass, forType); } } else if (conversionHint instanceof ParameterizedTypeReference) { - result = convertParameterizedType(message, targetClass, (ParameterizedTypeReference)conversionHint); + result = convertParameterizedType(message, targetClass, + (ParameterizedTypeReference) conversionHint); } if (result == null) { - if (message.getPayload() instanceof byte[] && targetClass.isAssignableFrom(String.class)) { - result = new String((byte[])message.getPayload(), StandardCharsets.UTF_8); + if (message.getPayload() instanceof byte[] + && targetClass.isAssignableFrom(String.class)) { + result = new String((byte[]) message.getPayload(), + StandardCharsets.UTF_8); } else { result = super.convertFromInternal(message, targetClass, conversionHint); @@ -101,13 +109,15 @@ class ApplicationJsonMessageMarshallingConverter extends MappingJackson2MessageC return result; } - private Object convertParameterizedType(Message message, Class targetClass, ParameterizedTypeReference conversionHint) { + private Object convertParameterizedType(Message message, Class targetClass, + ParameterizedTypeReference conversionHint) { ObjectMapper objectMapper = this.getObjectMapper(); Object payload = message.getPayload(); try { JavaType type = this.typeCache.get(conversionHint); if (type == null) { - type = objectMapper.getTypeFactory().constructType((conversionHint).getType()); + type = objectMapper.getTypeFactory() + .constructType((conversionHint).getType()); this.typeCache.put(conversionHint, type); } if (payload instanceof byte[]) { @@ -124,4 +134,5 @@ class ApplicationJsonMessageMarshallingConverter extends MappingJackson2MessageC throw new MessageConversionException("Cannot parse payload ", e); } } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CompositeMessageConverterFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CompositeMessageConverterFactory.java index 738943a1e..0a75cbc29 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CompositeMessageConverterFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CompositeMessageConverterFactory.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,7 +35,8 @@ import org.springframework.util.MimeType; /** * A factory for creating an instance of {@link CompositeMessageConverter} for a given - * target MIME type + * target MIME type. + * * @author David Turanski * @author Ilayaperumal Gopinathan * @author Marius Bogoevici @@ -57,8 +57,10 @@ public class CompositeMessageConverterFactory { /** * @param customConverters a list of {@link AbstractMessageConverter} + * @param objectMapper object mapper for for serialization / deserialization */ - public CompositeMessageConverterFactory(List customConverters, + public CompositeMessageConverterFactory( + List customConverters, ObjectMapper objectMapper) { this.objectMapper = objectMapper; if (!CollectionUtils.isEmpty(customConverters)) { @@ -71,14 +73,15 @@ public class CompositeMessageConverterFactory { DefaultContentTypeResolver resolver = new DefaultContentTypeResolver(); resolver.setDefaultMimeType(BindingProperties.DEFAULT_CONTENT_TYPE); - this.converters.stream() - .filter(mc -> mc instanceof AbstractMessageConverter) - .forEach(mc -> ((AbstractMessageConverter)mc).setContentTypeResolver(resolver)); + this.converters.stream().filter(mc -> mc instanceof AbstractMessageConverter) + .forEach(mc -> ((AbstractMessageConverter) mc) + .setContentTypeResolver(resolver)); } @SuppressWarnings("deprecation") private void initDefaultConverters() { - ApplicationJsonMessageMarshallingConverter applicationJsonConverter = new ApplicationJsonMessageMarshallingConverter(this.objectMapper); + ApplicationJsonMessageMarshallingConverter applicationJsonConverter = new ApplicationJsonMessageMarshallingConverter( + this.objectMapper); applicationJsonConverter.setStrictContentTypeMatch(true); this.converters.add(applicationJsonConverter); this.converters.add(new TupleJsonMessageConverter(this.objectMapper)); @@ -95,7 +98,7 @@ public class CompositeMessageConverterFactory { // Deprecated converters this.converters.add(new JavaSerializationMessageConverter()); - this.converters.add(new KryoMessageConverter(null,true)); + this.converters.add(new KryoMessageConverter(null, true)); this.converters.add(new JsonUnmarshallingConverter(this.objectMapper)); } @@ -108,7 +111,8 @@ public class CompositeMessageConverterFactory { List converters = new ArrayList<>(); for (MessageConverter converter : this.converters) { if (converter instanceof AbstractMessageConverter) { - for (MimeType type : ((AbstractMessageConverter) converter).getSupportedMimeTypes()) { + for (MimeType type : ((AbstractMessageConverter) converter) + .getSupportedMimeTypes()) { if (type.includes(mimeType)) { converters.add(converter); } @@ -116,14 +120,16 @@ public class CompositeMessageConverterFactory { } else { if (this.log.isDebugEnabled()) { - this.log.debug("Ommitted " + converter + " of type " + converter.getClass().toString() + - " for '" + mimeType.toString() + "' as it is not an AbstractMessageConverter"); + this.log.debug("Ommitted " + converter + " of type " + + converter.getClass().toString() + " for '" + + mimeType.toString() + + "' as it is not an AbstractMessageConverter"); } } } if (CollectionUtils.isEmpty(converters)) { - throw new ConversionException("No message converter is registered for " - + mimeType.toString()); + throw new ConversionException( + "No message converter is registered for " + mimeType.toString()); } if (converters.size() > 1) { return new CompositeMessageConverter(converters); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ConversionException.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ConversionException.java index 2c9a7f34d..7a615caa6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ConversionException.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CustomMimeTypeConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CustomMimeTypeConverter.java index 93a931eb0..bdfc9a461 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CustomMimeTypeConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/CustomMimeTypeConverter.java @@ -23,7 +23,6 @@ import org.springframework.util.MimeType; * A custom converter for {@link MimeType} that accepts a plain java class name as a * shorthand for {@code application/x-java-object;type=the.qualified.ClassName}. * - * * @author Eric Bottard * @author David Turanski */ diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JavaSerializationMessageConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JavaSerializationMessageConverter.java index b475f45c3..8adb251a5 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JavaSerializationMessageConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JavaSerializationMessageConverter.java @@ -42,19 +42,21 @@ public class JavaSerializationMessageConverter extends AbstractMessageConverter @Override protected boolean supports(Class clazz) { - if (clazz != null){ + if (clazz != null) { return Serializable.class.isAssignableFrom(clazz); } return true; } @Override - public Object convertFromInternal(Message message, Class targetClass, Object conversionHint) { + public Object convertFromInternal(Message message, Class targetClass, + Object conversionHint) { if (!(message.getPayload() instanceof byte[])) { return null; } try { - ByteArrayInputStream bis = new ByteArrayInputStream((byte[]) (message.getPayload())); + ByteArrayInputStream bis = new ByteArrayInputStream( + (byte[]) (message.getPayload())); return new ObjectInputStream(bis).readObject(); } catch (Exception e) { @@ -64,7 +66,8 @@ public class JavaSerializationMessageConverter extends AbstractMessageConverter } @Override - protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + protected Object convertToInternal(Object payload, MessageHeaders headers, + Object conversionHint) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { new ObjectOutputStream(bos).writeObject(payload); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JsonUnmarshallingConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JsonUnmarshallingConverter.java index f3858bc89..1f36fa58b 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JsonUnmarshallingConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/JsonUnmarshallingConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,10 +30,10 @@ import org.springframework.messaging.converter.MessageConversionException; * as input. * * @author Marius Bogoevici - * * @deprecated as of 2.0. */ -// NOTE we need to revisit as to why do we need it in the first place, given that our first converter already handles JSON +// NOTE we need to revisit as to why do we need it in the first place, given that our +// first converter already handles JSON @Deprecated public class JsonUnmarshallingConverter extends AbstractMessageConverter { @@ -47,15 +47,18 @@ public class JsonUnmarshallingConverter extends AbstractMessageConverter { @Override protected boolean supports(Class aClass) { - return String.class.isAssignableFrom(aClass) || byte[].class.isAssignableFrom(aClass) ; + return String.class.isAssignableFrom(aClass) + || byte[].class.isAssignableFrom(aClass); } @Override - protected Object convertFromInternal(Message message, Class targetClass, Object conversionHint) { + protected Object convertFromInternal(Message message, Class targetClass, + Object conversionHint) { Object payload = message.getPayload(); try { - return payload instanceof byte[] ? objectMapper.readValue((byte[]) payload, targetClass) - : objectMapper.readValue((String) payload, targetClass); + return payload instanceof byte[] + ? this.objectMapper.readValue((byte[]) payload, targetClass) + : this.objectMapper.readValue((String) payload, targetClass); } catch (IOException e) { throw new MessageConversionException("Cannot parse payload ", e); @@ -63,7 +66,9 @@ public class JsonUnmarshallingConverter extends AbstractMessageConverter { } @Override - protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + protected Object convertToInternal(Object payload, MessageHeaders headers, + Object conversionHint) { return super.convertToInternal(payload, headers, conversionHint); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/KryoMessageConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/KryoMessageConverter.java index 01cfc8799..1240aaa00 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/KryoMessageConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/KryoMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,71 +48,82 @@ import org.springframework.util.MimeType; /** * @author Vinicius Carvalho - * @deprecated as of 2.0 all language specific type converters (kryo, java etc) are deprecated and won't be supported in the future. + * @deprecated as of 2.0 all language specific type converters (kryo, java etc) are + * deprecated and won't be supported in the future. */ @Deprecated public class KryoMessageConverter implements SmartMessageConverter { + /** + * Kryo mime type. + */ + public static final String KRYO_MIME_TYPE = "application/x-java-object"; + protected final KryoPool pool; private final CompositeKryoRegistrar kryoRegistrar; private final boolean useReferences; - private ConcurrentMap mimeTypesCache = new ConcurrentHashMap<>(); - private final List supportedMimeTypes; - public static final String KRYO_MIME_TYPE = "application/x-java-object"; + private ConcurrentMap mimeTypesCache = new ConcurrentHashMap<>(); private ContentTypeResolver contentTypeResolver = new DefaultContentTypeResolver(); - public KryoMessageConverter(List kryoRegistrars, boolean useReferences) { + public KryoMessageConverter(List kryoRegistrars, + boolean useReferences) { this.useReferences = useReferences; - this.kryoRegistrar = CollectionUtils.isEmpty(kryoRegistrars) ? null : - new CompositeKryoRegistrar(kryoRegistrars); + this.kryoRegistrar = CollectionUtils.isEmpty(kryoRegistrars) ? null + : new CompositeKryoRegistrar(kryoRegistrars); KryoFactory factory = () -> { Kryo kryo = new Kryo(); configureKryoInstance(kryo); return kryo; }; this.pool = new KryoPool.Builder(factory).softReferences().build(); - this.supportedMimeTypes = Collections.singletonList(MimeType.valueOf(KRYO_MIME_TYPE)); + this.supportedMimeTypes = Collections + .singletonList(MimeType.valueOf(KRYO_MIME_TYPE)); } @Nullable @Override - public Object fromMessage(Message message, Class targetClass, @Nullable Object conversionHint) { + public Object fromMessage(Message message, Class targetClass, + @Nullable Object conversionHint) { if (!canConvertFrom(message, targetClass)) { return null; } - if(!message.getPayload().getClass().isAssignableFrom(byte[].class)){ - throw new MessageConversionException("This converter can only convert messages with byte[] payload"); + if (!message.getPayload().getClass().isAssignableFrom(byte[].class)) { + throw new MessageConversionException( + "This converter can only convert messages with byte[] payload"); } - byte[] payload = (byte[])message.getPayload(); + byte[] payload = (byte[]) message.getPayload(); try { return deserialize(payload, targetClass); } catch (IOException e) { - throw new MessageConversionException("Could not deserialize payload",e); + throw new MessageConversionException("Could not deserialize payload", e); } } @Nullable @Override - public Message toMessage(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { + public Message toMessage(Object payload, @Nullable MessageHeaders headers, + @Nullable Object conversionHint) { if (!canConvertTo(payload, headers)) { return null; } byte[] payloadToUse = serialize(payload); MimeType mimeType = getDefaultContentType(payload); if (headers != null) { - MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class); + MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, + MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { if (mimeType != null) { accessor.setHeader(MessageHeaders.CONTENT_TYPE, mimeType); } - return MessageBuilder.createMessage(payloadToUse, accessor.getMessageHeaders()); + return MessageBuilder.createMessage(payloadToUse, + accessor.getMessageHeaders()); } } MessageBuilder builder = MessageBuilder.withPayload(payloadToUse); @@ -134,20 +145,18 @@ public class KryoMessageConverter implements SmartMessageConverter { return mimeTypeFromObject(payload); } - - protected byte[] serialize(Object payload) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); final Output output = new Output(baos); this.pool.run(kryo -> { - kryo.writeObject(output,payload); + kryo.writeObject(output, payload); return Void.TYPE; }); output.close(); - return baos.toByteArray(); + return baos.toByteArray(); } - protected T deserialize(byte[] bytes, Class type) throws IOException { + protected T deserialize(byte[] bytes, Class type) throws IOException { Assert.notNull(bytes, "'bytes' cannot be null"); final Input input = new Input(bytes); try { @@ -158,13 +167,15 @@ public class KryoMessageConverter implements SmartMessageConverter { } } - protected T deserialize(InputStream inputStream, final Class type) throws IOException { + protected T deserialize(InputStream inputStream, final Class type) + throws IOException { Assert.notNull(inputStream, "'inputStream' cannot be null"); Assert.notNull(type, "'type' cannot be null"); - final Input input = (inputStream instanceof Input ? (Input) inputStream : new Input(inputStream)); + final Input input = (inputStream instanceof Input ? (Input) inputStream + : new Input(inputStream)); T result = null; try { - result = this.pool.run(kryo -> kryo.readObject(input,type)); + result = this.pool.run(kryo -> kryo.readObject(input, type)); } finally { input.close(); @@ -173,18 +184,18 @@ public class KryoMessageConverter implements SmartMessageConverter { } protected void configureKryoInstance(Kryo kryo) { - kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy())); + kryo.setInstantiatorStrategy( + new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy())); if (this.kryoRegistrar != null) { this.kryoRegistrar.registerTypes(kryo); } kryo.setReferences(this.useReferences); } - - protected MimeType mimeTypeFromObject(Object payload) { + protected MimeType mimeTypeFromObject(Object payload) { Assert.notNull(payload, "payload object cannot be null."); String className = payload.getClass().getName(); - MimeType mimeType = mimeTypesCache.get(className); + MimeType mimeType = this.mimeTypesCache.get(className); if (mimeType == null) { String modifiedClassName = className; if (payload.getClass().isArray()) { @@ -192,18 +203,18 @@ public class KryoMessageConverter implements SmartMessageConverter { // "[Ljava.lang.String;" or multi-dimensional // "[[[Ljava.lang.String;" if (modifiedClassName.endsWith(";")) { - modifiedClassName = modifiedClassName.substring(0, modifiedClassName.length() - 1); + modifiedClassName = modifiedClassName.substring(0, + modifiedClassName.length() - 1); } // Wrap in quotes to handle the illegal '[' character modifiedClassName = "\"" + modifiedClassName + "\""; } - mimeType = MimeType.valueOf(KRYO_MIME_TYPE+";type=" + modifiedClassName); - mimeTypesCache.put(className, mimeType); + mimeType = MimeType.valueOf(KRYO_MIME_TYPE + ";type=" + modifiedClassName); + this.mimeTypesCache.put(className, mimeType); } return mimeType; } - protected boolean canConvertFrom(Message message, Class targetClass) { return (supports(targetClass) && supportsMimeType(message.getHeaders())); } @@ -217,7 +228,8 @@ public class KryoMessageConverter implements SmartMessageConverter { return false; } for (MimeType current : getSupportedMimeTypes()) { - if (current.getType().equals(mimeType.getType()) && current.getSubtype().equals(mimeType.getSubtype())) { + if (current.getType().equals(mimeType.getType()) + && current.getSubtype().equals(mimeType.getSubtype())) { return true; } } @@ -226,7 +238,8 @@ public class KryoMessageConverter implements SmartMessageConverter { @Nullable protected MimeType getMimeType(@Nullable MessageHeaders headers) { - return (headers != null && this.contentTypeResolver != null ? this.contentTypeResolver.resolve(headers) : null); + return (headers != null && this.contentTypeResolver != null + ? this.contentTypeResolver.resolve(headers) : null); } private boolean supports(Class targetClass) { @@ -242,10 +255,11 @@ public class KryoMessageConverter implements SmartMessageConverter { @Nullable @Override public Message toMessage(Object payload, @Nullable MessageHeaders headers) { - return toMessage(payload,headers,null); + return toMessage(payload, headers, null); } public List getSupportedMimeTypes() { - return supportedMimeTypes; + return this.supportedMimeTypes; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/MessageConverterUtils.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/MessageConverterUtils.java index ad1d15f24..fc1560f08 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/MessageConverterUtils.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/MessageConverterUtils.java @@ -34,27 +34,29 @@ public abstract class MessageConverterUtils { /** * An MimeType specifying a {@link Tuple}. */ - public static final MimeType X_SPRING_TUPLE = MimeType.valueOf("application/x-spring-tuple"); + public static final MimeType X_SPRING_TUPLE = MimeType + .valueOf("application/x-spring-tuple"); /** * A general MimeType for Java Types. */ - public static final MimeType X_JAVA_OBJECT = MimeType.valueOf("application/x-java-object"); + public static final MimeType X_JAVA_OBJECT = MimeType + .valueOf("application/x-java-object"); /** * A general MimeType for a Java serialized byte array. */ - public static final MimeType X_JAVA_SERIALIZED_OBJECT = MimeType.valueOf("application/x-java-serialized-object"); + public static final MimeType X_JAVA_SERIALIZED_OBJECT = MimeType + .valueOf("application/x-java-serialized-object"); /** - * Get the java Object type for the MimeType X_JAVA_OBJECT - * - * @return the class for the content type + * Get the java Object type for the MimeType X_JAVA_OBJECT. + * @param contentType content type + * @return the class for the content type. */ public static Class getJavaTypeForJavaObjectContentType(MimeType contentType) { - Assert.isTrue(X_JAVA_OBJECT.includes(contentType), - "Content type must be " + X_JAVA_OBJECT.toString() + ", or " + - "included in it"); + Assert.isTrue(X_JAVA_OBJECT.includes(contentType), "Content type must be " + + X_JAVA_OBJECT.toString() + ", or " + "included in it"); if (contentType.getParameter("type") != null) { try { return ClassUtils.forName(contentType.getParameter("type"), null); @@ -67,8 +69,7 @@ public abstract class MessageConverterUtils { } /** - * Build the conventional {@link MimeType} for a java object - * + * Build the conventional {@link MimeType} for a java object. * @param clazz the java type * @return the MIME type */ @@ -83,13 +84,16 @@ public abstract class MessageConverterUtils { mimeType = resolveContentType(contentTypeString); } catch (ClassNotFoundException cfe) { - throw new IllegalArgumentException("Could not find the class required for " + contentTypeString, cfe); + throw new IllegalArgumentException( + "Could not find the class required for " + contentTypeString, + cfe); } } return mimeType; } - public static MimeType resolveContentType(String type) throws ClassNotFoundException, LinkageError { + public static MimeType resolveContentType(String type) + throws ClassNotFoundException, LinkageError { if (!type.contains("/")) { Class javaType = resolveJavaType(type); return javaObjectMimeType(javaType); @@ -97,7 +101,8 @@ public abstract class MessageConverterUtils { return MimeType.valueOf(type); } - public static Class resolveJavaType(String type) throws ClassNotFoundException, LinkageError { + public static Class resolveJavaType(String type) + throws ClassNotFoundException, LinkageError { return ClassUtils.forName(type, null); } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ObjectStringMessageConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ObjectStringMessageConverter.java index fdee12a8e..47de34091 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ObjectStringMessageConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/ObjectStringMessageConverter.java @@ -34,7 +34,6 @@ import org.springframework.util.MimeType; * * @author Marius Bogoevici * @author Oleg Zhurakousky - * * @since 1.2 */ public class ObjectStringMessageConverter extends AbstractMessageConverter { @@ -68,19 +67,22 @@ public class ObjectStringMessageConverter extends AbstractMessageConverter { return super.supportsMimeType(headers); } - protected Object convertFromInternal(Message message, Class targetClass, Object conversionHint) { + protected Object convertFromInternal(Message message, Class targetClass, + Object conversionHint) { if (message.getPayload() != null) { if (message.getPayload() instanceof byte[]) { if (byte[].class.isAssignableFrom(targetClass)) { return message.getPayload(); } else { - return new String((byte[]) message.getPayload(), StandardCharsets.UTF_8); + return new String((byte[]) message.getPayload(), + StandardCharsets.UTF_8); } } else { if (byte[].class.isAssignableFrom(targetClass)) { - return message.getPayload().toString().getBytes(StandardCharsets.UTF_8); + return message.getPayload().toString() + .getBytes(StandardCharsets.UTF_8); } else { return message.getPayload(); @@ -90,7 +92,8 @@ public class ObjectStringMessageConverter extends AbstractMessageConverter { return null; } - protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + protected Object convertToInternal(Object payload, MessageHeaders headers, + Object conversionHint) { if (payload != null) { if ((payload instanceof byte[])) { return payload; diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/TupleJsonMessageConverter.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/TupleJsonMessageConverter.java index e26ec202a..8f5a15468 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/TupleJsonMessageConverter.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/converter/TupleJsonMessageConverter.java @@ -32,12 +32,12 @@ import org.springframework.util.MimeTypeUtils; /** * A {@link org.springframework.messaging.converter.MessageConverter} to convert a - * {@link Tuple} to JSON bytes + * {@link Tuple} to JSON bytes. + * * @author David Turanski * @author Ilayaperumal Gopinathan * @author Marius Bogoevici * @author Vinicius Carvalho - * * @deprecated as of 2.0. please use 'application/json' content type */ @Deprecated @@ -49,7 +49,8 @@ public class TupleJsonMessageConverter extends AbstractMessageConverter { private volatile boolean prettyPrint; public TupleJsonMessageConverter(ObjectMapper objectMapper) { - super(Arrays.asList(MessageConverterUtils.X_SPRING_TUPLE, MimeTypeUtils.APPLICATION_JSON)); + super(Arrays.asList(MessageConverterUtils.X_SPRING_TUPLE, + MimeTypeUtils.APPLICATION_JSON)); this.objectMapper = (objectMapper != null) ? objectMapper : new ObjectMapper(); } @@ -63,13 +64,15 @@ public class TupleJsonMessageConverter extends AbstractMessageConverter { } @Override - protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + protected Object convertToInternal(Object payload, MessageHeaders headers, + Object conversionHint) { Tuple t = (Tuple) payload; String json; if (this.prettyPrint) { try { Object tmp = this.objectMapper.readValue(t.toString(), Object.class); - json = this.objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(tmp); + json = this.objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(tmp); } catch (IOException e) { this.logger.error(e.getMessage(), e); @@ -83,7 +86,8 @@ public class TupleJsonMessageConverter extends AbstractMessageConverter { } @Override - public Object convertFromInternal(Message message, Class targetClass, Object conversionHint) { + public Object convertFromInternal(Message message, Class targetClass, + Object conversionHint) { String source; if (message.getPayload() instanceof byte[]) { source = new String((byte[]) message.getPayload(), Charset.forName("UTF-8")); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/BindingsEndpoint.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/BindingsEndpoint.java index c22893140..49d3e15e6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/BindingsEndpoint.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/BindingsEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -35,12 +35,10 @@ import org.springframework.util.Assert; /** * - * Actuator endpoint for binding control + * Actuator endpoint for binding control. * * @author Oleg Zhurakousky - * * @since 2.0 - * */ @Endpoint(id = "bindings") public class BindingsEndpoint { @@ -51,8 +49,10 @@ public class BindingsEndpoint { private final ObjectMapper objectMapper; - public BindingsEndpoint(List inputBindingLifecycles, List outputBindingsLifecycles) { - Assert.notEmpty(inputBindingLifecycles, "'inputBindingLifecycles' must not be null or empty"); + public BindingsEndpoint(List inputBindingLifecycles, + List outputBindingsLifecycles) { + Assert.notEmpty(inputBindingLifecycles, + "'inputBindingLifecycles' must not be null or empty"); this.inputBindingLifecycles = inputBindingLifecycles; this.outputBindingsLifecycles = outputBindingsLifecycles; this.objectMapper = new ObjectMapper(); @@ -63,20 +63,20 @@ public class BindingsEndpoint { Binding binding = BindingsEndpoint.this.locateBinding(name); if (binding != null) { switch (state) { - case STARTED: - binding.start(); - break; - case STOPPED: - binding.stop(); - break; - case PAUSED: - binding.pause(); - break; - case RESUMED: - binding.resume(); - break; - default: - break; + case STARTED: + binding.start(); + break; + case STOPPED: + binding.stop(); + break; + case PAUSED: + binding.pause(); + break; + case RESUMED: + binding.resume(); + break; + default: + break; } } } @@ -85,7 +85,7 @@ public class BindingsEndpoint { public List queryStates() { List> bindings = new ArrayList<>(gatherInputBindings()); bindings.addAll(gatherOutputBindings()); - return objectMapper.convertValue(bindings, List.class); + return this.objectMapper.convertValue(bindings, List.class); } @ReadOperation @@ -98,8 +98,8 @@ public class BindingsEndpoint { private List> gatherInputBindings() { List> inputBindings = new ArrayList<>(); for (InputBindingLifecycle inputBindingLifecycle : this.inputBindingLifecycles) { - Collection> lifecycleInputBindings = - (Collection>) new DirectFieldAccessor(inputBindingLifecycle).getPropertyValue("inputBindings"); + Collection> lifecycleInputBindings = (Collection>) new DirectFieldAccessor( + inputBindingLifecycle).getPropertyValue("inputBindings"); inputBindings.addAll(lifecycleInputBindings); } return inputBindings; @@ -117,17 +117,37 @@ public class BindingsEndpoint { } private Binding locateBinding(String name) { - Stream> bindings = Stream.concat(this.gatherInputBindings().stream(), this.gatherOutputBindings().stream()); - return bindings - .filter(binding -> name.equals(binding.getName())) - .findFirst() - .orElse(null); + Stream> bindings = Stream.concat(this.gatherInputBindings().stream(), + this.gatherOutputBindings().stream()); + return bindings.filter(binding -> name.equals(binding.getName())).findFirst() + .orElse(null); } + /** + * Binding states. + */ public enum State { + + /** + * Started state of a binding. + */ STARTED, + + /** + * Stopped state of a binding. + */ STOPPED, + + /** + * Paused state of a binding. + */ PAUSED, + + /** + * Resumed state of a binding. + */ RESUMED; + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/ChannelsEndpoint.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/ChannelsEndpoint.java index 0c2786168..dc2b380a9 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/ChannelsEndpoint.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/ChannelsEndpoint.java @@ -46,7 +46,8 @@ public class ChannelsEndpoint { private BindingServiceProperties properties; - public ChannelsEndpoint(List adapters, BindingServiceProperties properties) { + public ChannelsEndpoint(List adapters, + BindingServiceProperties properties) { this.adapters = adapters; this.properties = properties; } @@ -64,10 +65,14 @@ public class ChannelsEndpoint { outputs.put(name, this.properties.getBindingProperties(name)); } } - return new ObjectMapper().convertValue(map, new TypeReference>() { - }); + return new ObjectMapper().convertValue(map, + new TypeReference>() { + }); } + /** + * Meta data for channels. Contains e.g. input and outputs. + */ @JsonInclude(Include.NON_DEFAULT) public static class ChannelsMetaData { @@ -82,6 +87,7 @@ public class ChannelsEndpoint { public Map getOutputs() { return this.outputs; } + } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FluxedConsumerWrapper.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FluxedConsumerWrapper.java index 8a7e9990a..e9019aa65 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FluxedConsumerWrapper.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FluxedConsumerWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -25,14 +25,13 @@ import reactor.core.publisher.Mono; import org.springframework.cloud.function.core.FluxWrapper; /** - * * @author Oleg Zhurakousky - * * @since 2.1 * * Will most likely be moved to SCF */ -class FluxedConsumerWrapper implements Function, Mono>, FluxWrapper>> { +class FluxedConsumerWrapper + implements Function, Mono>, FluxWrapper>> { private final Consumer> consumer; @@ -42,12 +41,12 @@ class FluxedConsumerWrapper implements Function, Mono>, FluxWra @Override public Consumer> getTarget() { - return consumer; + return this.consumer; } @Override public Mono apply(Flux t) { - return Mono.fromRunnable(() -> this.consumer.accept(t)); + return Mono.fromRunnable(() -> this.consumer.accept(t)); } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionCatalogWrapper.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionCatalogWrapper.java index 6d5c4af62..c3c82ac70 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionCatalogWrapper.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionCatalogWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -22,7 +22,6 @@ import org.springframework.util.Assert; /** * @author David Turanski * @author Oleg Zhurakousky - * * @since 2.1 **/ class FunctionCatalogWrapper { @@ -34,10 +33,13 @@ class FunctionCatalogWrapper { } T lookup(Class functionType, String name) { - T function = catalog.lookup(functionType, name); - Assert.notNull(function, functionType == null ? - String.format("User provided Function '%s' cannot be located.", name) : - String.format("User provided %s '%s' cannot be located.", functionType.getSimpleName(), name)); + T function = this.catalog.lookup(functionType, name); + Assert.notNull(function, + functionType == null + ? String.format("User provided Function '%s' cannot be located.", + name) + : String.format("User provided %s '%s' cannot be located.", + functionType.getSimpleName(), name)); return function; } @@ -46,6 +48,7 @@ class FunctionCatalogWrapper { } boolean contains(Class functionType, String name) { - return catalog.lookup(functionType, name) != null; + return this.catalog.lookup(functionType, name) != null; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java index 279935346..f1f8cfbef 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -59,11 +59,13 @@ public class FunctionConfiguration { private Sink sink; @Bean - public IntegrationFlowFunctionSupport functionSupport(FunctionCatalogWrapper functionCatalog, - FunctionInspector functionInspector, CompositeMessageConverterFactory messageConverterFactory, - StreamFunctionProperties functionProperties, BindingServiceProperties bindingServiceProperties) { - return new IntegrationFlowFunctionSupport(functionCatalog, functionInspector, messageConverterFactory, - functionProperties, bindingServiceProperties); + public IntegrationFlowFunctionSupport functionSupport( + FunctionCatalogWrapper functionCatalog, FunctionInspector functionInspector, + CompositeMessageConverterFactory messageConverterFactory, + StreamFunctionProperties functionProperties, + BindingServiceProperties bindingServiceProperties) { + return new IntegrationFlowFunctionSupport(functionCatalog, functionInspector, + messageConverterFactory, functionProperties, bindingServiceProperties); } @Bean @@ -73,27 +75,39 @@ public class FunctionConfiguration { /** * This configuration creates an instance of the {@link IntegrationFlow} from standard - * Spring Cloud Stream bindings such as {@link Source}, {@link Processor} and {@link Sink} - * ONLY if there are no existing instances of the {@link IntegrationFlow} already available - * in the context. This means that it only plays a role in green-field Spring Cloud Stream apps. + * Spring Cloud Stream bindings such as {@link Source}, {@link Processor} and + * {@link Sink} ONLY if there are no existing instances of the {@link IntegrationFlow} + * already available in the context. This means that it only plays a role in + * green-field Spring Cloud Stream apps. * - * For logic to compose functions into the existing apps please see "FUNCTION-TO-EXISTING-APP" - * section of AbstractMessageChannelBinder. + * For logic to compose functions into the existing apps please see + * "FUNCTION-TO-EXISTING-APP" section of AbstractMessageChannelBinder. * - * The @ConditionalOnMissingBean ensures it does not collide with the the instance of the IntegrationFlow - * that may have been already defined by the existing (extended) app. + * The @ConditionalOnMissingBean ensures it does not collide with the the instance of + * the IntegrationFlow that may have been already defined by the existing (extended) + * app. + * @param functionSupport support for registering beans + * @return integration flow for Stream */ @ConditionalOnMissingBean @Bean - public IntegrationFlow integrationFlowCreator(IntegrationFlowFunctionSupport functionSupport) { - if (functionSupport.containsFunction(Consumer.class) && consumerBindingPresent()) { - return functionSupport.integrationFlowForFunction(getInputChannel(), getOutputChannel()).get(); + public IntegrationFlow integrationFlowCreator( + IntegrationFlowFunctionSupport functionSupport) { + if (functionSupport.containsFunction(Consumer.class) + && consumerBindingPresent()) { + return functionSupport + .integrationFlowForFunction(getInputChannel(), getOutputChannel()) + .get(); } - else if (functionSupport.containsFunction(Function.class) && consumerBindingPresent()) { - return functionSupport.integrationFlowForFunction(getInputChannel(), getOutputChannel()).get(); + else if (functionSupport.containsFunction(Function.class) + && consumerBindingPresent()) { + return functionSupport + .integrationFlowForFunction(getInputChannel(), getOutputChannel()) + .get(); } else if (functionSupport.containsFunction(Supplier.class)) { - return functionSupport.integrationFlowFromNamedSupplier().channel(getOutputChannel()).get(); + return functionSupport.integrationFlowFromNamedSupplier() + .channel(getOutputChannel()).get(); } return null; } @@ -110,4 +124,5 @@ public class FunctionConfiguration { return this.processor != null ? this.processor.output() : (this.source != null ? this.source.output() : new NullChannel()); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionInvoker.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionInvoker.java index df1444d2a..966ca5d7a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionInvoker.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionInvoker.java @@ -45,14 +45,11 @@ import org.springframework.util.MimeType; import org.springframework.util.ReflectionUtils; /** - * + * @param the payload type of the input Message + * @param the payload type of the output Message * @author Oleg Zhurakousky * @author David Turanski * @author Tolga Kavukcu - * - * @param the payload type of the input Message - * @param the payload type of the output Message - * * @since 2.1 */ class FunctionInvoker implements Function>, Flux>> { @@ -62,7 +59,8 @@ class FunctionInvoker implements Function>, Flux implements Function>, Flux((Consumer) originalUserFunction) - : (Function, Flux>) originalUserFunction; + : (Function, Flux>) originalUserFunction; Assert.isInstanceOf(Function.class, this.userFunction); - this.messageConverter = compositeMessageConverterFactory.getMessageConverterForAllRegistered(); - FunctionType functionType = functionInspector.getRegistration(originalUserFunction).getType(); + this.messageConverter = compositeMessageConverterFactory + .getMessageConverterForAllRegistered(); + FunctionType functionType = functionInspector + .getRegistration(originalUserFunction).getType(); this.isInputArgumentMessage = functionType.isMessage(); this.inputClass = functionType.getInputType(); this.outputClass = functionType.getOutputType(); this.errorChannel = errorChannel; this.bindingServiceProperties = functionProperties.getBindingServiceProperties(); - this.consumerProperties = bindingServiceProperties.getConsumerProperties(functionProperties.getInputDestinationName()); - this.producerProperties = bindingServiceProperties.getProducerProperties(functionProperties.getOutputDestinationName()); + this.consumerProperties = this.bindingServiceProperties + .getConsumerProperties(functionProperties.getInputDestinationName()); + this.producerProperties = this.bindingServiceProperties + .getProducerProperties(functionProperties.getOutputDestinationName()); } @Override @@ -119,18 +126,20 @@ class FunctionInvoker implements Function>, Flux> originalMessageRef = new AtomicReference<>(); return input.concatMap(message -> { - return Flux.just(message) - .doOnNext(originalMessageRef::set) - .map(this::resolveArgument) - .transform(this.userFunction::apply) - .retryBackoff(consumerProperties.getMaxAttempts(), - Duration.ofMillis(consumerProperties.getBackOffInitialInterval()), - Duration.ofMillis(consumerProperties.getBackOffMaxInterval())) - .onErrorResume(e -> { - onError(e, originalMessageRef.get()); - return Mono.empty(); - }); - }).log().map(resultMessage -> toMessage(resultMessage, originalMessageRef.get())); // create output message + return Flux.just(message).doOnNext(originalMessageRef::set) + .map(this::resolveArgument).transform(this.userFunction::apply) + .retryBackoff(this.consumerProperties.getMaxAttempts(), + Duration.ofMillis( + this.consumerProperties.getBackOffInitialInterval()), + Duration.ofMillis( + this.consumerProperties.getBackOffMaxInterval())) + .onErrorResume(e -> { + onError(e, originalMessageRef.get()); + return Mono.empty(); + }); + }).log().map(resultMessage -> toMessage(resultMessage, originalMessageRef.get())); // create + // output + // message } private void onError(Throwable t, Message originalMessage) { @@ -147,40 +156,50 @@ class FunctionInvoker implements Function>, Flux Message toMessage(T value, Message originalMessage) { if (logger.isDebugEnabled()) { - logger.debug("Converting result back to message using the original message: " + originalMessage); + logger.debug("Converting result back to message using the original message: " + + originalMessage); } Message returnMessage; - if(producerProperties.isUseNativeEncoding()){ + if (this.producerProperties.isUseNativeEncoding()) { if (logger.isDebugEnabled()) { - logger.debug("Native encoding enabled wrapping result to message using the original message: " + originalMessage); + logger.debug( + "Native encoding enabled wrapping result to message using the original message: " + + originalMessage); } - returnMessage = wrapOutputToMessage(value,originalMessage); + returnMessage = wrapOutputToMessage(value, originalMessage); } else { - returnMessage = (Message) - (value instanceof Message - ? value - : this.messageConverter.toMessage(value, originalMessage.getHeaders(), this.outputClass)); - if (returnMessage == null && value.getClass().isAssignableFrom(this.outputClass)) { + returnMessage = (Message) (value instanceof Message ? value + : this.messageConverter.toMessage(value, originalMessage.getHeaders(), + this.outputClass)); + if (returnMessage == null + && value.getClass().isAssignableFrom(this.outputClass)) { returnMessage = wrapOutputToMessage(value, originalMessage); } else if (this.bindingServiceProperties != null - && this.bindingServiceProperties.getBindingProperties(this.functionProperties.getOutputDestinationName()) != null - && !returnMessage.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) { + && this.bindingServiceProperties.getBindingProperties( + this.functionProperties.getOutputDestinationName()) != null + && !returnMessage.getHeaders() + .containsKey(MessageHeaders.CONTENT_TYPE)) { - ((Map) ReflectionUtils.getField(MESSAGE_HEADERS_FIELD, returnMessage.getHeaders())) - .put(MessageHeaders.CONTENT_TYPE, MimeType.valueOf(bindingServiceProperties.getBindingProperties("output").getContentType())); + ((Map) ReflectionUtils.getField(MESSAGE_HEADERS_FIELD, + returnMessage.getHeaders())).put( + MessageHeaders.CONTENT_TYPE, + MimeType.valueOf(this.bindingServiceProperties + .getBindingProperties("output") + .getContentType())); } - Assert.notNull(returnMessage, "Failed to convert result value '" + value + "' to message."); + Assert.notNull(returnMessage, + "Failed to convert result value '" + value + "' to message."); } return returnMessage; } - @SuppressWarnings("unchecked") private Message wrapOutputToMessage(T value, Message originalMessage) { - Message returnMessage = (Message) MessageBuilder.withPayload(value).copyHeaders(originalMessage.getHeaders()) + Message returnMessage = (Message) MessageBuilder.withPayload(value) + .copyHeaders(originalMessage.getHeaders()) .removeHeader(MessageHeaders.CONTENT_TYPE).build(); return returnMessage; } @@ -192,19 +211,19 @@ class FunctionInvoker implements Function>, Flux)argument).getPayload(); + argument = ((Message) argument).getPayload(); } return argument; } private boolean shouldConvertFromMessage(Message message) { - return !this.inputClass.isAssignableFrom(Message.class) && - !this.inputClass.isAssignableFrom(message.getPayload().getClass()) && - !this.inputClass.isAssignableFrom(Object.class); + return !this.inputClass.isAssignableFrom(Message.class) + && !this.inputClass.isAssignableFrom(message.getPayload().getClass()) + && !this.inputClass.isAssignableFrom(Object.class); } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/IntegrationFlowFunctionSupport.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/IntegrationFlowFunctionSupport.java index d9df46d49..4de6aa1d7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/IntegrationFlowFunctionSupport.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/IntegrationFlowFunctionSupport.java @@ -41,11 +41,9 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * * @author Oleg Zhurakousky * @author David Turanski * @author Ilayaperumal Gopinathan - * * @since 2.1 */ public class IntegrationFlowFunctionSupport { @@ -61,19 +59,15 @@ public class IntegrationFlowFunctionSupport { @Autowired private MessageChannel errorChannel; - /** - * @param functionCatalog - * @param functionInspector - * @param messageConverterFactory - * @param functionProperties - */ - IntegrationFlowFunctionSupport(FunctionCatalogWrapper functionCatalog, FunctionInspector functionInspector, - CompositeMessageConverterFactory messageConverterFactory, StreamFunctionProperties functionProperties, + IntegrationFlowFunctionSupport(FunctionCatalogWrapper functionCatalog, + FunctionInspector functionInspector, + CompositeMessageConverterFactory messageConverterFactory, + StreamFunctionProperties functionProperties, BindingServiceProperties bindingServiceProperties) { - Assert.notNull(functionCatalog, "'functionCatalog' must not be null"); Assert.notNull(functionInspector, "'functionInspector' must not be null"); - Assert.notNull(messageConverterFactory, "'messageConverterFactory' must not be null"); + Assert.notNull(messageConverterFactory, + "'messageConverterFactory' must not be null"); Assert.notNull(functionProperties, "'functionProperties' must not be null"); this.functionCatalog = functionCatalog; this.functionInspector = functionInspector; @@ -84,49 +78,55 @@ public class IntegrationFlowFunctionSupport { /** * Determines if function specified via 'spring.cloud.stream.function.definition' - * property can be located in {@link FunctionCatalog} - * + * property can be located in {@link FunctionCatalog}s. + * @param type of function * @param typeOfFunction must be Supplier, Function or Consumer - * @return + * @return {@code true} if function is already stored */ public boolean containsFunction(Class typeOfFunction) { return StringUtils.hasText(this.functionProperties.getDefinition()) - && this.functionCatalog.contains(typeOfFunction, this.functionProperties.getDefinition()); + && this.functionCatalog.contains(typeOfFunction, + this.functionProperties.getDefinition()); } /** * Determines if function specified via 'spring.cloud.stream.function.definition' - * property can be located in {@link FunctionCatalog} - * + * property can be located in {@link FunctionCatalog}. + * @param type of function * @param typeOfFunction must be Supplier, Function or Consumer * @param functionName the function name to check - * @return + * @return {@code true} if function is already stored */ public boolean containsFunction(Class typeOfFunction, String functionName) { return StringUtils.hasText(functionName) && this.functionCatalog.contains(typeOfFunction, functionName); } + /** + * @return the function type basing on the function definition. + */ public FunctionType getCurrentFunctionType() { - FunctionType functionType = functionInspector.getRegistration( - functionCatalog.lookup(this.functionProperties.getDefinition())).getType(); + FunctionType functionType = this.functionInspector.getRegistration( + this.functionCatalog.lookup(this.functionProperties.getDefinition())) + .getType(); return functionType; } /** - * Create an instance of the {@link IntegrationFlowBuilder} from a {@link Supplier} bean available in the context. - * The name of the bean must be provided via `spring.cloud.stream.function.definition` property. + * Create an instance of the {@link IntegrationFlowBuilder} from a {@link Supplier} + * bean available in the context. The name of the bean must be provided via + * `spring.cloud.stream.function.definition` property. * @return instance of {@link IntegrationFlowBuilder} * @throws IllegalStateException if the named Supplier can not be located. */ public IntegrationFlowBuilder integrationFlowFromNamedSupplier() { if (StringUtils.hasText(this.functionProperties.getDefinition())) { - Supplier supplier = functionCatalog.lookup(Supplier.class, this.functionProperties.getDefinition()); + Supplier supplier = this.functionCatalog.lookup(Supplier.class, + this.functionProperties.getDefinition()); if (supplier instanceof FluxSupplier) { - supplier = ((FluxSupplier)supplier).getTarget(); + supplier = ((FluxSupplier) supplier).getTarget(); } - return integrationFlowFromProvidedSupplier(supplier) - .split(); + return integrationFlowFromProvidedSupplier(supplier).split(); } throw new IllegalStateException( @@ -134,34 +134,45 @@ public class IntegrationFlowFunctionSupport { } /** - * Create an instance of the {@link IntegrationFlowBuilder} from a provided {@link Supplier}. + * Create an instance of the {@link IntegrationFlowBuilder} from a provided + * {@link Supplier}. + * @param supplier supplier from which the flow builder will be built * @return instance of {@link IntegrationFlowBuilder} */ - public IntegrationFlowBuilder integrationFlowFromProvidedSupplier(Supplier supplier) { + public IntegrationFlowBuilder integrationFlowFromProvidedSupplier( + Supplier supplier) { return IntegrationFlows.from(supplier); } /** - * @param inputChannel - * @return + * @param inputChannel channel for which flow we be built + * @return instance of {@link IntegrationFlowBuilder} */ - public IntegrationFlowBuilder integrationFlowFromChannel(SubscribableChannel inputChannel) { + public IntegrationFlowBuilder integrationFlowFromChannel( + SubscribableChannel inputChannel) { IntegrationFlowBuilder flowBuilder = IntegrationFlows.from(inputChannel).bridge(); return flowBuilder; } - public IntegrationFlowBuilder integrationFlowForFunction(SubscribableChannel inputChannel, - MessageChannel outputChannel) { + /** + * @param inputChannel channel for which flow we be built + * @param outputChannel channel for which flow we be built + * @return instance of {@link IntegrationFlowBuilder} + */ + public IntegrationFlowBuilder integrationFlowForFunction( + SubscribableChannel inputChannel, MessageChannel outputChannel) { if (inputChannel instanceof IntegrationObjectSupport) { - String inputBindingName = ((IntegrationObjectSupport)inputChannel).getComponentName(); + String inputBindingName = ((IntegrationObjectSupport) inputChannel) + .getComponentName(); if (StringUtils.hasText(inputBindingName)) { this.functionProperties.setInputDestinationName(inputBindingName); } } if (outputChannel instanceof IntegrationObjectSupport) { - String outputBindingName = ((IntegrationObjectSupport)outputChannel).getComponentName(); + String outputBindingName = ((IntegrationObjectSupport) outputChannel) + .getComponentName(); if (StringUtils.hasText(outputBindingName)) { this.functionProperties.setOutputDestinationName(outputBindingName); } @@ -176,31 +187,40 @@ public class IntegrationFlowFunctionSupport { } /** - * Add a {@link Function} bean to the end of an integration flow. - * The name of the bean must be provided via `spring.cloud.stream.function.definition` property. + * Add a {@link Function} bean to the end of an integration flow. The name of the bean + * must be provided via `spring.cloud.stream.function.definition` property. *

- * NOTE: If this method returns true, the integration flow is now represented - * as a Reactive Streams {@link Publisher} bean. + * NOTE: If this method returns true, the integration flow is now represented as a + * Reactive Streams {@link Publisher} bean. *

- * @param flowBuilder instance of the {@link IntegrationFlowBuilder} representing - * the current state of the integration flow + * @param flowBuilder instance of the {@link IntegrationFlowBuilder} representing the + * current state of the integration flow * @param outputChannel channel where the output of a function will be sent - * @param functionName the function name to use + * @param functionProperties the function properties * @return true if {@link Function} was located and added and false if it wasn't. */ - public boolean andThenFunction(IntegrationFlowBuilder flowBuilder, MessageChannel outputChannel, - StreamFunctionProperties functionProperties) { - return andThenFunction(flowBuilder.toReactivePublisher(), outputChannel, functionProperties); + public boolean andThenFunction(IntegrationFlowBuilder flowBuilder, + MessageChannel outputChannel, StreamFunctionProperties functionProperties) { + return andThenFunction(flowBuilder.toReactivePublisher(), outputChannel, + functionProperties); } - public boolean andThenFunction(Publisher publisher, MessageChannel outputChannel, - StreamFunctionProperties functionProperties) { + /** + * @param publisher publisher to subscribe to + * @param outputChannel output channel to which a message will be sent + * @param functionProperties function properties + * @param input of the function + * @param output of the function + * @return whether the function was properly invoked + */ + public boolean andThenFunction(Publisher publisher, + MessageChannel outputChannel, StreamFunctionProperties functionProperties) { if (!StringUtils.hasText(functionProperties.getDefinition())) { return false; } - FunctionInvoker functionInvoker = - new FunctionInvoker<>(functionProperties, this.functionCatalog, - this.functionInspector, this.messageConverterFactory, this.errorChannel); + FunctionInvoker functionInvoker = new FunctionInvoker<>(functionProperties, + this.functionCatalog, this.functionInspector, + this.messageConverterFactory, this.errorChannel); if (outputChannel != null) { subscribeToInput(functionInvoker, publisher, outputChannel::send); @@ -214,17 +234,18 @@ public class IntegrationFlowFunctionSupport { private Mono subscribeToOutput(Consumer> outputProcessor, Publisher> outputPublisher) { - Flux> output = outputProcessor == null - ? Flux.from(outputPublisher) - : Flux.from(outputPublisher).doOnNext(outputProcessor); + Flux> output = outputProcessor == null ? Flux.from(outputPublisher) + : Flux.from(outputPublisher).doOnNext(outputProcessor); return output.then(); } @SuppressWarnings("unchecked") - private void subscribeToInput(FunctionInvoker functionInvoker, Publisher publisher, - Consumer> outputProcessor) { + private void subscribeToInput(FunctionInvoker functionInvoker, + Publisher publisher, Consumer> outputProcessor) { Flux inputPublisher = Flux.from(publisher); - subscribeToOutput(outputProcessor, functionInvoker.apply((Flux>) inputPublisher)).subscribe(); + subscribeToOutput(outputProcessor, + functionInvoker.apply((Flux>) inputPublisher)).subscribe(); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/StreamFunctionProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/StreamFunctionProperties.java index dfb9f4df8..0d2874298 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/StreamFunctionProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/StreamFunctionProperties.java @@ -21,18 +21,16 @@ import org.springframework.cloud.stream.config.BindingServiceProperties; import org.springframework.cloud.stream.messaging.Processor; /** - * * @author Oleg Zhurakousky * @author Tolga Kavukcu - * * @since 2.1 */ @ConfigurationProperties("spring.cloud.stream.function") public class StreamFunctionProperties { /** - * Definition of functions to bind. If several functions need to be composed - * into one, use pipes (e.g., 'fooFunc|barFunc') + * Definition of functions to bind. If several functions need to be composed into one, + * use pipes (e.g., 'fooFunc|barFunc') */ private String definition; @@ -51,7 +49,7 @@ public class StreamFunctionProperties { } BindingServiceProperties getBindingServiceProperties() { - return bindingServiceProperties; + return this.bindingServiceProperties; } void setBindingServiceProperties(BindingServiceProperties bindingServiceProperties) { @@ -59,7 +57,7 @@ public class StreamFunctionProperties { } String getInputDestinationName() { - return inputDestinationName; + return this.inputDestinationName; } void setInputDestinationName(String inputDestinationName) { @@ -67,10 +65,11 @@ public class StreamFunctionProperties { } String getOutputDestinationName() { - return outputDestinationName; + return this.outputDestinationName; } void setOutputDestinationName(String outputDestinationName) { this.outputDestinationName = outputDestinationName; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/internal/InternalPropertyNames.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/internal/InternalPropertyNames.java index 42860667a..a900cd567 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/internal/InternalPropertyNames.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/internal/InternalPropertyNames.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-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. @@ -23,10 +23,21 @@ package org.springframework.cloud.stream.internal; */ public abstract class InternalPropertyNames { + /** + * Prefix for internal Spring Cloud Stream properties. + */ public static final String SPRING_CLOUD_STREAM_INTERNAL_PREFIX = "spring.cloud.stream.internal"; - public static final String NAMESPACE_PROPERTY_NAME = SPRING_CLOUD_STREAM_INTERNAL_PREFIX + ".namespace"; + /** + * Namespace property for internal Spring Cloud Stream properties. + */ + public static final String NAMESPACE_PROPERTY_NAME = SPRING_CLOUD_STREAM_INTERNAL_PREFIX + + ".namespace"; + /** + * Self contained property for internal Spring Cloud Stream properties. + */ public static final String SELF_CONTAINED_APP_PROPERTY_NAME = SPRING_CLOUD_STREAM_INTERNAL_PREFIX + ".selfContained"; + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/DirectWithAttributesChannel.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/DirectWithAttributesChannel.java index 1a759c810..534ad2491 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/DirectWithAttributesChannel.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/DirectWithAttributesChannel.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -22,7 +22,6 @@ import java.util.Map; import org.springframework.integration.channel.DirectChannel; /** - * * @author Oleg Zhurakousky * @since 2.1 */ @@ -37,4 +36,5 @@ public class DirectWithAttributesChannel extends DirectChannel { public Object getAttribute(String key) { return this.attributes.get(key); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Processor.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Processor.java index 88bb661f4..f2e0adc54 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Processor.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Processor.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,9 @@ package org.springframework.cloud.stream.messaging; /** * Bindable interface with one input and one output channel. * - * @see org.springframework.cloud.stream.annotation.EnableBinding * @author Dave Syer * @author Marius Bogoevici + * @see org.springframework.cloud.stream.annotation.EnableBinding */ public interface Processor extends Source, Sink { diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Sink.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Sink.java index 6b1490bb5..3c9cf5731 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Sink.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Sink.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,14 +22,20 @@ import org.springframework.messaging.SubscribableChannel; /** * Bindable interface with one input channel. * - * @see org.springframework.cloud.stream.annotation.EnableBinding * @author Dave Syer * @author Marius Bogoevici + * @see org.springframework.cloud.stream.annotation.EnableBinding */ public interface Sink { + /** + * Input channel name. + */ String INPUT = "input"; + /** + * @return input channel. + */ @Input(Sink.INPUT) SubscribableChannel input(); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Source.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Source.java index dff4851d1..21536f126 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Source.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/messaging/Source.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,14 +22,20 @@ import org.springframework.messaging.MessageChannel; /** * Bindable interface with one output channel. * - * @see org.springframework.cloud.stream.annotation.EnableBinding * @author Dave Syer * @author Marius Bogoevici + * @see org.springframework.cloud.stream.annotation.EnableBinding */ public interface Source { + /** + * Name of the output channel. + */ String OUTPUT = "output"; + /** + * @return output channel + */ @Output(Source.OUTPUT) MessageChannel output(); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetrics.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetrics.java index beef4aaaf..2109e5243 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetrics.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetrics.java @@ -25,7 +25,6 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - /** * @author Vinicius Carvalho * @author Oleg Zhurakousky @@ -45,14 +44,15 @@ class ApplicationMetrics { private Map properties; @JsonCreator - ApplicationMetrics(@JsonProperty("name") String name, @JsonProperty("metrics") Collection> metrics) { + ApplicationMetrics(@JsonProperty("name") String name, + @JsonProperty("metrics") Collection> metrics) { this.name = name; this.metrics = metrics; this.createdTime = new Date(); } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -60,7 +60,7 @@ class ApplicationMetrics { } public Collection> getMetrics() { - return metrics; + return this.metrics; } public void setMetrics(Collection> metrics) { @@ -68,11 +68,11 @@ class ApplicationMetrics { } public Date getCreatedTime() { - return createdTime; + return this.createdTime; } public Map getProperties() { - return properties; + return this.properties; } public void setProperties(Map properties) { @@ -80,10 +80,11 @@ class ApplicationMetrics { } public long getInterval() { - return interval; + return this.interval; } public void setInterval(long interval) { this.interval = interval; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetricsProperties.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetricsProperties.java index 18e812b07..b83ae523d 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetricsProperties.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/ApplicationMetricsProperties.java @@ -43,31 +43,40 @@ import org.springframework.util.PatternMatchUtils; * @author Oleg Zhurakousky */ @ConfigurationProperties(prefix = ApplicationMetricsProperties.PREFIX) -public class ApplicationMetricsProperties implements EnvironmentAware, ApplicationContextAware { - - public static final String PREFIX = "spring.cloud.stream.metrics"; - - public static final String EXPORT_FILTER = PREFIX + ".filter"; - - private static final Bindable> STRING_STRING_MAP = Bindable.mapOf(String.class, String.class); - +public class ApplicationMetricsProperties + implements EnvironmentAware, ApplicationContextAware { /** - * Pattern to control the 'meters' one wants to capture. By default all 'meters' will be captured. - * For example, 'spring.integration.*' will only capture metric information for meters whose name starts with 'spring.integration'. + * Prefix for Stream application metrics. + */ + public static final String PREFIX = "spring.cloud.stream.metrics"; + + /** + * Property for the metrics filter. + */ + public static final String EXPORT_FILTER = PREFIX + ".filter"; + + private static final Bindable> STRING_STRING_MAP = Bindable + .mapOf(String.class, String.class); + + /** + * Pattern to control the 'meters' one wants to capture. By default all 'meters' will + * be captured. For example, 'spring.integration.*' will only capture metric + * information for meters whose name starts with 'spring.integration'. */ private String meterFilter; /** * The name of the metric being emitted. Should be an unique value per application. - * Defaults to: ${spring.application.name:${vcap.application.name:${spring.config.name:application}}} + * Defaults to: + * ${spring.application.name:${vcap.application.name:${spring.config.name:application}}}. */ @Value("${spring.application.name:${vcap.application.name:${spring.config.name:application}}}") private String key; /** - * Application properties that should be added to the metrics payload - * For example: `spring.application**` + * Application properties that should be added to the metrics payload For example: + * `spring.application**`. */ private String[] properties; @@ -94,12 +103,13 @@ public class ApplicationMetricsProperties implements EnvironmentAware, Applicati } @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { this.applicationContext = applicationContext; } public String getKey() { - return key; + return this.key; } public void setKey(String key) { @@ -107,7 +117,7 @@ public class ApplicationMetricsProperties implements EnvironmentAware, Applicati } public String[] getProperties() { - return properties; + return this.properties; } public void setProperties(String[] properties) { @@ -122,7 +132,7 @@ public class ApplicationMetricsProperties implements EnvironmentAware, Applicati } public Duration getScheduleInterval() { - return scheduleInterval; + return this.scheduleInterval; } public void setScheduleInterval(Duration scheduleInterval) { @@ -150,10 +160,12 @@ public class ApplicationMetricsProperties implements EnvironmentAware, Applicati if (!ObjectUtils.isEmpty(this.properties)) { Map target = bindProperties(); - BeanExpressionResolver beanExpressionResolver = ((ConfigurableApplicationContext) applicationContext) + BeanExpressionResolver beanExpressionResolver = ((ConfigurableApplicationContext) this.applicationContext) .getBeanFactory().getBeanExpressionResolver(); BeanExpressionContext expressionContext = new BeanExpressionContext( - ((ConfigurableApplicationContext) applicationContext).getBeanFactory(), null); + ((ConfigurableApplicationContext) this.applicationContext) + .getBeanFactory(), + null); for (Entry entry : target.entrySet()) { if (isMatch(entry.getKey(), this.properties, null)) { String stringValue = ObjectUtils.nullSafeToString(entry.getValue()); @@ -161,8 +173,9 @@ public class ApplicationMetricsProperties implements EnvironmentAware, Applicati if (stringValue != null) { exportedValue = stringValue.startsWith("#{") ? beanExpressionResolver.evaluate( - environment.resolvePlaceholders(stringValue), expressionContext) - : environment.resolvePlaceholders(stringValue); + this.environment.resolvePlaceholders(stringValue), + expressionContext) + : this.environment.resolvePlaceholders(stringValue); } props.put(entry.getKey(), exportedValue); @@ -174,7 +187,8 @@ public class ApplicationMetricsProperties implements EnvironmentAware, Applicati private Map bindProperties() { Map target; - BindResult> bindResult = Binder.get(environment).bind("", STRING_STRING_MAP); + BindResult> bindResult = Binder.get(this.environment).bind("", + STRING_STRING_MAP); if (bindResult.isBound()) { target = bindResult.get(); } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DefaultDestinationPublishingMeterRegistry.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DefaultDestinationPublishingMeterRegistry.java index 585c828af..8e4a435a3 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DefaultDestinationPublishingMeterRegistry.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DefaultDestinationPublishingMeterRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -28,7 +28,6 @@ import java.util.function.ToLongFunction; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; - import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.DistributionSummary; @@ -52,7 +51,6 @@ import io.micrometer.core.instrument.step.StepDistributionSummary; import io.micrometer.core.instrument.step.StepFunctionCounter; import io.micrometer.core.instrument.step.StepFunctionTimer; import io.micrometer.core.instrument.step.StepTimer; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -61,14 +59,14 @@ import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; /** - * * @author Oleg Zhurakousky - * * @since 2.0 */ -class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements SmartLifecycle { +class DefaultDestinationPublishingMeterRegistry extends MeterRegistry + implements SmartLifecycle { - private static final Log logger = LogFactory.getLog(DefaultDestinationPublishingMeterRegistry.class); + private static final Log logger = LogFactory + .getLog(DefaultDestinationPublishingMeterRegistry.class); private final MetricsPublisherConfig metricsPublisherConfig; @@ -80,8 +78,10 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements private ScheduledFuture publisher; - DefaultDestinationPublishingMeterRegistry(ApplicationMetricsProperties applicationProperties, - MetersPublisherBinding publisherBinding, MetricsPublisherConfig metricsPublisherConfig, Clock clock) { + DefaultDestinationPublishingMeterRegistry( + ApplicationMetricsProperties applicationProperties, + MetersPublisherBinding publisherBinding, + MetricsPublisherConfig metricsPublisherConfig, Clock clock) { super(clock); this.metricsPublisherConfig = metricsPublisherConfig; this.metricsConsumer = new MessageChannelPublisher(publisherBinding); @@ -95,9 +95,9 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements @Override public void stop() { - if (publisher != null) { - publisher.cancel(false); - publisher = null; + if (this.publisher != null) { + this.publisher.cancel(false); + this.publisher = null; } } @@ -129,12 +129,13 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements @Override protected Counter newCounter(Meter.Id id) { - return new StepCounter(id, clock, metricsPublisherConfig.step().toMillis()); + return new StepCounter(id, this.clock, + this.metricsPublisherConfig.step().toMillis()); } @Override protected LongTaskTimer newLongTaskTimer(Meter.Id id) { - return new DefaultLongTaskTimer(id, clock); + return new DefaultLongTaskTimer(id, this.clock); } @Override @@ -153,7 +154,8 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements } } if (!aggregatedMeters.isEmpty()) { - ApplicationMetrics metrics = new ApplicationMetrics(this.applicationProperties.getKey(), aggregatedMeters); + ApplicationMetrics metrics = new ApplicationMetrics( + this.applicationProperties.getKey(), aggregatedMeters); metrics.setInterval(this.metricsPublisherConfig.step().toMillis()); metrics.setProperties(this.applicationProperties.getExportProperties()); try { @@ -167,21 +169,27 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements } @Override - protected Timer newTimer(Id id, DistributionStatisticConfig distributionStatisticConfig, + protected Timer newTimer(Id id, + DistributionStatisticConfig distributionStatisticConfig, PauseDetector pauseDetector) { - return new StepTimer(id, clock, distributionStatisticConfig, pauseDetector, getBaseTimeUnit(), metricsPublisherConfig.step().toMillis(), false); + return new StepTimer(id, this.clock, distributionStatisticConfig, pauseDetector, + getBaseTimeUnit(), this.metricsPublisherConfig.step().toMillis(), false); } @Override - protected FunctionTimer newFunctionTimer(Id id, T obj, ToLongFunction countFunction, - ToDoubleFunction totalTimeFunction, TimeUnit totalTimeFunctionUnits) { - return new StepFunctionTimer(id, clock, metricsPublisherConfig.step().toMillis(), obj, countFunction, totalTimeFunction, - totalTimeFunctionUnits, getBaseTimeUnit()); + protected FunctionTimer newFunctionTimer(Id id, T obj, + ToLongFunction countFunction, ToDoubleFunction totalTimeFunction, + TimeUnit totalTimeFunctionUnits) { + return new StepFunctionTimer(id, this.clock, + this.metricsPublisherConfig.step().toMillis(), obj, countFunction, + totalTimeFunction, totalTimeFunctionUnits, getBaseTimeUnit()); } @Override - protected FunctionCounter newFunctionCounter(Id id, T obj, ToDoubleFunction valueFunction) { - return new StepFunctionCounter(id, clock, metricsPublisherConfig.step().toMillis(), obj, valueFunction); + protected FunctionCounter newFunctionCounter(Id id, T obj, + ToDoubleFunction valueFunction) { + return new StepFunctionCounter(id, this.clock, + this.metricsPublisherConfig.step().toMillis(), obj, valueFunction); } @Override @@ -190,23 +198,28 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements } @Override - protected DistributionSummary newDistributionSummary(Id id, DistributionStatisticConfig distributionStatisticConfig, double scale) { - return new StepDistributionSummary(id, clock, distributionStatisticConfig, scale, metricsPublisherConfig.step().toMillis(), false); + protected DistributionSummary newDistributionSummary(Id id, + DistributionStatisticConfig distributionStatisticConfig, double scale) { + return new StepDistributionSummary(id, this.clock, distributionStatisticConfig, + scale, this.metricsPublisherConfig.step().toMillis(), false); } @Override protected DistributionStatisticConfig defaultHistogramConfig() { - return DistributionStatisticConfig.builder().expiry(metricsPublisherConfig.step()).build() + return DistributionStatisticConfig.builder() + .expiry(this.metricsPublisherConfig.step()).build() .merge(DistributionStatisticConfig.DEFAULT); } private void start(ThreadFactory threadFactory) { - if (publisher != null) { + if (this.publisher != null) { stop(); } - publisher = Executors.newSingleThreadScheduledExecutor(threadFactory).scheduleAtFixedRate(this::publish, - metricsPublisherConfig.step().toMillis(), metricsPublisherConfig.step().toMillis(), - TimeUnit.MILLISECONDS); + this.publisher = Executors.newSingleThreadScheduledExecutor(threadFactory) + .scheduleAtFixedRate(this::publish, + this.metricsPublisherConfig.step().toMillis(), + this.metricsPublisherConfig.step().toMillis(), + TimeUnit.MILLISECONDS); } private Metric toSummaryMetric(DistributionSummary summary) { @@ -221,6 +234,7 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements * */ private static final class MessageChannelPublisher implements Consumer { + private final MetersPublisherBinding metersPublisherBinding; MessageChannelPublisher(MetersPublisherBinding metersPublisherBinding) { @@ -230,8 +244,11 @@ class DefaultDestinationPublishingMeterRegistry extends MeterRegistry implements @Override public void accept(String metricData) { logger.trace(metricData); - Message message = MessageBuilder.withPayload(metricData).setHeader("STREAM_CLOUD_STREAM_VERSION", "2.x").build(); + Message message = MessageBuilder.withPayload(metricData) + .setHeader("STREAM_CLOUD_STREAM_VERSION", "2.x").build(); this.metersPublisherBinding.applicationMetrics().send(message); } + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DestinationPublishingMetricsAutoConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DestinationPublishingMetricsAutoConfiguration.java index 1880f5e47..bb859e957 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DestinationPublishingMetricsAutoConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/DestinationPublishingMetricsAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -40,22 +40,22 @@ import org.springframework.util.PatternMatchUtils; import org.springframework.util.StringUtils; /** - * * @author Oleg Zhurakousky - * * @since 2.0 */ @Configuration @AutoConfigureBefore(SimpleMetricsExportAutoConfiguration.class) @AutoConfigureAfter(MetricsAutoConfiguration.class) @ConditionalOnClass({ Binder.class, MetricsAutoConfiguration.class }) -@ConditionalOnProperty("spring.cloud.stream.bindings." + MetersPublisherBinding.APPLICATION_METRICS + ".destination") +@ConditionalOnProperty("spring.cloud.stream.bindings." + + MetersPublisherBinding.APPLICATION_METRICS + ".destination") @EnableConfigurationProperties(ApplicationMetricsProperties.class) public class DestinationPublishingMetricsAutoConfiguration { @Bean @ConditionalOnMissingBean - public MetricsPublisherConfig metricsPublisherConfig(ApplicationMetricsProperties metersPublisherProperties) { + public MetricsPublisherConfig metricsPublisherConfig( + ApplicationMetricsProperties metersPublisherProperties) { return new MetricsPublisherConfig(metersPublisherProperties); } @@ -65,10 +65,15 @@ public class DestinationPublishingMetricsAutoConfiguration { ApplicationMetricsProperties applicationMetricsProperties, MetersPublisherBinding publisherBinding, MetricsPublisherConfig metricsPublisherConfig, Clock clock) { - DefaultDestinationPublishingMeterRegistry registry = new DefaultDestinationPublishingMeterRegistry(applicationMetricsProperties, publisherBinding, metricsPublisherConfig, clock); + DefaultDestinationPublishingMeterRegistry registry = new DefaultDestinationPublishingMeterRegistry( + applicationMetricsProperties, publisherBinding, metricsPublisherConfig, + clock); if (StringUtils.hasText(applicationMetricsProperties.getMeterFilter())) { - registry.config().meterFilter(MeterFilter.denyUnless(id -> PatternMatchUtils.simpleMatch(applicationMetricsProperties.getMeterFilter(), id.getName()))); + registry.config() + .meterFilter(MeterFilter.denyUnless(id -> PatternMatchUtils + .simpleMatch(applicationMetricsProperties.getMeterFilter(), + id.getName()))); } return registry; } @@ -77,11 +82,16 @@ public class DestinationPublishingMetricsAutoConfiguration { public BeanFactoryPostProcessor metersPublisherBindingRegistrant() { return new BeanFactoryPostProcessor() { @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - RootBeanDefinition emitterBindingDefinition = new RootBeanDefinition(BindableProxyFactory.class); - emitterBindingDefinition.getConstructorArgumentValues().addGenericArgumentValue(MetersPublisherBinding.class); - ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(MetersPublisherBinding.class.getName(), emitterBindingDefinition); + public void postProcessBeanFactory( + ConfigurableListableBeanFactory beanFactory) throws BeansException { + RootBeanDefinition emitterBindingDefinition = new RootBeanDefinition( + BindableProxyFactory.class); + emitterBindingDefinition.getConstructorArgumentValues() + .addGenericArgumentValue(MetersPublisherBinding.class); + ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition( + MetersPublisherBinding.class.getName(), emitterBindingDefinition); } }; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetersPublisherBinding.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetersPublisherBinding.java index 30b909afe..3383cf05f 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetersPublisherBinding.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetersPublisherBinding.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -20,15 +20,20 @@ import org.springframework.cloud.stream.annotation.Output; import org.springframework.messaging.MessageChannel; /** - * * @author Oleg Zhurakousky - * * @since 2.0 */ public interface MetersPublisherBinding { + /** + * Application metrics channel name. + */ String APPLICATION_METRICS = "applicationMetrics"; + /** + * @return Channel for application metrics. + */ @Output(APPLICATION_METRICS) MessageChannel applicationMetrics(); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/Metric.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/Metric.java index 7d82bf80b..2fb6a5ee6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/Metric.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/Metric.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.distribution.HistogramSnapshot; @@ -29,10 +28,9 @@ import io.micrometer.core.instrument.distribution.HistogramSnapshot; * Immutable class that wraps the micrometer's {@link HistogramSnapshot}. * * @param the value of type {@link Number} - * * @author Oleg Zhurakousky */ -@JsonPropertyOrder({ "id", "timestamp", "sum", "count", "mean", "upper", "total"}) +@JsonPropertyOrder({ "id", "timestamp", "sum", "count", "mean", "upper", "total" }) class Metric { private final Date timestamp; @@ -49,7 +47,6 @@ class Metric { private final Number total; - /** * Create a new {@link Metric} instance. * @param id Meter id @@ -75,33 +72,30 @@ class Metric { } public Number getSum() { - return sum; + return this.sum; } public Number getCount() { - return count; + return this.count; } public Number getMean() { - return mean; + return this.mean; } public Number getUpper() { - return upper; + return this.upper; } public Number getTotal() { - return total; + return this.total; } @Override public String toString() { - return "Metric [id=" + this.id + - ", sum=" + this.sum + - ", count=" + this.count + - ", mean=" + this.mean + - ", upper=" + this.upper + - ", total=" + this.total + - ", timestamp=" + this.timestamp + "]"; + return "Metric [id=" + this.id + ", sum=" + this.sum + ", count=" + this.count + + ", mean=" + this.mean + ", upper=" + this.upper + ", total=" + + this.total + ", timestamp=" + this.timestamp + "]"; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetricsPublisherConfig.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetricsPublisherConfig.java index 8d77edabc..214daf04e 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetricsPublisherConfig.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/micrometer/MetricsPublisherConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -19,9 +19,7 @@ package org.springframework.cloud.stream.micrometer; import io.micrometer.core.instrument.step.StepRegistryConfig; /** - * * @author Oleg Zhurakousky - * * @since 2.0 * */ @@ -46,4 +44,5 @@ class MetricsPublisherConfig implements StepRegistryConfig { } return value; } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ConsumerDestination.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ConsumerDestination.java index b776f7d79..2f34581ff 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ConsumerDestination.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ConsumerDestination.java @@ -21,17 +21,15 @@ import org.springframework.cloud.stream.binder.ConsumerProperties; /** * Represents a ConsumerDestination that provides the information about the destination * that is physically provisioned through - * {@link ProvisioningProvider#provisionConsumerDestination(String, String, ConsumerProperties)} + * {@link ProvisioningProvider#provisionConsumerDestination(String, String, ConsumerProperties)}. * * @author Soby Chacko - * * @since 1.2 */ public interface ConsumerDestination { /** * Provides the destination name. - * * @return destination name */ String getName(); diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProducerDestination.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProducerDestination.java index e0f411d55..06b70b345 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProducerDestination.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProducerDestination.java @@ -21,17 +21,15 @@ import org.springframework.cloud.stream.binder.ProducerProperties; /** * Represents a ProducerDestination that provides the information about the destination * that is physically provisioned through - * {@link ProvisioningProvider#provisionProducerDestination(String, ProducerProperties)} + * {@link ProvisioningProvider#provisionProducerDestination(String, ProducerProperties)}. * * @author Soby Chacko - * * @since 1.2 */ public interface ProducerDestination { /** * Provides the destination name. - * * @return destination name */ String getName(); @@ -49,9 +47,9 @@ public interface ProducerDestination { * On certain brokers (for instance, Kafka), this behavior is completely skipped and * there is a one-to-one correspondence between the destination name in the * provisioner and the physical destination on the broker. - * * @param partition the partition to find destination for * @return destination name for the given partition */ String getNameForPartition(int partition); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningException.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningException.java index a5e8c5bb7..6fc2d05b2 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningException.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningException.java @@ -46,4 +46,5 @@ public class ProvisioningException extends NestedRuntimeException { public ProvisioningException(String msg, Throwable cause) { super(msg, cause); } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningProvider.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningProvider.java index eebc9c204..825b16a6b 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningProvider.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/provisioning/ProvisioningProvider.java @@ -33,9 +33,7 @@ import org.springframework.cloud.stream.binder.ProducerProperties; * * @param the consumer properties type * @param

the producer properties type - * * @author Soby Chacko - * * @since 1.2 */ public interface ProvisioningProvider { @@ -43,25 +41,24 @@ public interface ProvisioningProvider - * {@code + *

 {@code
 	 * class MessageChannelBinder implements Binder
-	 * }
+	 * } 
* - *
-	 * {@code
+	 * 
 {@code
 	 * getParameterType(MessageChannelBinder.class, Binder.class, 0);
-	 * }
+	 * } 
* * will return {@code Binder} - * * @param evaluatedClass the evaluated class * @param interfaceClass the parametrized interface * @param position the position @@ -60,11 +57,14 @@ public final class GenericsUtils { * @throws IllegalStateException if the evaluated class does not implement the * interface or */ - public static Class getParameterType(Class evaluatedClass, Class interfaceClass, int position) { + public static Class getParameterType(Class evaluatedClass, + Class interfaceClass, int position) { Class bindableType = null; - Assert.isTrue(interfaceClass.isInterface(), "'interfaceClass' must be an interface"); + Assert.isTrue(interfaceClass.isInterface(), + "'interfaceClass' must be an interface"); if (!interfaceClass.isAssignableFrom(evaluatedClass)) { - throw new IllegalStateException(evaluatedClass + " does not implement " + interfaceClass); + throw new IllegalStateException( + evaluatedClass + " does not implement " + interfaceClass); } ResolvableType currentType = ResolvableType.forType(evaluatedClass); while (!Object.class.equals(currentType.getRawClass()) && bindableType == null) { @@ -92,30 +92,31 @@ public final class GenericsUtils { } } if (bindableType == null) { - throw new IllegalStateException("Cannot find parameter of " + evaluatedClass.getName() + " for " - + interfaceClass + " at position " + position); + throw new IllegalStateException( + "Cannot find parameter of " + evaluatedClass.getName() + " for " + + interfaceClass + " at position " + position); } return bindableType; } /** - * Return the generic type of PollableSource to determine if it is appropriate - * for the binder. - * e.g., with PollableMessageSource extends PollableSource - * and AbstractMessageChannelBinder - * implements PollableConsumerBinder - * We're checking that the the generic type (MessageHandler) matches. - * + * Return the generic type of PollableSource to determine if it is appropriate for the + * binder. e.g., with PollableMessageSource extends + * PollableSource<MessageHandler> and AbstractMessageChannelBinder implements + * PollableConsumerBinder<MessageHandler, C> We're checking that the the generic + * type (MessageHandler) matches. * @param binderInstance the binder. * @param bindingTargetType the binding target type. * @return true if found, false otherwise. */ @SuppressWarnings("rawtypes") - public static boolean checkCompatiblePollableBinder(Binder binderInstance, Class bindingTargetType) { + public static boolean checkCompatiblePollableBinder(Binder binderInstance, + Class bindingTargetType) { Class[] binderInterfaces = ClassUtils.getAllInterfaces(binderInstance); for (Class intf : binderInterfaces) { if (PollableConsumerBinder.class.isAssignableFrom(intf)) { - Class[] targetInterfaces = ClassUtils.getAllInterfacesForClass(bindingTargetType); + Class[] targetInterfaces = ClassUtils + .getAllInterfacesForClass(bindingTargetType); Class psType = findPollableSourceType(targetInterfaces); if (psType != null) { return getParameterType(binderInstance.getClass(), intf, 0) diff --git a/spring-cloud-stream/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-stream/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 7c7bb1897..f2ee4de23 100644 --- a/spring-cloud-stream/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-stream/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,16 +1,16 @@ { - "properties": [ - { - "defaultValue": "false", - "name": "spring.cloud.stream.override-cloud-connectors", - "description": "This property is only applicable when the cloud profile is active and Spring Cloud Connectors are provided with the application. If the property is false (the default), the binder detects a suitable bound service (for example, a RabbitMQ service bound in Cloud Foundry for the RabbitMQ binder) and uses it for creating connections (usually through Spring Cloud Connectors). When set to true, this property instructs binders to completely ignore the bound services and rely on Spring Boot properties (for example, relying on the spring.rabbitmq.* properties provided in the environment for the RabbitMQ binder). The typical usage of this property is to be nested in a customized environment when connecting to multiple systems.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": "true", - "name": "management.health.binders.enabled", - "description": "Allows to enable/disable binder's' health indicators. If you want to disable health indicator completely, then set it to `false`.", - "type": "java.lang.Boolean" - } - ] + "properties": [ + { + "defaultValue": "false", + "name": "spring.cloud.stream.override-cloud-connectors", + "description": "This property is only applicable when the cloud profile is active and Spring Cloud Connectors are provided with the application. If the property is false (the default), the binder detects a suitable bound service (for example, a RabbitMQ service bound in Cloud Foundry for the RabbitMQ binder) and uses it for creating connections (usually through Spring Cloud Connectors). When set to true, this property instructs binders to completely ignore the bound services and rely on Spring Boot properties (for example, relying on the spring.rabbitmq.* properties provided in the environment for the RabbitMQ binder). The typical usage of this property is to be nested in a customized environment when connecting to multiple systems.", + "type": "java.lang.Boolean" + }, + { + "defaultValue": "true", + "name": "management.health.binders.enabled", + "description": "Allows to enable/disable binder's' health indicators. If you want to disable health indicator completely, then set it to `false`.", + "type": "java.lang.Boolean" + } + ] } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/aggregation/AggregationTest.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/aggregation/AggregationTest.java index ef52364c3..47ea9eeab 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/aggregation/AggregationTest.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/aggregation/AggregationTest.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import org.junit.After; -import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -47,7 +46,7 @@ import org.springframework.messaging.MessageChannel; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.fail; /** * @author Marius Bogoevici @@ -68,40 +67,38 @@ public class AggregationTest { System.clearProperty("c.fooValue"); System.clearProperty("a.foo.value"); System.clearProperty("c.foo.value"); - if (aggregatedApplicationContext != null) { - aggregatedApplicationContext.close(); + if (this.aggregatedApplicationContext != null) { + this.aggregatedApplicationContext.close(); } } @Test public void aggregation() { - aggregatedApplicationContext = new AggregateApplicationBuilder( - AggregationAppConfig.class, - "--spring.cloud.stream.default-binder=mock") - .web(false).from(TestSource.class).to(TestProcessor.class).run(); - SharedBindingTargetRegistry sharedBindingTargetRegistry = aggregatedApplicationContext + this.aggregatedApplicationContext = new AggregateApplicationBuilder( + AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock") + .web(false).from(TestSource.class).to(TestProcessor.class).run(); + SharedBindingTargetRegistry sharedBindingTargetRegistry = this.aggregatedApplicationContext .getBean(SharedBindingTargetRegistry.class); - BindingTargetFactory channelFactory = aggregatedApplicationContext + BindingTargetFactory channelFactory = this.aggregatedApplicationContext .getBean(SubscribableChannelBindingTargetFactory.class); assertThat(channelFactory).isNotNull(); assertThat(sharedBindingTargetRegistry.getAll().keySet()).hasSize(2); - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test public void testModuleAggregationUsingSharedChannelRegistry() { // test backward compatibility - aggregatedApplicationContext = new AggregateApplicationBuilder( - AggregationAppConfig.class, - "--spring.cloud.stream.default-binder=mock").web(false) - .from(TestSource.class).to(TestProcessor.class).run(); - SharedBindingTargetRegistry sharedChannelRegistry = aggregatedApplicationContext + this.aggregatedApplicationContext = new AggregateApplicationBuilder( + AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock") + .web(false).from(TestSource.class).to(TestProcessor.class).run(); + SharedBindingTargetRegistry sharedChannelRegistry = this.aggregatedApplicationContext .getBean(SharedBindingTargetRegistry.class); - BindingTargetFactory channelFactory = aggregatedApplicationContext + BindingTargetFactory channelFactory = this.aggregatedApplicationContext .getBean(SubscribableChannelBindingTargetFactory.class); assertThat(channelFactory).isNotNull(); assertThat(sharedChannelRegistry.getAll().keySet()).hasSize(2); - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test @@ -118,8 +115,8 @@ public class AggregationTest { final ConfigurableApplicationContext context = aggregateApplicationBuilder .parent(DummyConfig.class, "--foo2=bar2").web(false) .from(TestSource.class).namespace("foo").to(TestProcessor.class) - .namespace("bar").run("--foo3=bar3", - "--spring.cloud.stream.default-binder=mock"); + .namespace("bar") + .run("--foo3=bar3", "--spring.cloud.stream.default-binder=mock"); DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor( aggregateApplicationBuilder); final List parentArgs = (List) aggregateApplicationBuilderAccessor @@ -154,28 +151,31 @@ public class AggregationTest { public void testNamespacePrefixesFromCmdLine() { AggregateApplicationBuilder aggregateApplicationBuilder = new AggregateApplicationBuilder( AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock"); - aggregatedApplicationContext = aggregateApplicationBuilder + this.aggregatedApplicationContext = aggregateApplicationBuilder .parent(DummyConfig.class).web(false).from(TestSource.class) .namespace("a").via(TestProcessor.class).namespace("b") .via(TestProcessor.class).namespace("c") .run("--a.foo1=bar1", "--b.foo1=bar2", "--c.foo1=bar3"); DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor( aggregateApplicationBuilder); - assertTrue(Arrays.asList(((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer")).getArgs()) - .contains("--foo1=bar1")); - final List processorConfigurers = (List) aggregateApplicationBuilderAccessor + assertThat(Arrays + .asList(((SourceConfigurer) aggregateApplicationBuilderAccessor + .getPropertyValue("sourceConfigurer")).getArgs()) + .contains("--foo1=bar1")).isTrue(); + final List processorConfigurers; + processorConfigurers = (List) aggregateApplicationBuilderAccessor .getPropertyValue("processorConfigurers"); for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : processorConfigurers) { if (processorConfigurer.getNamespace().equals("b")) { - assertTrue(Arrays.equals(processorConfigurer.getArgs(), - new String[]{"--foo1=bar2"})); + assertThat(Arrays.equals(processorConfigurer.getArgs(), + new String[] { "--foo1=bar2" })).isTrue(); } if (processorConfigurer.getNamespace().equals("c")) { - assertTrue(Arrays.asList(processorConfigurer.getArgs()) - .contains("--foo1=bar3")); + assertThat(Arrays.asList(processorConfigurer.getArgs()) + .contains("--foo1=bar3")).isTrue(); } } - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test @@ -183,28 +183,33 @@ public class AggregationTest { public void testNamespacePrefixesFromCmdLineVsArgs() { AggregateApplicationBuilder aggregateApplicationBuilder = new AggregateApplicationBuilder( AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock"); - aggregatedApplicationContext = aggregateApplicationBuilder + this.aggregatedApplicationContext = aggregateApplicationBuilder .parent(DummyConfig.class).web(false).from(TestSource.class) .namespace("a").args("--fooValue=bar").via(TestProcessor.class) .namespace("b").args("--foo1=argbarb").via(TestProcessor.class) .namespace("c").run("--a.fooValue=bara", "--c.foo1=barc"); DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor( aggregateApplicationBuilder); - assertTrue(Arrays.asList(((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer")).getArgs()) - .contains("--fooValue=bara")); - final List processorConfigurers = (List) aggregateApplicationBuilderAccessor + assertThat(Arrays + .asList(((SourceConfigurer) aggregateApplicationBuilderAccessor + .getPropertyValue("sourceConfigurer")).getArgs()) + .contains("--fooValue=bara")).isTrue(); + final List processorConfigurers; + processorConfigurers = (List) aggregateApplicationBuilderAccessor .getPropertyValue("processorConfigurers"); for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : processorConfigurers) { if (processorConfigurer.getNamespace().equals("b")) { - assertTrue(Arrays.equals(processorConfigurer.getArgs(), - new String[]{"--foo1=argbarb"})); + assertThat(Arrays.equals(processorConfigurer.getArgs(), + new String[] { "--foo1=argbarb" })).isTrue(); } if (processorConfigurer.getNamespace().equals("c")) { - assertTrue(Arrays.asList(((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer")).getArgs()) - .contains("--fooValue=bara")); + assertThat(Arrays + .asList(((SourceConfigurer) aggregateApplicationBuilderAccessor + .getPropertyValue("sourceConfigurer")).getArgs()) + .contains("--fooValue=bara")).isTrue(); } } - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test @@ -212,7 +217,7 @@ public class AggregationTest { public void testNamespacePrefixesFromCmdLineWithRelaxedNames() { AggregateApplicationBuilder aggregateApplicationBuilder = new AggregateApplicationBuilder( AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock"); - aggregatedApplicationContext = aggregateApplicationBuilder + this.aggregatedApplicationContext = aggregateApplicationBuilder .parent(DummyConfig.class).web(false).from(TestSource.class) .namespace("a").args("--foo-value=bar").via(TestProcessor.class) .namespace("b").args("--fooValue=argbarb").via(TestProcessor.class) @@ -220,21 +225,24 @@ public class AggregationTest { .run("--a.fooValue=bara", "--b.foo-value=barb", "--c.foo1=barc"); DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor( aggregateApplicationBuilder); - assertTrue(Arrays.asList(((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer")).getArgs()) - .contains("--fooValue=bara")); - final List processorConfigurers = (List) aggregateApplicationBuilderAccessor + assertThat(Arrays + .asList(((SourceConfigurer) aggregateApplicationBuilderAccessor + .getPropertyValue("sourceConfigurer")).getArgs()) + .contains("--fooValue=bara")).isTrue(); + final List processorConfigurers; + processorConfigurers = (List) aggregateApplicationBuilderAccessor .getPropertyValue("processorConfigurers"); for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : processorConfigurers) { if (processorConfigurer.getNamespace().equals("b")) { - assertTrue(Arrays.equals(processorConfigurer.getArgs(), - new String[]{"--foo-value=barb"})); + assertThat(Arrays.equals(processorConfigurer.getArgs(), + new String[] { "--foo-value=barb" })).isTrue(); } if (processorConfigurer.getNamespace().equals("c")) { - assertTrue(Arrays.asList(processorConfigurer.getArgs()) - .contains("--foo1=barc")); + assertThat(Arrays.asList(processorConfigurer.getArgs()) + .contains("--foo1=barc")).isTrue(); } } - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test @@ -244,30 +252,33 @@ public class AggregationTest { AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock"); System.setProperty("a.foo-value", "sysbara"); System.setProperty("c.fooValue", "sysbarc"); - aggregatedApplicationContext = aggregateApplicationBuilder + this.aggregatedApplicationContext = aggregateApplicationBuilder .parent(DummyConfig.class).web(false).from(TestSource.class) .namespace("a").args("--foo-value=bar").via(TestProcessor.class) .namespace("b").args("--fooValue=argbarb").via(TestProcessor.class) .namespace("c").args("--foo-value=argbarc").run("--a.fooValue=bara"); DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor( aggregateApplicationBuilder); - assertTrue(Arrays.asList(((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer")).getArgs()) - .contains("--fooValue=bara")); - assertTrue(Arrays.asList(((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer")).getArgs()) - .contains("--foo-value=bara")); - final List processorConfigurers = (List) aggregateApplicationBuilderAccessor + SourceConfigurer sourceConfigurer = (SourceConfigurer) aggregateApplicationBuilderAccessor + .getPropertyValue("sourceConfigurer"); + assertThat(Arrays.asList(sourceConfigurer.getArgs()).contains("--fooValue=bara")) + .isTrue(); + assertThat(Arrays.asList(sourceConfigurer.getArgs()).contains("--foo-value=bara")) + .isTrue(); + final List processorConfigurers; + processorConfigurers = (List) aggregateApplicationBuilderAccessor .getPropertyValue("processorConfigurers"); for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : processorConfigurers) { if (processorConfigurer.getNamespace().equals("b")) { - assertTrue(Arrays.equals(processorConfigurer.getArgs(), - new String[]{"--fooValue=argbarb"})); + assertThat(Arrays.equals(processorConfigurer.getArgs(), + new String[] { "--fooValue=argbarb" })).isTrue(); } if (processorConfigurer.getNamespace().equals("c")) { - assertTrue(Arrays.asList(processorConfigurer.getArgs()) - .contains("--fooValue=sysbarc")); + assertThat(Arrays.asList(processorConfigurer.getArgs()) + .contains("--fooValue=sysbarc")).isTrue(); } } - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test @@ -277,28 +288,32 @@ public class AggregationTest { AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock"); System.setProperty("a.foo-value", "sysbara"); System.setProperty("c.fooValue", "sysbarc"); - aggregatedApplicationContext = aggregateApplicationBuilder + this.aggregatedApplicationContext = aggregateApplicationBuilder .parent(DummyConfig.class).web(false).from(TestSource.class) .namespace("a").args("--foo-value=bar").via(TestProcessor.class) .namespace("b").args("--fooValue=argbarb").via(TestProcessor.class) .namespace("c").args("--foo-value=argbarc").run(); DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor( aggregateApplicationBuilder); - - assertTrue(Arrays.asList(((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer")).getArgs()) - .contains("--foo-value=sysbara")); - for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : ((List) aggregateApplicationBuilderAccessor - .getPropertyValue("processorConfigurers"))) { + SourceConfigurer sourceConfigurer = (SourceConfigurer) aggregateApplicationBuilderAccessor + .getPropertyValue("sourceConfigurer"); + assertThat( + Arrays.asList(sourceConfigurer.getArgs()).contains("--foo-value=sysbara")) + .isTrue(); + List configurers; + configurers = (List) aggregateApplicationBuilderAccessor + .getPropertyValue("processorConfigurers"); + for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : configurers) { if (processorConfigurer.getNamespace().equals("b")) { - assertTrue(Arrays.equals(processorConfigurer.getArgs(), - new String[]{"--fooValue=argbarb"})); + assertThat(Arrays.equals(processorConfigurer.getArgs(), + new String[] { "--fooValue=argbarb" })).isTrue(); } if (processorConfigurer.getNamespace().equals("c")) { - assertTrue(Arrays.asList(processorConfigurer.getArgs()) - .contains("--fooValue=sysbarc")); + assertThat(Arrays.asList(processorConfigurer.getArgs()) + .contains("--fooValue=sysbarc")).isTrue(); } } - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test @@ -308,40 +323,41 @@ public class AggregationTest { AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock"); System.setProperty("a.fooValue", "sysbara"); System.setProperty("c.fooValue", "sysbarc"); - aggregatedApplicationContext = aggregateApplicationBuilder + this.aggregatedApplicationContext = aggregateApplicationBuilder .parent(DummyConfig.class).web(false).from(TestSource.class) .namespace("a").args("--foo-value=bar").via(TestProcessor.class) .namespace("b").args("--fooValue=argbarb").via(TestProcessor.class) .namespace("c").args("--foo-value=argbarc").run("--a.fooValue=highest"); DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor( aggregateApplicationBuilder); - assertThat(((SourceConfigurer) aggregateApplicationBuilderAccessor - .getPropertyValue("sourceConfigurer")).getArgs()) - .contains(new String[]{"--fooValue=highest"}); - final List processorConfigurers = (List) aggregateApplicationBuilderAccessor + String[] configurers = ((SourceConfigurer) aggregateApplicationBuilderAccessor + .getPropertyValue("sourceConfigurer")).getArgs(); + assertThat(configurers).contains(new String[] { "--fooValue=highest" }); + final List processorConfigurers; + processorConfigurers = (List) aggregateApplicationBuilderAccessor .getPropertyValue("processorConfigurers"); for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : processorConfigurers) { if (processorConfigurer.getNamespace().equals("b")) { - assertTrue(Arrays.equals(processorConfigurer.getArgs(), - new String[]{"--fooValue=argbarb"})); + assertThat(Arrays.equals(processorConfigurer.getArgs(), + new String[] { "--fooValue=argbarb" })).isTrue(); } if (processorConfigurer.getNamespace().equals("c")) { - assertTrue(Arrays.asList(processorConfigurer.getArgs()) - .contains("--fooValue=sysbarc")); + assertThat(Arrays.asList(processorConfigurer.getArgs()) + .contains("--fooValue=sysbarc")).isTrue(); } } - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test public void testNamespaces() { - aggregatedApplicationContext = new AggregateApplicationBuilder( - AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock").web(false) - .from(TestSource.class).namespace("foo").to(TestProcessor.class) - .namespace("bar").run(); - SharedBindingTargetRegistry sharedChannelRegistry = aggregatedApplicationContext + this.aggregatedApplicationContext = new AggregateApplicationBuilder( + AggregationAppConfig.class, "--spring.cloud.stream.default-binder=mock") + .web(false).from(TestSource.class).namespace("foo") + .to(TestProcessor.class).namespace("bar").run(); + SharedBindingTargetRegistry sharedChannelRegistry = this.aggregatedApplicationContext .getBean(SharedBindingTargetRegistry.class); - BindingTargetFactory channelFactory = aggregatedApplicationContext + BindingTargetFactory channelFactory = this.aggregatedApplicationContext .getBean(SubscribableChannelBindingTargetFactory.class); MessageChannel fooOutput = sharedChannelRegistry.get("foo.output", MessageChannel.class); @@ -350,15 +366,14 @@ public class AggregationTest { assertThat(barInput).isNotNull(); assertThat(channelFactory).isNotNull(); assertThat(sharedChannelRegistry.getAll().keySet()).hasSize(2); - aggregatedApplicationContext.close(); + this.aggregatedApplicationContext.close(); } @Test public void testBindableProxyFactoryCaching() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestSource2.class, - TestProcessor.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.default-binder=mock"); + ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestSource2.class, TestProcessor.class).web(WebApplicationType.NONE) + .run("--spring.cloud.stream.default-binder=mock"); Map factories = context .getBeansOfType(BindableProxyFactory.class); @@ -393,15 +408,24 @@ public class AggregationTest { } if (factory.getObjectType() == FooSource.class) { assertThat(targetCache).hasSize(1); - } else if (factory.getObjectType() == Processor.class) { + } + else if (factory.getObjectType() == Processor.class) { assertThat(targetCache).hasSize(2); - } else { - Assert.fail("Found unexpected type"); + } + else { + fail("Found unexpected type"); } } context.close(); } + public interface FooSource { + + @Output("fooOutput") + MessageChannel output(); + + } + @EnableBinding(Source.class) @EnableAutoConfiguration public static class TestSource { @@ -414,13 +438,6 @@ public class AggregationTest { } - public interface FooSource { - - @Output("fooOutput") - MessageChannel output(); - - } - @EnableBinding(FooSource.class) @EnableAutoConfiguration public static class TestSource2 { @@ -437,4 +454,5 @@ public class AggregationTest { public static class AggregationAppConfig { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java index a73fd0ba9..b95c5df42 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -39,15 +39,11 @@ import org.springframework.messaging.MessageHandler; import org.springframework.messaging.SubscribableChannel; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; /** * @author Marius Bogoevici * @author Gary Russell * @author Oleg Zhurakousky - * * @since 1.2.2 */ public class AbstractMessageChannelBinderTests { @@ -56,71 +52,87 @@ public class AbstractMessageChannelBinderTests { @Before public void prepare() { - this.context = new SpringApplicationBuilder(TestChannelBinderConfiguration.getCompleteConfiguration()) - .web(WebApplicationType.NONE) - .run(); + this.context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration()) + .web(WebApplicationType.NONE).run(); } @Test @SuppressWarnings("unchecked") public void testEndpointLifecycle() throws Exception { - AbstractMessageChannelBinder> binder = - context.getBean(AbstractMessageChannelBinder.class); + // @checkstyle:off + AbstractMessageChannelBinder> binder = this.context + .getBean(AbstractMessageChannelBinder.class); + // @checkstyle:on ConsumerProperties consumerProperties = new ConsumerProperties(); consumerProperties.setMaxAttempts(1); // to force error infrastructure creation - Binding consumerBinding = binder.bindConsumer("foo", "fooGroup", new DirectChannel(), consumerProperties); - DirectFieldAccessor consumerBindingAccessor = new DirectFieldAccessor(consumerBinding); - MessageProducer messageProducer = (MessageProducer) consumerBindingAccessor.getPropertyValue("lifecycle"); - assertTrue(((Lifecycle)messageProducer).isRunning()); - assertNotNull(messageProducer.getOutputChannel()); + Binding consumerBinding = binder.bindConsumer("foo", "fooGroup", + new DirectChannel(), consumerProperties); + DirectFieldAccessor consumerBindingAccessor = new DirectFieldAccessor( + consumerBinding); + MessageProducer messageProducer = (MessageProducer) consumerBindingAccessor + .getPropertyValue("lifecycle"); + assertThat(((Lifecycle) messageProducer).isRunning()).isTrue(); + assertThat(messageProducer.getOutputChannel()).isNotNull(); - SubscribableChannel errorChannel = (SubscribableChannel) consumerBindingAccessor.getPropertyValue("lifecycle.errorChannel"); + SubscribableChannel errorChannel = (SubscribableChannel) consumerBindingAccessor + .getPropertyValue("lifecycle.errorChannel"); assertThat(errorChannel).isNotNull(); - Set handlers = TestUtils.getPropertyValue(errorChannel, "dispatcher.handlers", Set.class); + Set handlers = TestUtils.getPropertyValue(errorChannel, + "dispatcher.handlers", Set.class); assertThat(handlers.size()).isEqualTo(2); Iterator iterator = handlers.iterator(); assertThat(iterator.next()).isInstanceOf(BridgeHandler.class); assertThat(iterator.next()).isInstanceOf(LastSubscriberMessageHandler.class); - assertThat(context.containsBean("foo.fooGroup.errors")).isTrue(); - assertThat(context.containsBean("foo.fooGroup.errors.recoverer")).isTrue(); - assertThat(context.containsBean("foo.fooGroup.errors.handler")).isTrue(); - assertThat(context.containsBean("foo.fooGroup.errors.bridge")).isTrue(); + assertThat(this.context.containsBean("foo.fooGroup.errors")).isTrue(); + assertThat(this.context.containsBean("foo.fooGroup.errors.recoverer")).isTrue(); + assertThat(this.context.containsBean("foo.fooGroup.errors.handler")).isTrue(); + assertThat(this.context.containsBean("foo.fooGroup.errors.bridge")).isTrue(); consumerBinding.unbind(); - assertThat(context.containsBean("foo.fooGroup.errors")).isFalse(); - assertThat(context.containsBean("foo.fooGroup.errors.recoverer")).isFalse(); - assertThat(context.containsBean("foo.fooGroup.errors.handler")).isFalse(); - assertThat(context.containsBean("foo.fooGroup.errors.bridge")).isFalse(); + assertThat(this.context.containsBean("foo.fooGroup.errors")).isFalse(); + assertThat(this.context.containsBean("foo.fooGroup.errors.recoverer")).isFalse(); + assertThat(this.context.containsBean("foo.fooGroup.errors.handler")).isFalse(); + assertThat(this.context.containsBean("foo.fooGroup.errors.bridge")).isFalse(); - assertFalse(((Lifecycle) messageProducer).isRunning()); + assertThat(((Lifecycle) messageProducer).isRunning()).isFalse(); ProducerProperties producerProps = new ProducerProperties(); producerProps.setErrorChannelEnabled(true); - Binding producerBinding = binder.bindProducer("bar", new DirectChannel(), producerProps); - assertThat(context.containsBean("bar.errors")).isTrue(); - assertThat(context.containsBean("bar.errors.bridge")).isTrue(); + Binding producerBinding = binder.bindProducer("bar", + new DirectChannel(), producerProps); + assertThat(this.context.containsBean("bar.errors")).isTrue(); + assertThat(this.context.containsBean("bar.errors.bridge")).isTrue(); producerBinding.unbind(); - assertThat(context.containsBean("bar.errors")).isFalse(); - assertThat(context.containsBean("bar.errors.bridge")).isFalse(); + assertThat(this.context.containsBean("bar.errors")).isFalse(); + assertThat(this.context.containsBean("bar.errors.bridge")).isFalse(); } @Test @SuppressWarnings("unchecked") public void testEndpointBinderHasRecoverer() throws Exception { - ConfigurableApplicationContext context = - new SpringApplicationBuilder(TestChannelBinderConfiguration.getCompleteConfiguration()).web(WebApplicationType.NONE).run(); + // @checkstyle:off + ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration()) + .web(WebApplicationType.NONE).run(); - AbstractMessageChannelBinder> binder = - context.getBean(AbstractMessageChannelBinder.class); + AbstractMessageChannelBinder> binder = context + .getBean(AbstractMessageChannelBinder.class); + // @checkstyle:on - Binding consumerBinding = binder.bindConsumer("foo", "fooGroup", new DirectChannel(), new ConsumerProperties()); - DirectFieldAccessor consumerBindingAccessor = new DirectFieldAccessor(consumerBinding); - SubscribableChannel errorChannel = (SubscribableChannel) consumerBindingAccessor.getPropertyValue("lifecycle.errorChannel"); + Binding consumerBinding = binder.bindConsumer("foo", "fooGroup", + new DirectChannel(), new ConsumerProperties()); + DirectFieldAccessor consumerBindingAccessor = new DirectFieldAccessor( + consumerBinding); + SubscribableChannel errorChannel = (SubscribableChannel) consumerBindingAccessor + .getPropertyValue("lifecycle.errorChannel"); assertThat(errorChannel).isNull(); - errorChannel = (SubscribableChannel) consumerBindingAccessor.getPropertyValue("lifecycle.recoveryCallback.channel"); + errorChannel = (SubscribableChannel) consumerBindingAccessor + .getPropertyValue("lifecycle.recoveryCallback.channel"); assertThat(errorChannel).isNotNull(); - Set handlers = TestUtils.getPropertyValue(errorChannel, "dispatcher.handlers", Set.class); + Set handlers = TestUtils.getPropertyValue(errorChannel, + "dispatcher.handlers", Set.class); assertThat(handlers.size()).isEqualTo(2); Iterator iterator = handlers.iterator(); assertThat(iterator.next()).isInstanceOf(BridgeHandler.class); @@ -135,4 +147,5 @@ public class AbstractMessageChannelBinderTests { assertThat(context.containsBean("foo.fooGroup.errors.handler")).isFalse(); assertThat(context.containsBean("foo.fooGroup.errors.bridge")).isFalse(); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithBindingTargetsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithBindingTargetsTests.java index 4d64fe0c5..22e25c0b3 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithBindingTargetsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithBindingTargetsTests.java @@ -37,25 +37,27 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Marius Bogoevici * @author Janne Valkealahti */ +// @checkstyle:off @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = ArbitraryInterfaceWithBindingTargetsTests.TestFooChannels.class, - properties = "spring.cloud.stream.default-binder=mock") +@SpringBootTest(classes = ArbitraryInterfaceWithBindingTargetsTests.TestFooChannels.class, properties = "spring.cloud.stream.default-binder=mock") public class ArbitraryInterfaceWithBindingTargetsTests { + // @checkstyle:on + @Autowired public FooChannels fooChannels; @Autowired private BinderFactory binderFactory; - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testArbitraryInterfaceChannelsBound() { - Binder binder = binderFactory.getBinder(null, MessageChannel.class); - verify(binder).bindConsumer(eq("someQueue.0"), isNull(), eq(this.fooChannels.foo()), - Mockito.any()); - verify(binder).bindConsumer(eq("someQueue.1"), isNull(), eq(this.fooChannels.bar()), - Mockito.any()); + Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); + verify(binder).bindConsumer(eq("someQueue.0"), isNull(), + eq(this.fooChannels.foo()), Mockito.any()); + verify(binder).bindConsumer(eq("someQueue.1"), isNull(), + eq(this.fooChannels.bar()), Mockito.any()); verify(binder).bindProducer(eq("someQueue.2"), eq(this.fooChannels.baz()), Mockito.any()); verify(binder).bindProducer(eq("someQueue.3"), eq(this.fooChannels.qux()), diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithDefaultsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithDefaultsTests.java index 1d3eb6f81..4c9b2d998 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithDefaultsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ArbitraryInterfaceWithDefaultsTests.java @@ -36,18 +36,20 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Marius Bogoevici * @author Janne Valkealahti */ +// @checkstyle:off @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = ArbitraryInterfaceWithDefaultsTests.TestFooChannels.class, - properties = "spring.cloud.stream.default-binder=mock") +@SpringBootTest(classes = ArbitraryInterfaceWithDefaultsTests.TestFooChannels.class, properties = "spring.cloud.stream.default-binder=mock") public class ArbitraryInterfaceWithDefaultsTests { + // @checkstyle:on + @Autowired public FooChannels fooChannels; @Autowired private BinderFactory binderFactory; - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testArbitraryInterfaceChannelsBound() { final Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); @@ -55,10 +57,8 @@ public class ArbitraryInterfaceWithDefaultsTests { Mockito.any()); verify(binder).bindConsumer(eq("bar"), isNull(), eq(this.fooChannels.bar()), Mockito.any()); - verify(binder).bindProducer(eq("baz"), eq(this.fooChannels.baz()), - Mockito.any()); - verify(binder).bindProducer(eq("qux"), eq(this.fooChannels.qux()), - Mockito.any()); + verify(binder).bindProducer(eq("baz"), eq(this.fooChannels.baz()), Mockito.any()); + verify(binder).bindProducer(eq("qux"), eq(this.fooChannels.qux()), Mockito.any()); verifyNoMoreInteractions(binder); } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderAwareChannelResolverTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderAwareChannelResolverTests.java index 8ee46b59e..24b2a95b0 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderAwareChannelResolverTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderAwareChannelResolverTests.java @@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit; import org.junit.Before; import org.junit.Test; - import org.mockito.Mockito; import org.springframework.boot.WebApplicationType; @@ -54,9 +53,7 @@ import org.springframework.messaging.SubscribableChannel; import org.springframework.messaging.support.ImmutableMessageChannelInterceptor; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.matches; @@ -84,44 +81,42 @@ public class BinderAwareChannelResolverTests { protected volatile DynamicDestinationsBindable dynamicDestinationsBindable; - @Configuration - public static class InterceptorConfiguration { - @Bean - public GlobalChannelInterceptorWrapper testInterceptor() { - return new GlobalChannelInterceptorWrapper(new ImmutableMessageChannelInterceptor()); - } - } - @SuppressWarnings("unchecked") @Before public void setupContext() throws Exception { - this.context = new SpringApplicationBuilder(TestChannelBinderConfiguration.getCompleteConfiguration(BinderAwareChannelResolverTests.InterceptorConfiguration.class)) - .web(WebApplicationType.NONE).run(); + this.context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration( + BinderAwareChannelResolverTests.InterceptorConfiguration.class)) + .web(WebApplicationType.NONE).run(); - this.resolver = context.getBean(BinderAwareChannelResolver.class); - this.binder = context.getBean(Binder.class); - this.bindingServiceProperties = context.getBean(BindingServiceProperties.class); - this.bindingTargetFactory = context.getBean(SubscribableChannelBindingTargetFactory.class); + this.resolver = this.context.getBean(BinderAwareChannelResolver.class); + this.binder = this.context.getBean(Binder.class); + this.bindingServiceProperties = this.context + .getBean(BindingServiceProperties.class); + this.bindingTargetFactory = this.context + .getBean(SubscribableChannelBindingTargetFactory.class); } @Test public void resolveChannel() { - Map bindables = context.getBeansOfType(Bindable.class); + Map bindables = this.context.getBeansOfType(Bindable.class); assertThat(bindables).hasSize(1); for (Bindable bindable : bindables.values()) { - assertEquals(0, bindable.getInputs().size()); // producer - assertEquals(0, bindable.getOutputs().size());// consumer + assertThat(bindable.getInputs().size()).isEqualTo(0); // producer + assertThat(bindable.getOutputs().size()).isEqualTo(0); // consumer } - MessageChannel registered = resolver.resolveDestination("foo"); - assertEquals(2, ((AbstractMessageChannel)registered).getChannelInterceptors().size()); - assertTrue(((AbstractMessageChannel)registered).getChannelInterceptors().get(1) instanceof ImmutableMessageChannelInterceptor); + MessageChannel registered = this.resolver.resolveDestination("foo"); + assertThat(((AbstractMessageChannel) registered).getChannelInterceptors().size()) + .isEqualTo(2); + assertThat(((AbstractMessageChannel) registered).getChannelInterceptors() + .get(1) instanceof ImmutableMessageChannelInterceptor).isTrue(); - bindables = context.getBeansOfType(Bindable.class); + bindables = this.context.getBeansOfType(Bindable.class); assertThat(bindables).hasSize(1); for (Bindable bindable : bindables.values()) { - assertEquals(0, bindable.getInputs().size()); // producer - assertEquals(1, bindable.getOutputs().size());// consumer + assertThat(bindable.getInputs().size()).isEqualTo(0); // producer + assertThat(bindable.getOutputs().size()).isEqualTo(1); // consumer } DirectChannel testChannel = new DirectChannel(); testChannel.setComponentName("INPUT"); @@ -145,18 +140,18 @@ public class BinderAwareChannelResolverTests { fail("interrupted while awaiting latch"); } assertThat(received).hasSize(1); - assertThat(new String((byte[])received.get(0).getPayload())).isEqualTo("hello"); + assertThat(new String((byte[]) received.get(0).getPayload())).isEqualTo("hello"); this.context.close(); for (Bindable bindable : bindables.values()) { - assertEquals(0, bindable.getInputs().size()); - assertEquals(0, bindable.getOutputs().size());//Must not be bound" + assertThat(bindable.getInputs().size()).isEqualTo(0); + assertThat(bindable.getOutputs().size()).isEqualTo(0); // Must not be bound" } } @Test public void resolveNonRegisteredChannel() { - MessageChannel other = resolver.resolveDestination("other"); - assertThat(context.getBean("other")).isSameAs(other); + MessageChannel other = this.resolver.resolveDestination("other"); + assertThat(this.context.getBean("other")).isSameAs(other); this.context.close(); } @@ -173,20 +168,37 @@ public class BinderAwareChannelResolverTests { BinderFactory mockBinderFactory = Mockito.mock(BinderFactory.class); Binding fooBinding = Mockito.mock(Binding.class); Binding barBinding = Mockito.mock(Binding.class); - when(binder.bindProducer( - matches("foo"), any(DirectChannel.class), any(ProducerProperties.class))).thenReturn(fooBinding); - when(binder2.bindProducer( - matches("bar"), any(DirectChannel.class), any(ProducerProperties.class))).thenReturn(barBinding); - when(mockBinderFactory.getBinder(null, DirectWithAttributesChannel.class)).thenReturn(binder); - when(mockBinderFactory.getBinder("someTransport", DirectWithAttributesChannel.class)).thenReturn(binder2); - BindingService bindingService = new BindingService(bindingServiceProperties, + when(binder.bindProducer(matches("foo"), any(DirectChannel.class), + any(ProducerProperties.class))).thenReturn(fooBinding); + when(binder2.bindProducer(matches("bar"), any(DirectChannel.class), + any(ProducerProperties.class))).thenReturn(barBinding); + when(mockBinderFactory.getBinder(null, DirectWithAttributesChannel.class)) + .thenReturn(binder); + when(mockBinderFactory.getBinder("someTransport", + DirectWithAttributesChannel.class)).thenReturn(binder2); + BindingService bindingService = new BindingService(this.bindingServiceProperties, mockBinderFactory); - BinderAwareChannelResolver resolver = new BinderAwareChannelResolver(bindingService, this.bindingTargetFactory, + BinderAwareChannelResolver resolver = new BinderAwareChannelResolver( + bindingService, this.bindingTargetFactory, new DynamicDestinationsBindable()); - resolver.setBeanFactory(context.getBeanFactory()); - SubscribableChannel resolved = (SubscribableChannel) resolver.resolveDestination("foo"); - verify(binder).bindProducer(eq("foo"), any(MessageChannel.class), any(ProducerProperties.class)); - assertThat(resolved).isSameAs(context.getBean("foo")); + resolver.setBeanFactory(this.context.getBeanFactory()); + SubscribableChannel resolved = (SubscribableChannel) resolver + .resolveDestination("foo"); + verify(binder).bindProducer(eq("foo"), any(MessageChannel.class), + any(ProducerProperties.class)); + assertThat(resolved).isSameAs(this.context.getBean("foo")); this.context.close(); } + + @Configuration + public static class InterceptorConfiguration { + + @Bean + public GlobalChannelInterceptorWrapper testInterceptor() { + return new GlobalChannelInterceptorWrapper( + new ImmutableMessageChannelInterceptor()); + } + + } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderFactoryConfigurationTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderFactoryConfigurationTests.java index fa5b41495..a3ce6e9b0 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderFactoryConfigurationTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/BinderFactoryConfigurationTests.java @@ -60,38 +60,38 @@ public class BinderFactoryConfigurationTests { : new URL[additionalClasspathDirectories.length]; if (!ObjectUtils.isEmpty(additionalClasspathDirectories)) { for (int i = 0; i < additionalClasspathDirectories.length; i++) { - urls[i] = new URL(new ClassPathResource(additionalClasspathDirectories[i]).getURL().toString() + "/"); + urls[i] = new URL(new ClassPathResource(additionalClasspathDirectories[i]) + .getURL().toString() + "/"); } } - return new URLClassLoader(urls, BinderFactoryConfigurationTests.class.getClassLoader()); + return new URLClassLoader(urls, + BinderFactoryConfigurationTests.class.getClassLoader()); } - private static ConfigurableApplicationContext createBinderTestContext(String[] additionalClasspathDirectories, - String... properties) throws IOException { - ClassLoader classLoader = createClassLoader(additionalClasspathDirectories, properties); + private static ConfigurableApplicationContext createBinderTestContext( + String[] additionalClasspathDirectories, String... properties) + throws IOException { + ClassLoader classLoader = createClassLoader(additionalClasspathDirectories, + properties); return new SpringApplicationBuilder(SimpleApplication.class) .resourceLoader(new DefaultResourceLoader(classLoader)) - .properties(properties) - .web(WebApplicationType.NONE) - .run(); + .properties(properties).web(WebApplicationType.NONE).run(); } - private static ConfigurableApplicationContext createBinderTestContextWithSources(Class[] sources, - String[] additionalClasspathDirectories, + private static ConfigurableApplicationContext createBinderTestContextWithSources( + Class[] sources, String[] additionalClasspathDirectories, String... properties) throws IOException { - ClassLoader classLoader = createClassLoader(additionalClasspathDirectories, properties); + ClassLoader classLoader = createClassLoader(additionalClasspathDirectories, + properties); return new SpringApplicationBuilder(sources) .resourceLoader(new DefaultResourceLoader(classLoader)) - .properties(properties) - .web(WebApplicationType.NONE) - .run(); + .properties(properties).web(WebApplicationType.NONE).run(); } @Test public void loadBinderTypeRegistryWithSelfContainedAggregatorApp() throws Exception { - createBinderTestContextWithSources( - new Class[] { SimpleApplication.class }, new String[] {}, - "spring.cloud.stream.internal.selfContained=true"); + createBinderTestContextWithSources(new Class[] { SimpleApplication.class }, + new String[] {}, "spring.cloud.stream.internal.selfContained=true"); } @SuppressWarnings("rawtypes") @@ -118,7 +118,8 @@ public class BinderFactoryConfigurationTests { @SuppressWarnings("rawtypes") @Test - public void loadBinderTypeRegistryWithOneBinderAndSharedEnvironment() throws Exception { + public void loadBinderTypeRegistryWithOneBinderAndSharedEnvironment() + throws Exception { ConfigurableApplicationContext context = createBinderTestContext( new String[] { "binder1" }, "binder1.name=foo"); @@ -130,11 +131,13 @@ public class BinderFactoryConfigurationTests { @SuppressWarnings("rawtypes") @Test - public void loadBinderTypeRegistryWithOneCustomBinderAndSharedEnvironment() throws Exception { + public void loadBinderTypeRegistryWithOneCustomBinderAndSharedEnvironment() + throws Exception { ConfigurableApplicationContext context = createBinderTestContext( new String[] { "binder1" }, "binder1.name=foo", "spring.cloud.stream.binders.custom.environment.foo=bar", - "spring.cloud.stream.binders.custom.environment.spring.main.sources=org.springframework.cloud.stream.binder.BinderFactoryConfigurationTests.AdditionalBinderConfiguration", + "spring.cloud.stream.binders.custom.environment.spring.main.sources=" + + "org.springframework.cloud.stream.binder.BinderFactoryConfigurationTests.AdditionalBinderConfiguration", "spring.cloud.stream.binders.custom.type=binder1"); BinderFactory binderFactory = context.getBean(BinderFactory.class); @@ -185,21 +188,24 @@ public class BinderFactoryConfigurationTests { @SuppressWarnings("rawtypes") @Test public void loadBinderTypeRegistryWithTwoBinders() throws Exception { - ConfigurableApplicationContext context = createBinderTestContext(new String[] { "binder1", "binder2" }); + ConfigurableApplicationContext context = createBinderTestContext( + new String[] { "binder1", "binder2" }); BinderTypeRegistry binderTypeRegistry = context.getBean(BinderTypeRegistry.class); assertThat(binderTypeRegistry).isNotNull(); assertThat(binderTypeRegistry.getAll()).hasSize(4); - assertThat(binderTypeRegistry.getAll()).containsOnlyKeys("binder1", "binder2", "mock", "integration"); + assertThat(binderTypeRegistry.getAll()).containsOnlyKeys("binder1", "binder2", + "mock", "integration"); assertThat((Class[]) binderTypeRegistry.get("binder1").getConfigurationClasses()) .containsExactly(StubBinder1Configuration.class); assertThat((Class[]) binderTypeRegistry.get("binder2").getConfigurationClasses()) - .containsExactlyInAnyOrder(StubBinder2ConfigurationA.class, StubBinder2ConfigurationB.class); + .containsExactlyInAnyOrder(StubBinder2ConfigurationA.class, + StubBinder2ConfigurationB.class); BinderFactory binderFactory = context.getBean(BinderFactory.class); try { binderFactory.getBinder(null, MessageChannel.class); - fail(); + fail("Should throw an exception"); } catch (Exception e) { assertThat(e).isInstanceOf(IllegalStateException.class); @@ -250,11 +256,13 @@ public class BinderFactoryConfigurationTests { BinderTypeRegistry binderTypeRegistry = context.getBean(BinderTypeRegistry.class); assertThat(binderTypeRegistry).isNotNull(); assertThat(binderTypeRegistry.getAll()).hasSize(4); - assertThat(binderTypeRegistry.getAll()).containsOnlyKeys("binder1", "binder2", "mock", "integration"); + assertThat(binderTypeRegistry.getAll()).containsOnlyKeys("binder1", "binder2", + "mock", "integration"); assertThat((Class[]) binderTypeRegistry.get("binder1").getConfigurationClasses()) .containsExactlyInAnyOrder(StubBinder1Configuration.class); assertThat((Class[]) binderTypeRegistry.get("binder2").getConfigurationClasses()) - .containsExactlyInAnyOrder(StubBinder2ConfigurationA.class, StubBinder2ConfigurationB.class); + .containsExactlyInAnyOrder(StubBinder2ConfigurationA.class, + StubBinder2ConfigurationB.class); BinderFactory binderFactory = context.getBean(BinderFactory.class); @@ -267,7 +275,9 @@ public class BinderFactoryConfigurationTests { assertThat(defaultBinder).isSameAs(binder2); } - @Import({ BinderFactoryConfiguration.class, PropertyPlaceholderAutoConfiguration.class, BindingServiceConfiguration.class}) + @Import({ BinderFactoryConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + BindingServiceConfiguration.class }) @EnableBinding public static class SimpleApplication { diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ErrorBindingTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ErrorBindingTests.java index 1f46a1781..00fb3dd34 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ErrorBindingTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ErrorBindingTests.java @@ -17,7 +17,6 @@ package org.springframework.cloud.stream.binder; import org.junit.Test; - import org.mockito.Mockito; import org.springframework.boot.SpringApplication; @@ -37,7 +36,6 @@ import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.support.GenericMessage; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -49,49 +47,60 @@ import static org.mockito.ArgumentMatchers.isNull; */ public class ErrorBindingTests { - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testErrorChannelNotBoundByDefault() { - ConfigurableApplicationContext applicationContext = SpringApplication.run(TestProcessor.class, - "--server.port=0", "--spring.cloud.stream.default-binder=mock", "--spring.jmx.enabled=false"); + ConfigurableApplicationContext applicationContext = SpringApplication.run( + TestProcessor.class, "--server.port=0", + "--spring.cloud.stream.default-binder=mock", + "--spring.jmx.enabled=false"); BinderFactory binderFactory = applicationContext.getBean(BinderFactory.class); Binder binder = binderFactory.getBinder(null, MessageChannel.class); - Mockito.verify(binder).bindConsumer(eq("input"), isNull(), any(MessageChannel.class), - any(ConsumerProperties.class)); - Mockito.verify(binder).bindProducer(eq("output"), any(MessageChannel.class), any(ProducerProperties.class)); + Mockito.verify(binder).bindConsumer(eq("input"), isNull(), + any(MessageChannel.class), any(ConsumerProperties.class)); + Mockito.verify(binder).bindProducer(eq("output"), any(MessageChannel.class), + any(ProducerProperties.class)); Mockito.verifyNoMoreInteractions(binder); applicationContext.close(); } @Test public void testConfigurationWithDefaultErrorHandler() { - ApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration - .getCompleteConfiguration(ErrorBindingTests.ErrorConfigurationDefault.class)) - .web(WebApplicationType.NONE).run("--spring.cloud.stream.bindings.input.consumer.max-attempts=1", "--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration( + ErrorBindingTests.ErrorConfigurationDefault.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.bindings.input.consumer.max-attempts=1", + "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); source.send(new GenericMessage("Hello".getBytes())); source.send(new GenericMessage("Hello".getBytes())); source.send(new GenericMessage("Hello".getBytes())); - ErrorConfigurationDefault errorConfiguration = context.getBean(ErrorConfigurationDefault.class); + ErrorConfigurationDefault errorConfiguration = context + .getBean(ErrorConfigurationDefault.class); assertThat(errorConfiguration.counter == 3); } @Test public void testConfigurationWithCustomErrorHandler() { - ApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration - .getCompleteConfiguration(ErrorBindingTests.ErrorConfigurationWithCustomErrorHandler.class)) - .web(WebApplicationType.NONE).run("--spring.cloud.stream.bindings.input.consumer.max-attempts=1", "--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration( + ErrorBindingTests.ErrorConfigurationWithCustomErrorHandler.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.bindings.input.consumer.max-attempts=1", + "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); source.send(new GenericMessage("Hello".getBytes())); source.send(new GenericMessage("Hello".getBytes())); source.send(new GenericMessage("Hello".getBytes())); - ErrorConfigurationWithCustomErrorHandler errorConfiguration = context.getBean(ErrorConfigurationWithCustomErrorHandler.class); + ErrorConfigurationWithCustomErrorHandler errorConfiguration = context + .getBean(ErrorConfigurationWithCustomErrorHandler.class); assertThat(errorConfiguration.counter == 6); } @@ -109,9 +118,10 @@ public class ErrorBindingTests { @StreamListener(Sink.INPUT) public void handle(Object value) { - counter++; + this.counter++; throw new RuntimeException("BOOM!"); } + } @EnableBinding(Processor.class) @@ -122,13 +132,15 @@ public class ErrorBindingTests { @StreamListener(Sink.INPUT) public void handle(Object value) { - counter++; + this.counter++; throw new RuntimeException("BOOM!"); } @ServiceActivator(inputChannel = "input.anonymous.errors") public void error(Message message) { - counter++; + this.counter++; } + } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinderAwareChannelResolverTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinderAwareChannelResolverTests.java index fad06ca66..028169a6a 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinderAwareChannelResolverTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesBinderAwareChannelResolverTests.java @@ -33,8 +33,7 @@ import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessagingException; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; /** * @author Mark Fisher @@ -42,23 +41,24 @@ import static org.junit.Assert.fail; * @author Ilayaperumal Gopinathan * @author Oleg Zhurakousky */ -public class ExtendedPropertiesBinderAwareChannelResolverTests extends BinderAwareChannelResolverTests { +public class ExtendedPropertiesBinderAwareChannelResolverTests + extends BinderAwareChannelResolverTests { @Test @Override public void resolveChannel() { - Map bindables = context.getBeansOfType(Bindable.class); + Map bindables = this.context.getBeansOfType(Bindable.class); assertThat(bindables).hasSize(1); for (Bindable bindable : bindables.values()) { - assertEquals(0, bindable.getInputs().size()); // producer - assertEquals(0, bindable.getOutputs().size());// consumer + assertThat(bindable.getInputs().size()).isEqualTo(0); // producer + assertThat(bindable.getOutputs().size()).isEqualTo(0); // consumer } - MessageChannel registered = resolver.resolveDestination("foo"); - bindables = context.getBeansOfType(Bindable.class); + MessageChannel registered = this.resolver.resolveDestination("foo"); + bindables = this.context.getBeansOfType(Bindable.class); assertThat(bindables).hasSize(1); for (Bindable bindable : bindables.values()) { - assertEquals(0, bindable.getInputs().size()); // producer - assertEquals(1, bindable.getOutputs().size());// consumer + assertThat(bindable.getInputs().size()).isEqualTo(0); // producer + assertThat(bindable.getOutputs().size()).isEqualTo(1); // consumer } DirectChannel testChannel = new DirectChannel(); final CountDownLatch latch = new CountDownLatch(1); @@ -71,7 +71,9 @@ public class ExtendedPropertiesBinderAwareChannelResolverTests extends BinderAwa latch.countDown(); } }); - binder.bindConsumer("foo", null, testChannel, new ExtendedConsumerProperties(new ConsumerProperties())); + this.binder.bindConsumer("foo", null, testChannel, + new ExtendedConsumerProperties( + new ConsumerProperties())); assertThat(received).hasSize(0); registered.send(MessageBuilder.withPayload("hello").build()); try { @@ -82,11 +84,12 @@ public class ExtendedPropertiesBinderAwareChannelResolverTests extends BinderAwa fail("interrupted while awaiting latch"); } assertThat(received).hasSize(1); - assertThat(new String((byte[])received.get(0).getPayload())).isEqualTo("hello"); - context.close(); + assertThat(new String((byte[]) received.get(0).getPayload())).isEqualTo("hello"); + this.context.close(); for (Bindable bindable : bindables.values()) { - assertEquals(0, bindable.getInputs().size()); - assertEquals(0, bindable.getOutputs().size());//Must not be bound" + assertThat(bindable.getInputs().size()).isEqualTo(0); + assertThat(bindable.getOutputs().size()).isEqualTo(0); // Must not be bound" } } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesDefaultTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesDefaultTests.java index 72d527342..90ff16c10 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesDefaultTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ExtendedPropertiesDefaultTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -36,34 +36,39 @@ public class ExtendedPropertiesDefaultTests { @Test public void testExtendedDefaultProducerProperties() { DefaultBinderFactory binderFactory = createMockExtendedBinderFactory(); - Binder binder = binderFactory.getBinder(null, MessageChannel.class); - FooProducerProperties fooProducerProperties = - (FooProducerProperties) ((ExtendedPropertiesBinder) binder) - .getExtendedProducerProperties("output"); + Binder binder = binderFactory.getBinder(null, + MessageChannel.class); + FooProducerProperties fooProducerProperties = (FooProducerProperties) ((ExtendedPropertiesBinder) binder) + .getExtendedProducerProperties("output"); // Expectations are set in the mock configuration for the binder factory - assertThat(fooProducerProperties.getExtendedProperty()).isEqualTo("someFancyExtension"); + assertThat(fooProducerProperties.getExtendedProperty()) + .isEqualTo("someFancyExtension"); } @Test public void testExtendedDefaultConsumerProperties() { DefaultBinderFactory binderFactory = createMockExtendedBinderFactory(); - Binder binder = binderFactory.getBinder(null, MessageChannel.class); - FooConsumerProperties fooConsumerProperties = - (FooConsumerProperties)((ExtendedPropertiesBinder)binder) - .getExtendedConsumerProperties("input"); + Binder binder = binderFactory.getBinder(null, + MessageChannel.class); + FooConsumerProperties fooConsumerProperties = (FooConsumerProperties) ((ExtendedPropertiesBinder) binder) + .getExtendedConsumerProperties("input"); // Expectations are set in the mock configuration for the binder factory - assertThat(fooConsumerProperties.getExtendedProperty()).isEqualTo("someFancyExtension"); + assertThat(fooConsumerProperties.getExtendedProperty()) + .isEqualTo("someFancyExtension"); } private DefaultBinderFactory createMockExtendedBinderFactory() { BinderTypeRegistry binderTypeRegistry = createMockExtendedBinderTypeRegistry(); return new DefaultBinderFactory( - Collections.singletonMap("mock", new BinderConfiguration("mock", new HashMap<>(), true, true)), + Collections.singletonMap("mock", + new BinderConfiguration("mock", new HashMap<>(), true, true)), binderTypeRegistry); } private DefaultBinderTypeRegistry createMockExtendedBinderTypeRegistry() { - return new DefaultBinderTypeRegistry(Collections.singletonMap("mock", - new BinderType("mock", new Class[] { MockExtendedBinderConfiguration.class }))); + return new DefaultBinderTypeRegistry( + Collections.singletonMap("mock", new BinderType("mock", + new Class[] { MockExtendedBinderConfiguration.class }))); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/FooChannels.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/FooChannels.java index a96f812a9..1ab4ed39e 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/FooChannels.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/FooChannels.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,4 +36,5 @@ public interface FooChannels { @Output MessageChannel qux(); + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/HealthIndicatorsConfigurationTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/HealthIndicatorsConfigurationTests.java index f0526d19e..ef8304bfa 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/HealthIndicatorsConfigurationTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/HealthIndicatorsConfigurationTests.java @@ -45,7 +45,7 @@ import org.springframework.messaging.MessageChannel; import org.springframework.util.ObjectUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; /** * @author Marius Bogoevici @@ -75,26 +75,38 @@ public class HealthIndicatorsConfigurationTests { @SuppressWarnings("rawtypes") @Test public void healthIndicatorsCheck() throws Exception { - ConfigurableApplicationContext context = createBinderTestContext(new String[] { "binder1", "binder2" }, - "spring.cloud.stream.defaultBinder:binder2", "--spring.jmx.enabled=false"); - Binder binder1 = context.getBean(BinderFactory.class).getBinder("binder1", MessageChannel.class); + ConfigurableApplicationContext context = createBinderTestContext( + new String[] { "binder1", "binder2" }, + "spring.cloud.stream.defaultBinder:binder2", + "--spring.jmx.enabled=false"); + Binder binder1 = context.getBean(BinderFactory.class).getBinder("binder1", + MessageChannel.class); assertThat(binder1).isInstanceOf(StubBinder1.class); - Binder binder2 = context.getBean(BinderFactory.class).getBinder("binder2", MessageChannel.class); + Binder binder2 = context.getBean(BinderFactory.class).getBinder("binder2", + MessageChannel.class); assertThat(binder2).isInstanceOf(StubBinder2.class); - CompositeHealthIndicator bindersHealthIndicator = context.getBean("bindersHealthIndicator", - CompositeHealthIndicator.class); - DirectFieldAccessor directFieldAccessor = new DirectFieldAccessor(bindersHealthIndicator); + CompositeHealthIndicator bindersHealthIndicator = context + .getBean("bindersHealthIndicator", CompositeHealthIndicator.class); + DirectFieldAccessor directFieldAccessor = new DirectFieldAccessor( + bindersHealthIndicator); assertThat(bindersHealthIndicator).isNotNull(); - assertThat(context.getBean("test1HealthIndicator1", CompositeHealthIndicator.class)).isNotNull(); - assertThat(context.getBean("test2HealthIndicator2", CompositeHealthIndicator.class)).isNotNull(); + assertThat( + context.getBean("test1HealthIndicator1", CompositeHealthIndicator.class)) + .isNotNull(); + assertThat( + context.getBean("test2HealthIndicator2", CompositeHealthIndicator.class)) + .isNotNull(); - HealthIndicatorRegistry registry = (HealthIndicatorRegistry)directFieldAccessor.getPropertyValue("registry"); + HealthIndicatorRegistry registry = (HealthIndicatorRegistry) directFieldAccessor + .getPropertyValue("registry"); Map healthIndicators = registry.getAll(); assertThat(healthIndicators).containsKey("binder1"); - assertThat(healthIndicators.get("binder1").health().getStatus()).isEqualTo(Status.UP); + assertThat(healthIndicators.get("binder1").health().getStatus()) + .isEqualTo(Status.UP); assertThat(healthIndicators).containsKey("binder2"); - assertThat(healthIndicators.get("binder2").health().getStatus()).isEqualTo(Status.UNKNOWN); + assertThat(healthIndicators.get("binder2").health().getStatus()) + .isEqualTo(Status.UNKNOWN); context.close(); } @@ -104,12 +116,13 @@ public class HealthIndicatorsConfigurationTests { ConfigurableApplicationContext context = createBinderTestContext( new String[] { "binder1", "binder2" }, "spring.cloud.stream.defaultBinder:binder2", - "management.health.binders.enabled:false", - "--spring.jmx.enabled=false"); + "management.health.binders.enabled:false", "--spring.jmx.enabled=false"); - Binder binder1 = context.getBean(BinderFactory.class).getBinder("binder1", MessageChannel.class); + Binder binder1 = context.getBean(BinderFactory.class).getBinder("binder1", + MessageChannel.class); assertThat(binder1).isInstanceOf(StubBinder1.class); - Binder binder2 = context.getBean(BinderFactory.class).getBinder("binder2", MessageChannel.class); + Binder binder2 = context.getBean(BinderFactory.class).getBinder("binder2", + MessageChannel.class); assertThat(binder2).isInstanceOf(StubBinder2.class); try { context.getBean("bindersHealthIndicator", CompositeHealthIndicator.class); @@ -117,8 +130,12 @@ public class HealthIndicatorsConfigurationTests { } catch (NoSuchBeanDefinitionException e) { } - assertThat(context.getBean("test1HealthIndicator1", CompositeHealthIndicator.class)).isNotNull(); - assertThat(context.getBean("test2HealthIndicator2", CompositeHealthIndicator.class)).isNotNull(); + assertThat( + context.getBean("test1HealthIndicator1", CompositeHealthIndicator.class)) + .isNotNull(); + assertThat( + context.getBean("test2HealthIndicator2", CompositeHealthIndicator.class)) + .isNotNull(); context.close(); } @@ -138,7 +155,9 @@ public class HealthIndicatorsConfigurationTests { public CompositeHealthIndicator test2HealthIndicator2() { return new CompositeHealthIndicator(new OrderedHealthAggregator()); } + } + } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/InputOutputBindingOrderTest.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/InputOutputBindingOrderTest.java index 42bf8a920..5bc150aab 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/InputOutputBindingOrderTest.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/InputOutputBindingOrderTest.java @@ -43,17 +43,19 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; */ public class InputOutputBindingOrderTest { - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testInputOutputBindingOrder() { - ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(TestSource.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.defaultBinder=mock", - "--spring.jmx.enabled=false"); - Binder binder = applicationContext.getBean(BinderFactory.class).getBinder(null, MessageChannel.class); + ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder( + TestSource.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.defaultBinder=mock", + "--spring.jmx.enabled=false"); + Binder binder = applicationContext.getBean(BinderFactory.class).getBinder(null, + MessageChannel.class); Processor processor = applicationContext.getBean(Processor.class); // input is bound after the context has been started - verify(binder).bindConsumer(eq("input"), isNull(), eq(processor.input()), Mockito.any()); + verify(binder).bindConsumer(eq("input"), isNull(), eq(processor.input()), + Mockito.any()); SomeLifecycle someLifecycle = applicationContext.getBean(SomeLifecycle.class); assertThat(someLifecycle.isRunning()); applicationContext.close(); @@ -69,6 +71,7 @@ public class InputOutputBindingOrderTest { public SomeLifecycle someLifecycle() { return new SomeLifecycle(); } + } public static class SomeLifecycle implements SmartLifecycle { @@ -82,10 +85,11 @@ public class InputOutputBindingOrderTest { private boolean running; @Override - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) public synchronized void start() { Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); - verify(binder).bindProducer(eq("output"), eq(this.processor.output()), Mockito.any()); + verify(binder).bindProducer(eq("output"), eq(this.processor.output()), + Mockito.any()); // input was not bound yet verifyNoMoreInteractions(binder); this.running = true; @@ -118,5 +122,7 @@ public class InputOutputBindingOrderTest { public int getPhase() { return 0; } + } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/LifecycleBinderTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/LifecycleBinderTests.java index 4d7725b72..9f36e4dde 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/LifecycleBinderTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/LifecycleBinderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,9 +36,11 @@ public class LifecycleBinderTests { @Test public void testOnlySmartLifecyclesStarted() { - ConfigurableApplicationContext applicationContext = SpringApplication.run(TestSource.class, - "--server.port=-1", "--spring.cloud.stream.defaultBinder=mock", "--spring.jmx.enabled=false"); - SimpleLifecycle simpleLifecycle = applicationContext.getBean(SimpleLifecycle.class); + ConfigurableApplicationContext applicationContext = SpringApplication.run( + TestSource.class, "--server.port=-1", + "--spring.cloud.stream.defaultBinder=mock", "--spring.jmx.enabled=false"); + SimpleLifecycle simpleLifecycle = applicationContext + .getBean(SimpleLifecycle.class); assertThat(simpleLifecycle.isRunning()).isFalse(); applicationContext.close(); } @@ -51,6 +53,7 @@ public class LifecycleBinderTests { public SimpleLifecycle simpleLifecycle() { return new SimpleLifecycle(); } + } public static class SimpleLifecycle implements Lifecycle { @@ -71,5 +74,7 @@ public class LifecycleBinderTests { public synchronized boolean isRunning() { return this.running; } + } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/MessageConverterTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/MessageConverterTests.java index d426a1a26..c355fdd73 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/MessageConverterTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/MessageConverterTests.java @@ -18,7 +18,6 @@ package org.springframework.cloud.stream.binder; import java.nio.BufferUnderflowException; -import org.junit.Assert; import org.junit.Test; import org.springframework.integration.support.MessageBuilder; @@ -26,6 +25,7 @@ import org.springframework.messaging.Message; import org.springframework.messaging.support.GenericMessage; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; /** * @author Gary Russell @@ -36,15 +36,16 @@ public class MessageConverterTests { @Test public void testHeaderEmbedding() throws Exception { - Message message = MessageBuilder.withPayload("Hello".getBytes()).setHeader("foo", "bar") - .setHeader("baz", "quxx").build(); - byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), "foo", "baz"); + Message message = MessageBuilder.withPayload("Hello".getBytes()) + .setHeader("foo", "bar").setHeader("baz", "quxx").build(); + byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), + "foo", "baz"); assertThat(embedded[0] & 0xff).isEqualTo(0xff); assertThat(new String(embedded).substring(1)).isEqualTo( "\u0002\u0003foo\u0000\u0000\u0000\u0005\"bar\"\u0003baz\u0000\u0000\u0000\u0006\"quxx\"Hello"); - MessageValues extracted = EmbeddedHeaderUtils.extractHeaders(MessageBuilder.withPayload(embedded).build(), - false); + MessageValues extracted = EmbeddedHeaderUtils + .extractHeaders(MessageBuilder.withPayload(embedded).build(), false); assertThat(new String((byte[]) extracted.getPayload())).isEqualTo("Hello"); assertThat(extracted.get("foo")).isEqualTo("bar"); assertThat(extracted.get("baz")).isEqualTo("quxx"); @@ -52,16 +53,17 @@ public class MessageConverterTests { @Test public void testConfigurableHeaders() throws Exception { - Message message = MessageBuilder.withPayload("Hello".getBytes()).setHeader("foo", "bar") - .setHeader("baz", "quxx").setHeader("contentType", "text/plain").build(); + Message message = MessageBuilder.withPayload("Hello".getBytes()) + .setHeader("foo", "bar").setHeader("baz", "quxx") + .setHeader("contentType", "text/plain").build(); String[] headers = new String[] { "foo" }; byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), EmbeddedHeaderUtils.headersToEmbed(headers)); assertThat(embedded[0] & 0xff).isEqualTo(0xff); assertThat(new String(embedded).substring(1)).isEqualTo( "\u0002\u000BcontentType\u0000\u0000\u0000\u000C\"text/plain\"\u0003foo\u0000\u0000\u0000\u0005\"bar\"Hello"); - MessageValues extracted = EmbeddedHeaderUtils.extractHeaders(MessageBuilder.withPayload(embedded).build(), - false); + MessageValues extracted = EmbeddedHeaderUtils + .extractHeaders(MessageBuilder.withPayload(embedded).build(), false); assertThat(new String((byte[]) extracted.getPayload())).isEqualTo("Hello"); assertThat(extracted.get("foo")).isEqualTo("bar"); assertThat(extracted.get("baz")).isNull(); @@ -71,15 +73,17 @@ public class MessageConverterTests { .extractHeaders(MessageBuilder.withPayload(embedded).build(), true); assertThat(extractedWithRequestHeaders.get("foo")).isEqualTo("bar"); assertThat(extractedWithRequestHeaders.get("baz")).isNull(); - assertThat(extractedWithRequestHeaders.get("contentType")).isEqualTo("text/plain"); + assertThat(extractedWithRequestHeaders.get("contentType")) + .isEqualTo("text/plain"); assertThat(extractedWithRequestHeaders.get("timestamp")).isNotNull(); } @Test public void testHeaderExtractionWithDirectPayload() throws Exception { - Message message = MessageBuilder.withPayload("Hello".getBytes()).setHeader("foo", "bar") - .setHeader("baz", "quxx").build(); - byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), "foo", "baz"); + Message message = MessageBuilder.withPayload("Hello".getBytes()) + .setHeader("foo", "bar").setHeader("baz", "quxx").build(); + byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), + "foo", "baz"); assertThat(embedded[0] & 0xff).isEqualTo(0xff); assertThat(new String(embedded).substring(1)).isEqualTo( "\u0002\u0003foo\u0000\u0000\u0000\u0005\"bar\"\u0003baz\u0000\u0000\u0000\u0006\"quxx\"Hello"); @@ -92,15 +96,16 @@ public class MessageConverterTests { @Test public void testUnicodeHeader() throws Exception { - Message message = MessageBuilder.withPayload("Hello".getBytes()).setHeader("foo", "bar") - .setHeader("baz", "ØØØØØØØØ").build(); - byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), "foo", "baz"); + Message message = MessageBuilder.withPayload("Hello".getBytes()) + .setHeader("foo", "bar").setHeader("baz", "ØØØØØØØØ").build(); + byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), + "foo", "baz"); assertThat(embedded[0] & 0xff).isEqualTo(0xff); assertThat(new String(embedded, "UTF-8").substring(1)).isEqualTo( "\u0002\u0003foo\u0000\u0000\u0000\u0005\"bar\"\u0003baz\u0000\u0000\u0000\u0012\"ØØØØØØØØ\"Hello"); - MessageValues extracted = EmbeddedHeaderUtils.extractHeaders(MessageBuilder.withPayload(embedded).build(), - false); + MessageValues extracted = EmbeddedHeaderUtils + .extractHeaders(MessageBuilder.withPayload(embedded).build(), false); assertThat(new String((byte[]) extracted.getPayload())).isEqualTo("Hello"); assertThat(extracted.get("foo")).isEqualTo("bar"); assertThat(extracted.get("baz")).isEqualTo("ØØØØØØØØ"); @@ -108,10 +113,13 @@ public class MessageConverterTests { @Test public void testHeaderEmbeddingMissingHeader() throws Exception { - Message message = MessageBuilder.withPayload("Hello".getBytes()).setHeader("foo", "bar").build(); - byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), "foo", "baz"); + Message message = MessageBuilder.withPayload("Hello".getBytes()) + .setHeader("foo", "bar").build(); + byte[] embedded = EmbeddedHeaderUtils.embedHeaders(new MessageValues(message), + "foo", "baz"); assertThat(embedded[0] & 0xff).isEqualTo(0xff); - assertThat(new String(embedded).substring(1)).isEqualTo("\u0001\u0003foo\u0000\u0000\u0000\u0005\"bar\"Hello"); + assertThat(new String(embedded).substring(1)) + .isEqualTo("\u0001\u0003foo\u0000\u0000\u0000\u0005\"bar\"Hello"); } @Test @@ -120,7 +128,7 @@ public class MessageConverterTests { Message message = new GenericMessage<>(bytes); try { EmbeddedHeaderUtils.extractHeaders(message, false); - Assert.fail("Exception expected"); + fail("Exception expected"); } catch (Exception e) { String s = EmbeddedHeaderUtils.decodeExceptionMessage(message); diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/PollableConsumerTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/PollableConsumerTests.java index edc1bc0e0..9c424ec9d 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/PollableConsumerTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/PollableConsumerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -69,34 +69,39 @@ public class PollableConsumerTests { @Before public void before() { - this.messageConverter = new CompositeMessageConverterFactory().getMessageConverterForAllRegistered(); + this.messageConverter = new CompositeMessageConverterFactory() + .getMessageConverterForAllRegistered(); } @Test public void testSimple() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); pollableSource.addInterceptor(new ChannelInterceptor() { @Override public Message preSend(Message message, MessageChannel channel) { - return MessageBuilder.withPayload(((String) message.getPayload()).toUpperCase()) - .copyHeaders(message.getHeaders()) - .build(); + return MessageBuilder + .withPayload(((String) message.getPayload()).toUpperCase()) + .copyHeaders(message.getHeaders()).build(); } }); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(2); properties.setBackOffInitialInterval(0); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); final AtomicInteger count = new AtomicInteger(); assertThat(pollableSource.poll(received -> { assertThat(received.getPayload()).isEqualTo("POLLED DATA"); - assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(MimeType.valueOf("text/plain")); + assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeType.valueOf("text/plain")); if (count.incrementAndGet() == 1) { throw new RuntimeException("test retry"); } @@ -107,26 +112,32 @@ public class PollableConsumerTests { @Test public void testConvertSimple() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); - binder.setMessageSourceDelegate(() -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes())); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + binder.setMessageSourceDelegate( + () -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes())); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(1); properties.setBackOffInitialInterval(0); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); final AtomicReference payload = new AtomicReference<>(); assertThat(pollableSource.poll(received -> { payload.set(received.getPayload()); - }, new ParameterizedTypeReference() {})).isTrue(); + }, new ParameterizedTypeReference() { + })).isTrue(); assertThat(payload.get()).isInstanceOf(Foo.class); assertThat(((Foo) payload.get()).getFoo()).isEqualTo("bar"); // test the cache for coverage assertThat(pollableSource.poll(received -> { payload.set(received.getPayload()); - }, new ParameterizedTypeReference() {})).isTrue(); + }, new ParameterizedTypeReference() { + })).isTrue(); assertThat(payload.get()).isInstanceOf(Foo.class); assertThat(((Foo) payload.get()).getFoo()).isEqualTo("bar"); } @@ -134,30 +145,36 @@ public class PollableConsumerTests { @Test public void testConvertSimpler() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); - BindingServiceProperties bsps = this.context.getBean(BindingServiceProperties.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); + BindingServiceProperties bsps = this.context + .getBean(BindingServiceProperties.class); BindingProperties props = new BindingProperties(); props.setContentType("text/plain"); bsps.setBindings(Collections.singletonMap("foo", props)); binder.setMessageSourceDelegate(() -> new GenericMessage<>("foo".getBytes())); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(1); properties.setBackOffInitialInterval(0); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); final AtomicReference payload = new AtomicReference<>(); assertThat(pollableSource.poll(received -> { payload.set(received.getPayload()); - }, new ParameterizedTypeReference() {})).isTrue(); + }, new ParameterizedTypeReference() { + })).isTrue(); assertThat(payload.get()).isInstanceOf(String.class); assertThat(payload.get()).isEqualTo("foo"); // test the cache for coverage assertThat(pollableSource.poll(received -> { payload.set(received.getPayload()); - }, new ParameterizedTypeReference() {})).isTrue(); + }, new ParameterizedTypeReference() { + })).isTrue(); assertThat(payload.get()).isInstanceOf(String.class); assertThat(payload.get()).isEqualTo("foo"); } @@ -165,24 +182,27 @@ public class PollableConsumerTests { @Test public void testConvertList() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); - binder.setMessageSourceDelegate(() -> new GenericMessage<>("[{\"foo\":\"bar\"},{\"foo\":\"baz\"}]".getBytes())); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + binder.setMessageSourceDelegate(() -> new GenericMessage<>( + "[{\"foo\":\"bar\"},{\"foo\":\"baz\"}]".getBytes())); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(1); properties.setBackOffInitialInterval(0); - - binder.bindPollableConsumer("foo", "bar", pollableSource, properties); final AtomicReference payload = new AtomicReference<>(); assertThat(pollableSource.poll(received -> { payload.set(received.getPayload()); - }, new ParameterizedTypeReference>() {})).isTrue(); + }, new ParameterizedTypeReference>() { + })).isTrue(); @SuppressWarnings("unchecked") List list = (List) payload.get(); assertThat(list.size()).isEqualTo(2); @@ -193,20 +213,25 @@ public class PollableConsumerTests { @Test public void testConvertMap() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); - binder.setMessageSourceDelegate(() -> new GenericMessage<>("{\"qux\":{\"foo\":\"bar\"}}".getBytes())); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + binder.setMessageSourceDelegate( + () -> new GenericMessage<>("{\"qux\":{\"foo\":\"bar\"}}".getBytes())); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(1); properties.setBackOffInitialInterval(0); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); final AtomicReference payload = new AtomicReference<>(); assertThat(pollableSource.poll(received -> { payload.set(received.getPayload()); - }, new ParameterizedTypeReference>() {})).isTrue(); + }, new ParameterizedTypeReference>() { + })).isTrue(); @SuppressWarnings("unchecked") Map map = (Map) payload.get(); assertThat(map.size()).isEqualTo(1); @@ -216,67 +241,78 @@ public class PollableConsumerTests { @Test public void testEmbedded() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); binder.setMessageSourceDelegate(() -> { MessageValues original = new MessageValues("foo".getBytes(), - Collections.singletonMap(MessageHeaders.CONTENT_TYPE, "application/octet-stream")); + Collections.singletonMap(MessageHeaders.CONTENT_TYPE, + "application/octet-stream")); byte[] payload = new byte[0]; try { - payload = EmbeddedHeaderUtils.embedHeaders(original, MessageHeaders.CONTENT_TYPE); + payload = EmbeddedHeaderUtils.embedHeaders(original, + MessageHeaders.CONTENT_TYPE); } catch (Exception e) { fail(e.getMessage()); } return new GenericMessage<>(payload); }); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setHeaderMode(HeaderMode.embeddedHeaders); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); pollableSource.addInterceptor(new ChannelInterceptor() { @Override public Message preSend(Message message, MessageChannel channel) { - return MessageBuilder.withPayload(new String((byte[]) message.getPayload()).toUpperCase()) - .copyHeaders(message.getHeaders()) - .build(); + return MessageBuilder + .withPayload( + new String((byte[]) message.getPayload()).toUpperCase()) + .copyHeaders(message.getHeaders()).build(); } }); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); assertThat(pollableSource.poll(received -> { assertThat(received.getPayload()).isEqualTo("FOO"); - assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo("application/octet-stream"); + assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo("application/octet-stream"); })).isTrue(); } @Test public void testErrors() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); pollableSource.addInterceptor(new ChannelInterceptor() { @Override public Message preSend(Message message, MessageChannel channel) { - return MessageBuilder.withPayload(((String) message.getPayload()).toUpperCase()) - .copyHeaders(message.getHeaders()) - .build(); + return MessageBuilder + .withPayload(((String) message.getPayload()).toUpperCase()) + .copyHeaders(message.getHeaders()).build(); } }); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(2); properties.setBackOffInitialInterval(0); properties.getRetryableExceptions().put(IllegalStateException.class, false); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); final CountDownLatch latch = new CountDownLatch(1); - context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, SubscribableChannel.class).subscribe(m -> { - latch.countDown(); - }); + this.context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, + SubscribableChannel.class).subscribe(m -> { + latch.countDown(); + }); final AtomicInteger count = new AtomicInteger(); assertThat(pollableSource.poll(received -> { count.incrementAndGet(); @@ -285,7 +321,8 @@ public class PollableConsumerTests { assertThat(count.get()).isEqualTo(2); Message lastError = binder.getLastError(); assertThat(lastError).isNotNull(); - assertThat(((Exception) lastError.getPayload()).getCause().getMessage()).isEqualTo("test recoverer"); + assertThat(((Exception) lastError.getPayload()).getCause().getMessage()) + .isEqualTo("test recoverer"); assertThat(pollableSource.poll(received -> { count.incrementAndGet(); throw new IllegalStateException("no retries"); @@ -293,33 +330,38 @@ public class PollableConsumerTests { assertThat(count.get()).isEqualTo(3); lastError = binder.getLastError(); assertThat(lastError).isNotNull(); - assertThat(((Exception) lastError.getPayload()).getCause().getMessage()).isEqualTo("no retries"); + assertThat(((Exception) lastError.getPayload()).getCause().getMessage()) + .isEqualTo("no retries"); } @Test public void testErrorsNoRetry() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); pollableSource.addInterceptor(new ChannelInterceptor() { @Override public Message preSend(Message message, MessageChannel channel) { - return MessageBuilder.withPayload(((String) message.getPayload()).toUpperCase()) - .copyHeaders(message.getHeaders()) - .build(); + return MessageBuilder + .withPayload(((String) message.getPayload()).toUpperCase()) + .copyHeaders(message.getHeaders()).build(); } }); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(1); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); final CountDownLatch latch = new CountDownLatch(1); - context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, SubscribableChannel.class).subscribe(m -> { - latch.countDown(); - }); + this.context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, + SubscribableChannel.class).subscribe(m -> { + latch.countDown(); + }); final AtomicInteger count = new AtomicInteger(); assertThat(pollableSource.poll(received -> { count.incrementAndGet(); @@ -331,9 +373,11 @@ public class PollableConsumerTests { @Test public void testRequeue() { TestChannelBinder binder = createBinder(); - MessageConverterConfigurer configurer = context.getBean(MessageConverterConfigurer.class); + MessageConverterConfigurer configurer = this.context + .getBean(MessageConverterConfigurer.class); - DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(this.messageConverter); + DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource( + this.messageConverter); configurer.configurePolledMessageSource(pollableSource, "foo"); AcknowledgmentCallback callback = mock(AcknowledgmentCallback.class); pollableSource.addInterceptor(new ChannelInterceptor() { @@ -341,12 +385,15 @@ public class PollableConsumerTests { @Override public Message preSend(Message message, MessageChannel channel) { return MessageBuilder.fromMessage(message) - .setHeader(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK, callback) + .setHeader( + IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK, + callback) .build(); } }); - ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>(null); + ExtendedConsumerProperties properties = new ExtendedConsumerProperties<>( + null); properties.setMaxAttempts(2); properties.setBackOffInitialInterval(0); binder.bindPollableConsumer("foo", "bar", pollableSource, properties); @@ -356,7 +403,7 @@ public class PollableConsumerTests { count.incrementAndGet(); throw new RequeueCurrentMessageException("test retry"); })).isTrue(); - //fail("Expected exception"); // see GH-1578 + // fail("Expected exception"); // see GH-1578 } catch (Exception e) { // no op @@ -366,9 +413,10 @@ public class PollableConsumerTests { } private TestChannelBinder createBinder(String... args) { - this.context = new SpringApplicationBuilder(TestChannelBinderConfiguration.getCompleteConfiguration()) - .web(WebApplicationType.NONE).run(args); - TestChannelBinder binder = context.getBean(TestChannelBinder.class); + this.context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration()) + .web(WebApplicationType.NONE).run(args); + TestChannelBinder binder = this.context.getBean(TestChannelBinder.class); return binder; } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingWithBindingTargetsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingWithBindingTargetsTests.java index e67651e9a..6f5056651 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingWithBindingTargetsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingWithBindingTargetsTests.java @@ -38,8 +38,9 @@ import static org.mockito.Mockito.verify; * @author Janne Valkealahti */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = ProcessorBindingWithBindingTargetsTests.TestProcessor.class, - properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:off +@SpringBootTest(classes = ProcessorBindingWithBindingTargetsTests.TestProcessor.class, properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:on public class ProcessorBindingWithBindingTargetsTests { @Autowired @@ -48,10 +49,10 @@ public class ProcessorBindingWithBindingTargetsTests { @Autowired private Processor testProcessor; - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testSourceOutputChannelBound() { - final Binder binder = binderFactory.getBinder(null, MessageChannel.class); + final Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); verify(binder).bindConsumer(eq("testtock.0"), isNull(), eq(this.testProcessor.input()), Mockito.any()); verify(binder).bindProducer(eq("testtock.1"), eq(this.testProcessor.output()), @@ -64,4 +65,5 @@ public class ProcessorBindingWithBindingTargetsTests { public static class TestProcessor { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingsWithDefaultsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingsWithDefaultsTests.java index 863caa51b..cb89a7021 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingsWithDefaultsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/ProcessorBindingsWithDefaultsTests.java @@ -37,22 +37,24 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Janne Valkealahti */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = ProcessorBindingsWithDefaultsTests.TestProcessor.class, -properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:off +@SpringBootTest(classes = ProcessorBindingsWithDefaultsTests.TestProcessor.class, properties = "spring.cloud.stream.defaultBinder=mock") public class ProcessorBindingsWithDefaultsTests { + // @checkstyle:on + @Autowired private BinderFactory binderFactory; @Autowired private Processor processor; - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testSourceOutputChannelBound() { Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); - Mockito.verify(binder).bindConsumer(eq("input"), isNull(), eq(this.processor.input()), - Mockito.any()); + Mockito.verify(binder).bindConsumer(eq("input"), isNull(), + eq(this.processor.input()), Mockito.any()); Mockito.verify(binder).bindProducer(eq("output"), eq(this.processor.output()), Mockito.any()); verifyNoMoreInteractions(binder); @@ -63,4 +65,5 @@ public class ProcessorBindingsWithDefaultsTests { public static class TestProcessor { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultTargetsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultTargetsTests.java index ae49a042e..0f16ed6c6 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultTargetsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultTargetsTests.java @@ -40,8 +40,9 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Janne Valkealahti */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SinkBindingWithDefaultTargetsTests.TestSink.class, - properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:off +@SpringBootTest(classes = SinkBindingWithDefaultTargetsTests.TestSink.class, properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:on public class SinkBindingWithDefaultTargetsTests { @Autowired @@ -51,9 +52,9 @@ public class SinkBindingWithDefaultTargetsTests { private Sink testSink; @Test - @SuppressWarnings({"rawtypes","unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) public void testSourceOutputChannelBound() { - Binder binder = binderFactory.getBinder(null, MessageChannel.class); + Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); verify(binder).bindConsumer(eq("testtock"), isNull(), eq(this.testSink.input()), Mockito.any()); verifyNoMoreInteractions(binder); @@ -65,4 +66,5 @@ public class SinkBindingWithDefaultTargetsTests { public static class TestSink { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultsTests.java index 2e20ccade..9cc0ef3ad 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SinkBindingWithDefaultsTests.java @@ -38,8 +38,9 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Janne Valkealahti */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SinkBindingWithDefaultsTests.TestSink.class, - properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:off +@SpringBootTest(classes = SinkBindingWithDefaultsTests.TestSink.class, properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:on public class SinkBindingWithDefaultsTests { @Autowired @@ -48,10 +49,10 @@ public class SinkBindingWithDefaultsTests { @Autowired private Sink testSink; - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testSourceOutputChannelBound() { - Binder binder = binderFactory.getBinder(null, MessageChannel.class); + Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); verify(binder).bindConsumer(eq("input"), isNull(), eq(this.testSink.input()), Mockito.any()); verifyNoMoreInteractions(binder); @@ -62,4 +63,5 @@ public class SinkBindingWithDefaultsTests { public static class TestSink { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithBindingTargetsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithBindingTargetsTests.java index 98a6ee062..32228cfff 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithBindingTargetsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithBindingTargetsTests.java @@ -41,8 +41,9 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Ilayaperumal Gopinathan */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SourceBindingWithBindingTargetsTests.TestSource.class, - properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:off +@SpringBootTest(classes = SourceBindingWithBindingTargetsTests.TestSource.class, properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:on public class SourceBindingWithBindingTargetsTests { @Autowired @@ -56,9 +57,9 @@ public class SourceBindingWithBindingTargetsTests { private PublishSubscribeChannel errorChannel; @Test - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) public void testSourceOutputChannelBound() { - Binder binder = binderFactory.getBinder(null, MessageChannel.class); + Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); verify(binder).bindProducer(eq("testtock"), eq(this.testSource.output()), Mockito.any()); verifyNoMoreInteractions(binder); @@ -70,4 +71,5 @@ public class SourceBindingWithBindingTargetsTests { public static class TestSource { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithDefaultsTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithDefaultsTests.java index 68d47b85c..376bf642a 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithDefaultsTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithDefaultsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,9 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Marius Bogoevici */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SourceBindingWithDefaultsTests.TestSource.class, - properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:off +@SpringBootTest(classes = SourceBindingWithDefaultsTests.TestSource.class, properties = "spring.cloud.stream.defaultBinder=mock") +// @checkstyle:on public class SourceBindingWithDefaultsTests { @Autowired @@ -46,11 +47,12 @@ public class SourceBindingWithDefaultsTests { @Autowired private Source testSource; - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testSourceOutputChannelBound() { - Binder binder = binderFactory.getBinder(null, MessageChannel.class); - verify(binder).bindProducer(eq("output"), eq(this.testSource.output()), Mockito.any()); + Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); + verify(binder).bindProducer(eq("output"), eq(this.testSource.output()), + Mockito.any()); verifyNoMoreInteractions(binder); } @@ -59,4 +61,5 @@ public class SourceBindingWithDefaultsTests { public static class TestSource { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesOnlyTest.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesOnlyTest.java index cce522c42..70611b4f5 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesOnlyTest.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesOnlyTest.java @@ -36,9 +36,11 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @author Ilayaperumal Gopinathan */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = {TestChannelBinderConfiguration.class, SourceBindingWithGlobalPropertiesOnlyTest.TestSource.class, SpelExpressionConverterConfiguration.class}, - properties = {"spring.cloud.stream.default.contentType=application/json", - "spring.cloud.stream.default.producer.partitionKeyExpression=key"}) +@SpringBootTest(classes = { TestChannelBinderConfiguration.class, + SourceBindingWithGlobalPropertiesOnlyTest.TestSource.class, + SpelExpressionConverterConfiguration.class }, properties = { + "spring.cloud.stream.default.contentType=application/json", + "spring.cloud.stream.default.producer.partitionKeyExpression=key" }) public class SourceBindingWithGlobalPropertiesOnlyTest { @Autowired @@ -46,10 +48,13 @@ public class SourceBindingWithGlobalPropertiesOnlyTest { @Test public void testGlobalPropertiesSet() { - BindingProperties bindingProperties = bindingServiceProperties.getBindingProperties(Source.OUTPUT); - Assertions.assertThat(bindingProperties.getContentType()).isEqualTo("application/json"); + BindingProperties bindingProperties = this.bindingServiceProperties + .getBindingProperties(Source.OUTPUT); + Assertions.assertThat(bindingProperties.getContentType()) + .isEqualTo("application/json"); Assertions.assertThat(bindingProperties.getProducer()).isNotNull(); - Assertions.assertThat(bindingProperties.getProducer().getPartitionKeyExpression().getExpressionString()).isEqualTo("key"); + Assertions.assertThat(bindingProperties.getProducer().getPartitionKeyExpression() + .getExpressionString()).isEqualTo("key"); } @EnableBinding(Source.class) @@ -57,4 +62,5 @@ public class SourceBindingWithGlobalPropertiesOnlyTest { public static class TestSource { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesTest.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesTest.java index 3b78533da..b85ef42fe 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesTest.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/SourceBindingWithGlobalPropertiesTest.java @@ -43,7 +43,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; "spring.cloud.stream.default.producer.partitionCount=1", "spring.cloud.stream.bindings.output.producer.headerMode=none", "spring.cloud.stream.bindings.output.producer.partitionCount=4", - "spring.cloud.stream.defaultBinder=mock"}) + "spring.cloud.stream.defaultBinder=mock" }) public class SourceBindingWithGlobalPropertiesTest { @Autowired @@ -51,12 +51,17 @@ public class SourceBindingWithGlobalPropertiesTest { @Test public void testGlobalPropertiesSet() { - BindingProperties bindingProperties = serviceProperties.getBindingProperties(Source.OUTPUT); - Assertions.assertThat(bindingProperties.getContentType()).isEqualTo("application/json"); + BindingProperties bindingProperties = this.serviceProperties + .getBindingProperties(Source.OUTPUT); + Assertions.assertThat(bindingProperties.getContentType()) + .isEqualTo("application/json"); Assertions.assertThat(bindingProperties.getDestination()).isEqualTo("ticktock"); - Assertions.assertThat(bindingProperties.getProducer().getRequiredGroups()).containsExactly("someGroup"); // default propagates to producer - Assertions.assertThat(bindingProperties.getProducer().getPartitionCount()).isEqualTo(4); // validates binding property takes precedence over default - Assertions.assertThat(bindingProperties.getProducer().getHeaderMode()).isEqualTo(HeaderMode.none); + Assertions.assertThat(bindingProperties.getProducer().getRequiredGroups()) + .containsExactly("someGroup"); // default propagates to producer + Assertions.assertThat(bindingProperties.getProducer().getPartitionCount()) + .isEqualTo(4); // validates binding property takes precedence over default + Assertions.assertThat(bindingProperties.getProducer().getHeaderMode()) + .isEqualTo(HeaderMode.none); } @EnableBinding(Source.class) @@ -64,4 +69,5 @@ public class SourceBindingWithGlobalPropertiesTest { public static class TestSource { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1.java index 8d4021fad..087220e6a 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1.java @@ -27,14 +27,15 @@ import org.springframework.context.ConfigurableApplicationContext; * @author Mark Fisher * @author Soby Chacko */ -public class StubBinder1 implements Binder { +public class StubBinder1 + implements Binder { private String name; private ConfigurableApplicationContext outerContext; public ConfigurableApplicationContext getOuterContext() { - return outerContext; + return this.outerContext; } public void setOuterContext(ConfigurableApplicationContext outerContext) { @@ -50,13 +51,14 @@ public class StubBinder1 implements Binder bindConsumer(String name, String group, Object inboundBindTarget, - ConsumerProperties properties) { + public Binding bindConsumer(String name, String group, + Object inboundBindTarget, ConsumerProperties properties) { return null; } @Override - public Binding bindProducer(String name, Object outboundBindTarget, ProducerProperties properties) { + public Binding bindProducer(String name, Object outboundBindTarget, + ProducerProperties properties) { return null; } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1Configuration.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1Configuration.java index 66f147ef6..f728f2191 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1Configuration.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub1/StubBinder1Configuration.java @@ -41,10 +41,11 @@ public class StubBinder1Configuration { StubBinder1 stubBinder1 = new StubBinder1(); ConfigurableApplicationContext outerContext = null; try { - outerContext = (ConfigurableApplicationContext) beanFactory.getBean("outerContext"); + outerContext = (ConfigurableApplicationContext) beanFactory + .getBean("outerContext"); } catch (BeansException be) { - //Pass through + // Pass through } if (outerContext != null) { stubBinder1.setOuterContext(outerContext); @@ -56,4 +57,5 @@ public class StubBinder1Configuration { public HealthIndicator binderHealthIndicator() { return new ApplicationHealthIndicator(); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2.java index 03f713623..0cffa69ed 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2.java @@ -25,7 +25,8 @@ import org.springframework.cloud.stream.binder.ProducerProperties; * @author Marius Bogoevici * @author Mark Fisher */ -public class StubBinder2 implements Binder { +public class StubBinder2 + implements Binder { @SuppressWarnings("unused") private final StubBinder2Dependency stubBinder2Dependency; @@ -35,13 +36,14 @@ public class StubBinder2 implements Binder bindConsumer(String name, String group, Object inboundBindTarget, - ConsumerProperties properties) { + public Binding bindConsumer(String name, String group, + Object inboundBindTarget, ConsumerProperties properties) { return null; } @Override - public Binding bindProducer(String name, Object outboundBindTarget, ProducerProperties properties) { + public Binding bindProducer(String name, Object outboundBindTarget, + ProducerProperties properties) { return null; } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationA.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationA.java index df6638200..86ae80e2f 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationA.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationA.java @@ -30,4 +30,5 @@ public class StubBinder2ConfigurationA { public Binder binder(StubBinder2Dependency dependency) { return new StubBinder2(dependency); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationB.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationB.java index 758956b95..b1ebbe505 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationB.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2ConfigurationB.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,4 +29,5 @@ public class StubBinder2ConfigurationB { public StubBinder2Dependency dependency() { return new StubBinder2Dependency(); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2Dependency.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2Dependency.java index b9573a36a..517c34a18 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2Dependency.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/stub2/StubBinder2Dependency.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java index 0d4f59a52..d9269710a 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.Test; import org.springframework.boot.WebApplicationType; @@ -59,17 +58,11 @@ import org.springframework.util.MimeType; import org.springframework.util.MimeTypeUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; /** - * Sort of a TCK test suite to validate payload conversion is - * done properly by interacting with binder's input/output destinations - * instead of its bridged channels. - * This means that all payloads (sent/received) must be expressed in the - * wire format (byte[]) + * Sort of a TCK test suite to validate payload conversion is done properly by interacting + * with binder's input/output destinations instead of its bridged channels. This means + * that all payloads (sent/received) must be expressed in the wire format (byte[]) * * @author Oleg Zhurakousky * @author Gary Russell @@ -79,484 +72,560 @@ public class ContentTypeTckTests { @Test public void stringToMapStreamListener() { - ApplicationContext context = new SpringApplicationBuilder(StringToMapStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + StringToMapStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals("oleg", new String(outputMessage.getPayload())); + assertThat(new String(outputMessage.getPayload())).isEqualTo("oleg"); } @Test public void stringToMapMessageStreamListener() { - ApplicationContext context = new SpringApplicationBuilder(StringToMapMessageStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + StringToMapMessageStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals("oleg", new String(outputMessage.getPayload())); + assertThat(new String(outputMessage.getPayload())).isEqualTo("oleg"); } @Test // emulates 1.3 behavior public void stringToMapMessageStreamListenerOriginalContentType() { - ApplicationContext context = new SpringApplicationBuilder(StringToMapMessageStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + StringToMapMessageStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; Message message = MessageBuilder.withPayload(jsonPayload.getBytes()) - .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain") - .setHeader("originalContentType", "application/json;charset=UTF-8") - .build(); + .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain") + .setHeader("originalContentType", "application/json;charset=UTF-8") + .build(); source.send(message); Message outputMessage = target.receive(); - assertEquals("oleg", new String(outputMessage.getPayload())); + assertThat(new String(outputMessage.getPayload())).isEqualTo("oleg"); } - @Test public void withInternalPipeline() { ApplicationContext context = new SpringApplicationBuilder(InternalPipeLine.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals("OLEG", new String(outputMessage.getPayload())); + assertThat(new String(outputMessage.getPayload())).isEqualTo("OLEG"); } @Test public void pojoToPojo() { - ApplicationContext context = new SpringApplicationBuilder(PojoToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + PojoToPojoStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); } @Test public void pojoToString() { - ApplicationContext context = new SpringApplicationBuilder(PojoToStringStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + PojoToStringStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals("oleg", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("oleg"); } @Test public void pojoToStringOutboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(PojoToStringStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.output.contentType=text/plain", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.TEXT_PLAIN, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals("oleg", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void pojoToByteArray() { - ApplicationContext context = new SpringApplicationBuilder(PojoToByteArrayStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals("oleg", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void pojoToByteArrayOutboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(PojoToByteArrayStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.output.contentType=text/plain", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals("oleg", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void stringToPojoInboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(StringToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void typelessToPojoInboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(TypelessToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void typelessToPojoInboundContentTypeBindingJson() { - ApplicationContext context = new SpringApplicationBuilder(TypelessToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.input.contentType=application/json", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void typelessMessageToPojoInboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(TypelessMessageToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void typelessMessageToPojoInboundContentTypeBindingJson() { - ApplicationContext context = new SpringApplicationBuilder(TypelessMessageToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.input.contentType=application/json", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void typelessToPojoWithTextHeaderContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(TypelessToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).setHeader(MessageHeaders.CONTENT_TYPE, MimeType.valueOf("text/plain")).build()); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void typelessToPojoOutboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(TypelessToMessageStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.output.contentType=text/plain", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).setHeader("contentType", new MimeType("text", "plain")).build()); - - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.TEXT_PLAIN, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void outboundMessageWithTextContentTypeOnly() { - ApplicationContext context = new SpringApplicationBuilder(TypelessToMessageTextOnlyContentTypeStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).setHeader("contentType", new MimeType("text")).build()); - - Message outputMessage = target.receive(); - assertEquals("text/plain", outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - - - @Test - public void stringToPojoInboundContentTypeHeader() { - ApplicationContext context = new SpringApplicationBuilder(StringToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes(), new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)))); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void byteArrayToPojoInboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(ByteArrayToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void byteArrayToPojoInboundContentTypeHeader() { - ApplicationContext context = new SpringApplicationBuilder(StringToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes(), new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)))); - Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void byteArrayToByteArray() { - ApplicationContext context = new SpringApplicationBuilder(ByteArrayToByteArrayStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - - @Test - public void byteArrayToByteArrayInboundOutboundContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(ByteArrayToByteArrayStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.bindings.input.contentType=text/plain", "--spring.cloud.stream.bindings.output.contentType=text/plain", + ApplicationContext context = new SpringApplicationBuilder( + PojoToStringStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.bindings.output.contentType=text/plain", "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.TEXT_PLAIN); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("oleg"); } - @Test - public void pojoMessageToStringMessage() { - ApplicationContext context = new SpringApplicationBuilder(PojoMessageToStringMessageStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + public void pojoToByteArray() { + ApplicationContext context = new SpringApplicationBuilder( + PojoToByteArrayStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.TEXT_PLAIN, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals("oleg", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("oleg"); + } + + @Test + public void pojoToByteArrayOutboundContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + PojoToByteArrayStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.bindings.output.contentType=text/plain", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("oleg"); + } + + @Test + public void stringToPojoInboundContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + StringToPojoStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void typelessToPojoInboundContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessToPojoStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void typelessToPojoInboundContentTypeBindingJson() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessToPojoStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.bindings.input.contentType=application/json", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void typelessMessageToPojoInboundContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessMessageToPojoStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void typelessMessageToPojoInboundContentTypeBindingJson() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessMessageToPojoStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.cloud.stream.bindings.input.contentType=application/json", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void typelessToPojoWithTextHeaderContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessToPojoStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(MessageBuilder.withPayload(jsonPayload.getBytes()) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeType.valueOf("text/plain")) + .build()); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void typelessToPojoOutboundContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessToMessageStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.bindings.output.contentType=text/plain", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(MessageBuilder.withPayload(jsonPayload.getBytes()) + .setHeader("contentType", new MimeType("text", "plain")).build()); + + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.TEXT_PLAIN); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void outboundMessageWithTextContentTypeOnly() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessToMessageTextOnlyContentTypeStreamListener.class) + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(MessageBuilder.withPayload(jsonPayload.getBytes()) + .setHeader("contentType", new MimeType("text")).build()); + + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()) + .isEqualTo("text/plain"); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void stringToPojoInboundContentTypeHeader() { + ApplicationContext context = new SpringApplicationBuilder( + StringToPojoStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes(), + new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, + MimeTypeUtils.TEXT_PLAIN)))); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void byteArrayToPojoInboundContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + ByteArrayToPojoStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void byteArrayToPojoInboundContentTypeHeader() { + ApplicationContext context = new SpringApplicationBuilder( + StringToPojoStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes(), + new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, + MimeTypeUtils.TEXT_PLAIN)))); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void byteArrayToByteArray() { + ApplicationContext context = new SpringApplicationBuilder( + ByteArrayToByteArrayStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void byteArrayToByteArrayInboundOutboundContentTypeBinding() { + ApplicationContext context = new SpringApplicationBuilder( + ByteArrayToByteArrayStreamListener.class).web(WebApplicationType.NONE) + .run("--spring.cloud.stream.bindings.input.contentType=text/plain", + "--spring.cloud.stream.bindings.output.contentType=text/plain", + "--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void pojoMessageToStringMessage() { + ApplicationContext context = new SpringApplicationBuilder( + PojoMessageToStringMessageStreamListener.class) + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.TEXT_PLAIN); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("oleg"); } @Test public void pojoMessageToStringMessageServiceActivator() { - ApplicationContext context = new SpringApplicationBuilder(PojoMessageToStringMessageServiceActivator.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + PojoMessageToStringMessageServiceActivator.class) + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.TEXT_PLAIN, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals("oleg", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.TEXT_PLAIN); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("oleg"); } @Test public void byteArrayMessageToStringJsonMessageStreamListener() { - ApplicationContext context = new SpringApplicationBuilder(ByteArrayMessageToStringJsonMessageStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + ByteArrayMessageToStringJsonMessageStreamListener.class) + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.APPLICATION_JSON, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals("{\"name\":\"bob\"}", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.APPLICATION_JSON); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("{\"name\":\"bob\"}"); } @Test public void byteArrayMessageToStringMessageStreamListener() { - ApplicationContext context = new SpringApplicationBuilder(StringMessageToStringMessageStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + StringMessageToStringMessageStreamListener.class) + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertEquals(MimeTypeUtils.TEXT_PLAIN, outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); - assertEquals("oleg", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeTypeUtils.TEXT_PLAIN); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("oleg"); } @Test @SuppressWarnings("deprecation") public void kryo_pojoToPojo() { - ApplicationContext context = new SpringApplicationBuilder(PojoToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.default.contentType=application/x-java-object", "--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + PojoToPojoStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.default.contentType=application/x-java-object", + "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); KryoMessageConverter converter = new KryoMessageConverter(null, true); @SuppressWarnings("unchecked") - Message message = (Message) converter - .toMessage(new Person("oleg"), new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, MessageConverterUtils.X_JAVA_OBJECT))); + Message message = (Message) converter.toMessage( + new Person("oleg"), + new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, + MessageConverterUtils.X_JAVA_OBJECT))); source.send(new GenericMessage<>(message.getPayload())); Message outputMessage = target.receive(); - assertNotNull(outputMessage); - MimeType contentType = (MimeType) outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE); - assertEquals("x-java-object", contentType.getSubtype()); - assertEquals(Person.class.getName(), contentType.getParameters().get("type")); + assertThat(outputMessage).isNotNull(); + MimeType contentType = (MimeType) outputMessage.getHeaders() + .get(MessageHeaders.CONTENT_TYPE); + assertThat(contentType.getSubtype()).isEqualTo("x-java-object"); + assertThat(contentType.getParameters().get("type")) + .isEqualTo(Person.class.getName()); } @Test @SuppressWarnings("deprecation") public void kryo_pojoToPojoContentTypeHeader() { - ApplicationContext context = new SpringApplicationBuilder(PojoToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.output.contentType=application/x-java-object"); + ApplicationContext context = new SpringApplicationBuilder( + PojoToPojoStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.jmx.enabled=false", + "--spring.cloud.stream.bindings.output.contentType=application/x-java-object"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); KryoMessageConverter converter = new KryoMessageConverter(null, true); @SuppressWarnings("unchecked") - Message message = (Message) converter - .toMessage(new Person("oleg"), new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, MessageConverterUtils.X_JAVA_OBJECT))); + Message message = (Message) converter.toMessage( + new Person("oleg"), + new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, + MessageConverterUtils.X_JAVA_OBJECT))); source.send(message); Message outputMessage = target.receive(); - assertNotNull(outputMessage); - MimeType contentType = (MimeType) outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE); - assertEquals("x-java-object", contentType.getSubtype()); + assertThat(outputMessage).isNotNull(); + MimeType contentType = (MimeType) outputMessage.getHeaders() + .get(MessageHeaders.CONTENT_TYPE); + assertThat(contentType.getSubtype()).isEqualTo("x-java-object"); } /** - * This test simply demonstrates how one can override an existing MessageConverter for a given contentType. - * In this case we are demonstrating how Kryo converter can be overriden ('application/x-java-object' maps to Kryo). + * This test simply demonstrates how one can override an existing MessageConverter for + * a given contentType. In this case we are demonstrating how Kryo converter can be + * overriden ('application/x-java-object' maps to Kryo). */ @Test public void overrideMessageConverter_defaultContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(StringToStringStreamListener.class, CustomConverters.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.default.contentType=application/x-java-object", "--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + StringToStringStreamListener.class, CustomConverters.class) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.default.contentType=application/x-java-object", + "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertNotNull(outputMessage); - System.out.println(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - assertEquals("AlwaysStringKryoMessageConverter", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - assertEquals(MimeType.valueOf("application/x-java-object"), outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); + assertThat(outputMessage).isNotNull(); + System.out + .println(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("AlwaysStringKryoMessageConverter"); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeType.valueOf("application/x-java-object")); } @Test public void customMessageConverter_defaultContentTypeBinding() { - ApplicationContext context = new SpringApplicationBuilder(StringToStringStreamListener.class, CustomConverters.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.default.contentType=foo/bar", "--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + StringToStringStreamListener.class, CustomConverters.class) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.default.contentType=foo/bar", + "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); Message outputMessage = target.receive(); - assertNotNull(outputMessage); - assertEquals("FooBarMessageConverter", new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - assertEquals(MimeType.valueOf("foo/bar"), outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)); + assertThat(outputMessage).isNotNull(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("FooBarMessageConverter"); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE)) + .isEqualTo(MimeType.valueOf("foo/bar")); } - //Failure tests + // Failure tests @Test public void _jsonToPojoWrongDefaultContentTypeProperty() { - ApplicationContext context = new SpringApplicationBuilder(PojoToPojoStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.default.contentType=text/plain", "--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + PojoToPojoStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.default.contentType=text/plain", + "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); TestChannelBinder binder = context.getBean(TestChannelBinder.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); - assertTrue(binder.getLastError().getPayload() instanceof MessagingException); + assertThat(binder.getLastError().getPayload() instanceof MessagingException) + .isTrue(); } @Test public void _toStringDefaultContentTypePropertyUnknownContentType() { - ApplicationContext context = new SpringApplicationBuilder(StringToStringStreamListener.class) - .web(WebApplicationType.NONE) - .run("--spring.cloud.stream.default.contentType=foo/bar", "--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + StringToStringStreamListener.class).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.default.contentType=foo/bar", + "--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); TestChannelBinder binder = context.getBean(TestChannelBinder.class); String jsonPayload = "{\"name\":\"oleg\"}"; source.send(new GenericMessage<>(jsonPayload.getBytes())); - assertTrue(binder.getLastError().getPayload() instanceof MessageConversionException); + assertThat( + binder.getLastError().getPayload() instanceof MessageConversionException) + .isTrue(); } - @Test public void toCollectionWithParameterizedType() { - ApplicationContext context = new SpringApplicationBuilder(CollectionWithParameterizedTypes.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); + ApplicationContext context = new SpringApplicationBuilder( + CollectionWithParameterizedTypes.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); String jsonPayload = "[{\"person\":{\"name\":\"jon\"},\"id\":123},{\"person\":{\"name\":\"jane\"},\"id\":456}]"; @@ -565,170 +634,303 @@ public class ContentTypeTckTests { assertThat(outputMessage.getPayload()).isEqualTo(jsonPayload.getBytes()); } + // ====== + @Test + public void testWithMapInputParameter() { + ApplicationContext context = new SpringApplicationBuilder( + MapInputConfiguration.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void testWithMapPayloadParameter() { + ApplicationContext context = new SpringApplicationBuilder( + MapInputConfiguration.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void testWithListInputParameter() { + ApplicationContext context = new SpringApplicationBuilder( + ListInputConfiguration.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "[\"foo\",\"bar\"]"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void testWithMessageHeadersInputParameter() { + ApplicationContext context = new SpringApplicationBuilder( + MessageHeadersInputConfiguration.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "{\"name\":\"oleg\"}"; + source.send(new GenericMessage<>(jsonPayload.getBytes())); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isNotEqualTo(jsonPayload); + assertThat(outputMessage.getHeaders().containsKey(MessageHeaders.ID)).isTrue(); + assertThat(outputMessage.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) + .isTrue(); + } + + @Test + public void testWithTypelessInputParameterAndOctetStream() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessPayloadConfiguration.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "[\"foo\",\"bar\"]"; + source.send(MessageBuilder.withPayload(jsonPayload.getBytes()) + .setHeader(MessageHeaders.CONTENT_TYPE, + MimeTypeUtils.APPLICATION_OCTET_STREAM) + .build()); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void testWithTypelessInputParameterAndServiceActivator() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessPayloadConfigurationSA.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "[\"foo\",\"bar\"]"; + source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).build()); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + + @Test + public void testWithTypelessMessageInputParameterAndServiceActivator() { + ApplicationContext context = new SpringApplicationBuilder( + TypelessPayloadConfigurationSA.class).web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "[\"foo\",\"bar\"]"; + source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).build()); + Message outputMessage = target.receive(); + assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo(jsonPayload); + } + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class CollectionWithParameterizedTypes { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public List> echo(List> value) { - assertTrue(value.get(0) != null); + assertThat(value.get(0) != null).isTrue(); return value; } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TextInJsonOutListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Message echo(String value) { - return MessageBuilder.withPayload(value).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON).build(); + return MessageBuilder.withPayload(value).setHeader( + MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON).build(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class PojoToPojoStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Person echo(Person value) { return value; } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class PojoToStringStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public String echo(Person value) { return value.toString(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class PojoToByteArrayStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public byte[] echo(Person value) { return value.toString().getBytes(StandardCharsets.UTF_8); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class ByteArrayToPojoStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Person echo(byte[] value) throws Exception { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(value, Person.class); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class StringToPojoStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Person echo(String value) throws Exception { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(value, Person.class); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TypelessToPojoStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Person echo(Object value) throws Exception { ObjectMapper mapper = new ObjectMapper(); - //assume it is string because CT is text/plain - return mapper.readValue((String)value, Person.class); + // assume it is string because CT is text/plain + return mapper.readValue((String) value, Person.class); } + } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TypelessMessageToPojoStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Person echo(Message message) throws Exception { ObjectMapper mapper = new ObjectMapper(); - //assume it is string because CT is text/plain - return mapper.readValue((String)message.getPayload(), Person.class); + // assume it is string because CT is text/plain + return mapper.readValue((String) message.getPayload(), Person.class); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TypelessToMessageStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Message echo(Object value) throws Exception { - return MessageBuilder.withPayload(value.toString()).setHeader("contentType", new MimeType("text", "plain")).build(); + return MessageBuilder.withPayload(value.toString()) + .setHeader("contentType", new MimeType("text", "plain")).build(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TypelessToMessageTextOnlyContentTypeStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Message echo(Object value) throws Exception { - return MessageBuilder.withPayload(value.toString()).setHeader("contentType", new MimeType("text")).build(); + return MessageBuilder.withPayload(value.toString()) + .setHeader("contentType", new MimeType("text")).build(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class ByteArrayToByteArrayStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public byte[] echo(byte[] value) { return value; } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class StringToStringStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) - public String echo(String value) { + public String echo(String value) { return value; } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration /* - * Uncomment to test MBean name quoting for ":" in bean name component of - * ObjectName. + * Uncomment to test MBean name quoting for ":" in bean name component of ObjectName. * Commented to avoid "InstanceAlreadyExistsException" in other tests. */ - // @EnableIntegrationMBeanExport + // @EnableIntegrationMBeanExport public static class StringToMapStreamListener { @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) - public String echo(@Payload Map value) { + public String echo(@Payload Map value) { return (String) value.get("name"); } @@ -742,52 +944,67 @@ public class ContentTypeTckTests { @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class StringToMapMessageStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) - public String echo(Message> value) { - assertTrue(value.getPayload() instanceof Map); + public String echo(Message> value) { + assertThat(value.getPayload() instanceof Map).isTrue(); return (String) value.getPayload().get("name"); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class PojoMessageToStringMessageStreamListener { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) - public Message echo(Message value) { - return MessageBuilder.withPayload(value.getPayload().toString()).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build(); + public Message echo(Message value) { + return MessageBuilder.withPayload(value.getPayload().toString()) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class PojoMessageToStringMessageServiceActivator { - @ServiceActivator(inputChannel=Processor.INPUT, outputChannel=Processor.OUTPUT) - public Message echo(Message value) { - return MessageBuilder.withPayload(value.getPayload().toString()).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build(); + + @ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) + public Message echo(Message value) { + return MessageBuilder.withPayload(value.getPayload().toString()) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class StringMessageToStringMessageStreamListener { - @ServiceActivator(inputChannel=Processor.INPUT, outputChannel=Processor.OUTPUT) + + @ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) public Message echo(Message value) throws Exception { ObjectMapper mapper = new ObjectMapper(); Person person = mapper.readValue(value.getPayload(), Person.class); - return MessageBuilder.withPayload(person.toString()).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build(); + return MessageBuilder.withPayload(person.toString()) + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class ByteArrayMessageToStringJsonMessageStreamListener { - @ServiceActivator(inputChannel=Processor.INPUT, outputChannel=Processor.OUTPUT) + + @ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) public Message echo(Message value) throws Exception { ObjectMapper mapper = new ObjectMapper(); Person person = mapper.readValue(value.getPayload(), Person.class); @@ -795,15 +1012,17 @@ public class ContentTypeTckTests { String json = mapper.writeValueAsString(person); return MessageBuilder.withPayload(json).build(); } + } @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class InternalPipeLine { + @StreamListener(Processor.INPUT) @SendTo("internalChannel") - public String handleA(Person value) { + public String handleA(Person value) { return "{\"name\":\"" + value.getName().toUpperCase() + "\"}"; } @@ -814,29 +1033,38 @@ public class ContentTypeTckTests { @StreamListener("internalChannel") @SendTo(Processor.OUTPUT) - public String handleB(Person value) { + public String handleB(Person value) { return value.toString(); } + } public static class Employee

{ + private P person; + private int id; + public int getId() { - return id; + return this.id; } + public void setId(int id) { this.id = id; } + public P getPerson() { - return person; + return this.person; } + public void setPerson(P person) { this.person = person; } + } public static class Person { + private String name; public Person() { @@ -848,7 +1076,7 @@ public class ContentTypeTckTests { } public String getName() { - return name; + return this.name; } public void setName(String name) { @@ -857,12 +1085,14 @@ public class ContentTypeTckTests { @Override public String toString() { - return name; + return this.name; } + } @Configuration public static class CustomConverters { + @Bean @StreamMessageConverter public FooBarMessageConverter fooBarMessageConverter() { @@ -872,16 +1102,19 @@ public class ContentTypeTckTests { @Bean @StreamMessageConverter public AlwaysStringKryoMessageConverter kryoOverrideMessageConverter() { - return new AlwaysStringKryoMessageConverter(MimeType.valueOf("application/x-java-object")); + return new AlwaysStringKryoMessageConverter( + MimeType.valueOf("application/x-java-object")); } /** - * Even though this MessageConverter has nothing to do with Kryo it still shows how Kryo - * conversion can be customized/overriden since it simply overriding a converter for - * contentType 'application/x-java-object' + * Even though this MessageConverter has nothing to do with Kryo it still shows + * how Kryo conversion can be customized/overriden since it simply overriding a + * converter for contentType 'application/x-java-object'. * */ - public static class AlwaysStringKryoMessageConverter extends AbstractMessageConverter { + public static class AlwaysStringKryoMessageConverter + extends AbstractMessageConverter { + public AlwaysStringKryoMessageConverter(MimeType supportedMimeType) { super(supportedMimeType); } @@ -892,211 +1125,136 @@ public class ContentTypeTckTests { } @Override - protected Object convertFromInternal( - Message message, Class targetClass, @Nullable Object conversionHint) { + protected Object convertFromInternal(Message message, Class targetClass, + @Nullable Object conversionHint) { return this.getClass().getSimpleName(); } + @Override - protected Object convertToInternal( - Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { - return ((String)payload).getBytes(StandardCharsets.UTF_8); + protected Object convertToInternal(Object payload, + @Nullable MessageHeaders headers, @Nullable Object conversionHint) { + return ((String) payload).getBytes(StandardCharsets.UTF_8); } + } public static class FooBarMessageConverter extends AbstractMessageConverter { + protected FooBarMessageConverter(MimeType supportedMimeType) { super(supportedMimeType); } + @Override protected boolean supports(Class clazz) { return clazz != null && String.class.isAssignableFrom(clazz); } @Override - protected Object convertFromInternal( - Message message, Class targetClass, @Nullable Object conversionHint) { + protected Object convertFromInternal(Message message, Class targetClass, + @Nullable Object conversionHint) { return this.getClass().getSimpleName(); } @Override - protected Object convertToInternal( - Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { - return ((String)payload).getBytes(StandardCharsets.UTF_8); + protected Object convertToInternal(Object payload, + @Nullable MessageHeaders headers, @Nullable Object conversionHint) { + return ((String) payload).getBytes(StandardCharsets.UTF_8); } } + } - //====== - @Test - public void testWithMapInputParameter() { - ApplicationContext context = new SpringApplicationBuilder(MapInputConfiguration.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class MapInputConfiguration { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Map echo(Map value) throws Exception { return value; } + } - - @Test - public void testWithMapPayloadParameter() { - ApplicationContext context = new SpringApplicationBuilder(MapInputConfiguration.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class MapPayloadConfiguration { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Map echo(Message> value) throws Exception { return value.getPayload(); } + } - - @Test - public void testWithListInputParameter() { - ApplicationContext context = new SpringApplicationBuilder(ListInputConfiguration.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "[\"foo\",\"bar\"]"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class ListInputConfiguration { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public List echo(List value) throws Exception { return value; } + } - - - @Test - public void testWithMessageHeadersInputParameter() { - ApplicationContext context = new SpringApplicationBuilder(MessageHeadersInputConfiguration.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "{\"name\":\"oleg\"}"; - source.send(new GenericMessage<>(jsonPayload.getBytes())); - Message outputMessage = target.receive(); - assertNotEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - assertTrue(outputMessage.getHeaders().containsKey(MessageHeaders.ID)); - assertTrue(outputMessage.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)); - } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class MessageHeadersInputConfiguration { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Map echo(MessageHeaders value) throws Exception { return value; } + } - - @Test - public void testWithTypelessInputParameterAndOctetStream() { - ApplicationContext context = new SpringApplicationBuilder(TypelessPayloadConfiguration.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "[\"foo\",\"bar\"]"; - source.send(MessageBuilder.withPayload(jsonPayload.getBytes()) - .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_OCTET_STREAM).build()); - Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TypelessPayloadConfiguration { + @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) public Object echo(Object value) throws Exception { System.out.println(value); return value; } + } - - @Test - public void testWithTypelessInputParameterAndServiceActivator() { - ApplicationContext context = new SpringApplicationBuilder(TypelessPayloadConfigurationSA.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "[\"foo\",\"bar\"]"; - source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).build()); - Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TypelessPayloadConfigurationSA { - @ServiceActivator(inputChannel=Processor.INPUT, outputChannel=Processor.OUTPUT) + + @ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) public Object echo(Object value) throws Exception { System.out.println(value); return value; } + } - - @Test - public void testWithTypelessMessageInputParameterAndServiceActivator() { - ApplicationContext context = new SpringApplicationBuilder(TypelessPayloadConfigurationSA.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); - String jsonPayload = "[\"foo\",\"bar\"]"; - source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).build()); - Message outputMessage = target.receive(); - assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); - } - + @EnableBinding(Processor.class) @Import(TestChannelBinderConfiguration.class) @EnableAutoConfiguration public static class TypelessMessageConfigurationSA { - @ServiceActivator(inputChannel=Processor.INPUT, outputChannel=Processor.OUTPUT) + + @ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) public Object echo(Message value) throws Exception { System.out.println(value.getPayload()); return value.getPayload(); } + } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/AbstractDestination.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/AbstractDestination.java index 5b094fe6f..4af02833d 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/AbstractDestination.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/AbstractDestination.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ abstract class AbstractDestination { private SubscribableChannel channel; SubscribableChannel getChannel() { - return channel; + return this.channel; } void setChannel(SubscribableChannel channel) { @@ -38,4 +38,5 @@ abstract class AbstractDestination { void afterChannelIsSet() { // noop } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/InputDestination.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/InputDestination.java index ec0523933..7125c3954 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/InputDestination.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/InputDestination.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,8 @@ package org.springframework.cloud.stream.binder.test; import org.springframework.messaging.Message; /** - * Implementation of binder endpoint that represents the source destination - * (e.g., destination from which messages will be received by Processor.INPUT). - *
+ * Implementation of binder endpoint that represents the source destination (e.g., + * destination from which messages will be received by Processor.INPUT).
* You can interact with it by calling {@link #send(Message)} operation. * * @author Oleg Zhurakousky @@ -30,11 +29,12 @@ import org.springframework.messaging.Message; public class InputDestination extends AbstractDestination { /** - * Allows the {@link Message} to be sent to a Binder to be delegated - * to binder's input destination (e.g., Processor.INPUT). - * + * Allows the {@link Message} to be sent to a Binder to be delegated to binder's input + * destination (e.g., Processor.INPUT). + * @param message message to send */ public void send(Message message) { this.getChannel().send(message); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/OutputDestination.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/OutputDestination.java index cadc998fc..aeeb3f6db 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/OutputDestination.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/OutputDestination.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-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. @@ -23,9 +23,8 @@ import java.util.concurrent.TimeUnit; import org.springframework.messaging.Message; /** - * Implementation of binder endpoint that represents the target destination - * (e.g., destination which receives messages sent to Processor.OUTPUT) - *
+ * Implementation of binder endpoint that represents the target destination (e.g., + * destination which receives messages sent to Processor.OUTPUT)
* You can interact with it by calling {@link #receive()} operation. * * @author Oleg Zhurakousky @@ -38,6 +37,7 @@ public class OutputDestination extends AbstractDestination { /** * Allows to access {@link Message}s received by this {@link OutputDestination}. * @param timeout how long to wait before giving up + * @return received message */ @SuppressWarnings("unchecked") public Message receive(long timeout) { @@ -52,6 +52,7 @@ public class OutputDestination extends AbstractDestination { /** * Allows to access {@link Message}s received by this {@link OutputDestination}. + * @return received message */ public Message receive() { return this.receive(0); @@ -60,6 +61,7 @@ public class OutputDestination extends AbstractDestination { @Override void afterChannelIsSet() { this.messages = new LinkedTransferQueue<>(); - this.getChannel().subscribe(message -> messages.offer(message)); + this.getChannel().subscribe(message -> this.messages.offer(message)); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/SampleStreamApp.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/SampleStreamApp.java index d1071babb..e21dea9fd 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/SampleStreamApp.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/SampleStreamApp.java @@ -35,10 +35,11 @@ import org.springframework.messaging.Message; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.support.GenericMessage; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; /** - * Sample spring cloud stream application that demonstrates the usage of {@link TestChannelBinder}. + * Sample spring cloud stream application that demonstrates the usage of + * {@link TestChannelBinder}. * * @author Oleg Zhurakousky * @author Gary Russell @@ -50,14 +51,15 @@ import static org.junit.Assert.assertEquals; public class SampleStreamApp { public static void main(String[] args) { - ApplicationContext context = new SpringApplicationBuilder(SampleStreamApp.class).web(WebApplicationType.NONE) - .run("--server.port=0"); + ApplicationContext context = new SpringApplicationBuilder(SampleStreamApp.class) + .web(WebApplicationType.NONE).run("--server.port=0"); InputDestination source = context.getBean(InputDestination.class); OutputDestination target = context.getBean(OutputDestination.class); source.send(new GenericMessage("Hello".getBytes())); Message message = target.receive(); - assertEquals("Hello", new String((byte[])message.getPayload(), StandardCharsets.UTF_8)); + assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_8)) + .isEqualTo("Hello"); } @Bean @@ -74,7 +76,7 @@ public class SampleStreamApp { return value; } - @ServiceActivator(inputChannel="input.anonymous.errors") + @ServiceActivator(inputChannel = "input.anonymous.errors") public void error(String value) { System.out.println("Handling ERROR payload: " + value); } @@ -87,5 +89,3 @@ public class SampleStreamApp { } } - - diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinder.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinder.java index c3a54bf34..b684471ad 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinder.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinder.java @@ -52,13 +52,13 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * Implementation of {@link Binder} backed by Spring Integration framework. - * It is useful for localized demos and testing. + * Implementation of {@link Binder} backed by Spring Integration framework. It is useful + * for localized demos and testing. *

* This binder extends from the same base class ({@link AbstractMessageChannelBinder}) as - * other binders (i.e., Rabbit, Kafka etc). Interaction with this binder is done via source - * and target destination which emulate real binder's destinations (i.e., Kafka topic) - *
+ * other binders (i.e., Rabbit, Kafka etc). Interaction with this binder is done via + * source and target destination which emulate real binder's destinations (i.e., Kafka + * topic)
* The destination classes are *

    *
  • {@link InputDestination}
  • @@ -66,9 +66,8 @@ import org.springframework.util.StringUtils; *
* Simply autowire them in your your application and send/receive messages. *

- * You must also add {@link TestChannelBinderConfiguration} to your configuration. - * Below is the example using Spring Boot test. - *
+ * You must also add {@link TestChannelBinderConfiguration} to your configuration. Below
+ * is the example using Spring Boot test. 
  *
  * @RunWith(SpringJUnit4ClassRunner.class)
  * @SpringBootTest(classes = {SpringIntegrationBinderConfiguration.class, TestWithSIBinder.MyProcessor.class})
@@ -81,8 +80,9 @@ import org.springframework.util.StringUtils;
  *
  *     @Test
  *     public void testWiring() {
- *         sourceDestination.send(new GenericMessage("Hello"));
- *         assertEquals("Hello world", new String((byte[])targetDestination.receive().getPayload(), StandardCharsets.UTF_8));
+ *         sourceDestination.send(new GenericMessage<String>("Hello"));
+ *         assertEquals("Hello world",
+ *             new String((byte[])targetDestination.receive().getPayload(), StandardCharsets.UTF_8));
  *     }
  *
  *     @SpringBootApplication
@@ -101,15 +101,16 @@ import org.springframework.util.StringUtils;
  * @author Gary Russell
  *
  */
-public class TestChannelBinder extends AbstractMessageChannelBinder {
+public class TestChannelBinder extends
+		AbstractMessageChannelBinder {
 
 	@Autowired
 	private BeanFactory beanFactory;
 
 	private Message lastError;
 
-	private MessageSource messageSourceDelegate = () -> new GenericMessage<>("polled data",
+	private MessageSource messageSourceDelegate = () -> new GenericMessage<>(
+			"polled data",
 			Collections.singletonMap(MessageHeaders.CONTENT_TYPE, "text/plain"));
 
 	public TestChannelBinder(TestChannelBinderProvisioner provisioningProvider) {
@@ -120,7 +121,7 @@ public class TestChannelBinder extends AbstractMessageChannelBinder messageSourceDelegate) {
 		this.messageSourceDelegate = messageSourceDelegate;
 	}
@@ -131,24 +132,29 @@ public class TestChannelBinder extends AbstractMessageChannelBinder 1) {
 			adapter.setRetryTemplate(buildRetryTemplate(properties));
 			adapter.setRecoveryCallback(errorInfrastructure.getRecoverer());
@@ -164,15 +170,16 @@ public class TestChannelBinder extends AbstractMessageChannelBinder {
 			this.logger.debug("Error handled: " + m);
 			this.lastError = m;
@@ -180,7 +187,8 @@ public class TestChannelBinder extends AbstractMessageChannelBinder> listener) {
 			this.listener = listener;
 		}
+
 	}
 
 	/**
-	 * Implementation of inbound channel adapter modeled after AmqpInboundChannelAdapter
+	 * Implementation of inbound channel adapter modeled after AmqpInboundChannelAdapter.
 	 */
-	private static class IntegrationBinderInboundChannelAdapter extends MessageProducerSupport {
+	private static class IntegrationBinderInboundChannelAdapter
+			extends MessageProducerSupport {
 
 		private static final ThreadLocal attributesHolder = new ThreadLocal();
 
@@ -209,13 +219,15 @@ public class TestChannelBinder extends AbstractMessageChannelBinder recoveryCallback;
 
-		IntegrationBinderInboundChannelAdapter(IntegrationMessageListeningContainer listenerContainer) {
+		IntegrationBinderInboundChannelAdapter(
+				IntegrationMessageListeningContainer listenerContainer) {
 			this.listenerContainer = listenerContainer;
 		}
 
 		@SuppressWarnings("unused")
 		// Temporarily unused until DLQ strategy for this binder becomes a requirement
-		public void setRecoveryCallback(RecoveryCallback recoveryCallback) {
+		public void setRecoveryCallback(
+				RecoveryCallback recoveryCallback) {
 			this.recoveryCallback = recoveryCallback;
 		}
 
@@ -226,9 +238,10 @@ public class TestChannelBinder extends AbstractMessageChannelBinder {
+						IntegrationBinderInboundChannelAdapter.this.retryTemplate
+								.execute(context -> {
 									processMessage(message);
 									return null;
-								},
-								(RecoveryCallback) IntegrationBinderInboundChannelAdapter.this.recoveryCallback);
+								}, (RecoveryCallback) IntegrationBinderInboundChannelAdapter.this.recoveryCallback);
 					}
 				}
 				catch (RuntimeException e) {
 					if (getErrorChannel() != null) {
-						getMessagingTemplate().send(getErrorChannel(), buildErrorMessage(null,
-								new IllegalStateException("Message conversion failed: " + message, e)));
+						getMessagingTemplate()
+								.send(getErrorChannel(),
+										buildErrorMessage(null, new IllegalStateException(
+												"Message conversion failed: " + message,
+												e)));
 					}
 					else {
 						throw e;
@@ -275,7 +291,8 @@ public class TestChannelBinder extends AbstractMessageChannelBinder boolean open(RetryContext context, RetryCallback callback) {
+			public  boolean open(RetryContext context,
+					RetryCallback callback) {
 				if (IntegrationBinderInboundChannelAdapter.this.recoveryCallback != null) {
 					attributesHolder.set(context);
 				}
@@ -283,16 +300,19 @@ public class TestChannelBinder extends AbstractMessageChannelBinder void close(RetryContext context, RetryCallback callback,
-					Throwable throwable) {
+			public  void close(RetryContext context,
+					RetryCallback callback, Throwable throwable) {
 				attributesHolder.remove();
 			}
 
 			@Override
-			public  void onError(RetryContext context, RetryCallback callback,
-					Throwable throwable) {
+			public  void onError(RetryContext context,
+					RetryCallback callback, Throwable throwable) {
 				// Empty
 			}
+
 		}
+
 	}
+
 }
diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderConfiguration.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderConfiguration.java
index c00cc35b2..e1ea23411 100644
--- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderConfiguration.java
+++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderConfiguration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-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.
@@ -38,8 +38,8 @@ import org.springframework.integration.config.EnableIntegration;
  *
  * Please see {@link TestChannelBinder} for more details.
  *
+ * @param  binding type
  * @author Oleg Zhurakousky
- *
  * @see TestChannelBinder
  */
 @Configuration
@@ -50,18 +50,25 @@ public class TestChannelBinderConfiguration {
 	public static final String NAME = "integration";
 
 	/**
-	 * Utility operation to return an array of configuration classes
-	 * defined in {@link EnableBinding} annotation.
-	 * Typically used for tests that do not rely on creating an SCSt boot
-	 * application annotated with {@link EnableBinding}, yet require
+	 * Utility operation to return an array of configuration classes defined in
+	 * {@link EnableBinding} annotation. Typically used for tests that do not rely on
+	 * creating an SCSt boot application annotated with {@link EnableBinding}, yet require
 	 * full {@link Binder} configuration.
+	 * @param additionalConfigurationClasses config classes to be added to the default
+	 * config
+	 * @return an array of configuration classes defined in {@link EnableBinding}
+	 * annotation
 	 */
-	public static Class[] getCompleteConfiguration(Class... additionalConfigurationClasses) {
+	public static Class[] getCompleteConfiguration(
+			Class... additionalConfigurationClasses) {
 		List> configClasses = new ArrayList<>();
 		configClasses.add(TestChannelBinderConfiguration.class);
-		Import annotation = AnnotationUtils.getAnnotation(EnableBinding.class, Import.class);
-		Map annotationAttributes = AnnotationUtils.getAnnotationAttributes(annotation);
-		configClasses.addAll(Arrays.asList((Class[])annotationAttributes.get("value")));
+		Import annotation = AnnotationUtils.getAnnotation(EnableBinding.class,
+				Import.class);
+		Map annotationAttributes = AnnotationUtils
+				.getAnnotationAttributes(annotation);
+		configClasses
+				.addAll(Arrays.asList((Class[]) annotationAttributes.get("value")));
 		configClasses.add(BindingServiceConfiguration.class);
 		if (additionalConfigurationClasses != null) {
 			configClasses.addAll(Arrays.asList(additionalConfigurationClasses));
@@ -81,8 +88,10 @@ public class TestChannelBinderConfiguration {
 
 	@SuppressWarnings("unchecked")
 	@Bean
-	public Binder springIntegrationChannelBinder(TestChannelBinderProvisioner provisioner) {
-		return (Binder) new TestChannelBinder(provisioner);
+	public Binder springIntegrationChannelBinder(
+			TestChannelBinderProvisioner provisioner) {
+		return (Binder) new TestChannelBinder(
+				provisioner);
 	}
 
 	@Bean
diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderProvisioner.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderProvisioner.java
index 5fc05c112..5be8b4e72 100644
--- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderProvisioner.java
+++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/test/TestChannelBinderProvisioner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,15 +34,16 @@ import org.springframework.messaging.Message;
 import org.springframework.messaging.SubscribableChannel;
 
 /**
- * {@link ProvisioningProvider} to support {@link TestChannelBinder}. It
- * exists primarily to support {@link AbstractMessageChannel} semantics for creating
+ * {@link ProvisioningProvider} to support {@link TestChannelBinder}. It exists primarily
+ * to support {@link AbstractMessageChannel} semantics for creating
  * {@link ConsumerDestination} and {@link ProducerDestination}, to interact with this
  * {@link Binder}.
  *
  * @author Oleg Zhurakousky
  *
  */
-public class TestChannelBinderProvisioner implements ProvisioningProvider {
+public class TestChannelBinderProvisioner
+		implements ProvisioningProvider {
 
 	private final Map provisionedDestinations = new HashMap<>();
 
@@ -53,24 +54,25 @@ public class TestChannelBinderProvisioner implements ProvisioningProvider
-	 * This provides convenience of registering additional subscriber (handler in the test method)
-	 * along side of being able to call {@link OutputDestination#receive()} to get a
-	 * {@link Message} for additional assertions.
+	 * Will provision producer destination as an SI {@link PublishSubscribeChannel}. 
+ * This provides convenience of registering additional subscriber (handler in the test + * method) along side of being able to call {@link OutputDestination#receive()} to get + * a {@link Message} for additional assertions. */ @Override - public ProducerDestination provisionProducerDestination(String name, ProducerProperties properties) throws ProvisioningException { + public ProducerDestination provisionProducerDestination(String name, + ProducerProperties properties) throws ProvisioningException { SubscribableChannel destination = this.provisionDestination(name, true); this.target.setChannel(destination); return new SpringIntegrationProducerDestination(name, destination); } /** - * Will provision consumer destination as SI {@link DirectChannel} + * Will provision consumer destination as SI {@link DirectChannel}. */ @Override - public ConsumerDestination provisionConsumerDestination(String name, String group, ConsumerProperties properties) throws ProvisioningException { + public ConsumerDestination provisionConsumerDestination(String name, String group, + ConsumerProperties properties) throws ProvisioningException { SubscribableChannel destination = this.provisionDestination(name, false); if (this.source != null) { this.source.setChannel(destination); @@ -80,18 +82,21 @@ public class TestChannelBinderProvisioner implements ProvisioningProvider bindables = new HashMap<>(); Bindable bindableWithTwo = new Bindable() { - public Collection> createAndBindInputs(BindingService adapter) { + public Collection> createAndBindInputs( + BindingService adapter) { return Arrays.asList(mock(Binding.class), mock(Binding.class)); } }; Bindable bindableWithThree = new Bindable() { - public Collection> createAndBindInputs(BindingService adapter) { - return Arrays.asList(mock(Binding.class), mock(Binding.class), mock(Binding.class)); + public Collection> createAndBindInputs( + BindingService adapter) { + return Arrays.asList(mock(Binding.class), mock(Binding.class), + mock(Binding.class)); } }; - Bindable bindableEmpty = new Bindable() {}; + Bindable bindableEmpty = new Bindable() { + }; bindables.put("two", bindableWithTwo); bindables.put("empty", bindableEmpty); bindables.put("three", bindableWithThree); - InputBindingLifecycle lifecycle = new InputBindingLifecycle(mock(BindingService.class), bindables); + InputBindingLifecycle lifecycle = new InputBindingLifecycle( + mock(BindingService.class), bindables); lifecycle.start(); - Collection> lifecycleInputBindings = - (Collection>) new DirectFieldAccessor(lifecycle).getPropertyValue("inputBindings"); - assertTrue(lifecycleInputBindings.size() == 5); + Collection> lifecycleInputBindings = (Collection>) new DirectFieldAccessor( + lifecycle).getPropertyValue("inputBindings"); + assertThat(lifecycleInputBindings.size() == 5).isTrue(); lifecycle.stop(); } @@ -70,27 +74,33 @@ public class BindingLifecycleTests { Map bindables = new HashMap<>(); Bindable bindableWithTwo = new Bindable() { - public Collection> createAndBindOutputs(BindingService adapter) { + public Collection> createAndBindOutputs( + BindingService adapter) { return Arrays.asList(mock(Binding.class), mock(Binding.class)); } }; Bindable bindableWithThree = new Bindable() { - public Collection> createAndBindOutputs(BindingService adapter) { - return Arrays.asList(mock(Binding.class), mock(Binding.class), mock(Binding.class)); + public Collection> createAndBindOutputs( + BindingService adapter) { + return Arrays.asList(mock(Binding.class), mock(Binding.class), + mock(Binding.class)); } }; - Bindable bindableEmpty = new Bindable() {}; + Bindable bindableEmpty = new Bindable() { + }; bindables.put("two", bindableWithTwo); bindables.put("empty", bindableEmpty); bindables.put("three", bindableWithThree); - OutputBindingLifecycle lifecycle = new OutputBindingLifecycle(mock(BindingService.class), bindables); + OutputBindingLifecycle lifecycle = new OutputBindingLifecycle( + mock(BindingService.class), bindables); lifecycle.start(); - Collection> lifecycleOutputBindings = - (Collection>) new DirectFieldAccessor(lifecycle).getPropertyValue("outputBindings"); - assertTrue(lifecycleOutputBindings.size() == 5); + Collection> lifecycleOutputBindings = (Collection>) new DirectFieldAccessor( + lifecycle).getPropertyValue("outputBindings"); + assertThat(lifecycleOutputBindings.size() == 5).isTrue(); lifecycle.stop(); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/BindingServiceTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/BindingServiceTests.java index 99a850990..7028868d1 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/BindingServiceTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/BindingServiceTests.java @@ -82,8 +82,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -151,8 +150,7 @@ public class BindingServiceTests { DefaultBinderFactory binderFactory = createMockBinderFactory(); Binder binder = binderFactory.getBinder("mock", MessageChannel.class); - BindingService service = new BindingService(properties, - binderFactory); + BindingService service = new BindingService(properties, binderFactory); MessageChannel inputChannel = new DirectChannel(); Binding mockBinding1 = Mockito.mock(Binding.class); @@ -206,8 +204,7 @@ public class BindingServiceTests { DefaultBinderFactory binderFactory = createMockBinderFactory(); Binder binder = binderFactory.getBinder("mock", MessageChannel.class); - BindingService service = new BindingService(properties, - binderFactory); + BindingService service = new BindingService(properties, binderFactory); MessageChannel inputChannel = new DirectChannel(); Binding mockBinding1 = Mockito.mock(Binding.class); @@ -246,8 +243,7 @@ public class BindingServiceTests { properties.setBindings(bindingProperties); DefaultBinderFactory binderFactory = createMockBinderFactory(); Binder binder = binderFactory.getBinder("mock", MessageChannel.class); - BindingService service = new BindingService(properties, - binderFactory); + BindingService service = new BindingService(properties, binderFactory); MessageChannel inputChannel = new DirectChannel(); Binding mockBinding = Mockito.mock(Binding.class); when(binder.bindConsumer(eq("foo"), eq("fooGroup"), same(inputChannel), @@ -283,19 +279,20 @@ public class BindingServiceTests { BindingService bindingService = new BindingService(properties, binderFactory) { @Override - protected Binder getBinder(String channelName, Class bindableType) { + protected Binder getBinder(String channelName, + Class bindableType) { return binder; } }; - SubscribableChannelBindingTargetFactory bindableSubscribableChannelFactory = - new SubscribableChannelBindingTargetFactory( - new MessageConverterConfigurer(properties, new CompositeMessageConverterFactory())); + SubscribableChannelBindingTargetFactory bindableSubscribableChannelFactory; + bindableSubscribableChannelFactory = new SubscribableChannelBindingTargetFactory( + new MessageConverterConfigurer(properties, + new CompositeMessageConverterFactory())); final AtomicBoolean callbackInvoked = new AtomicBoolean(); BinderAwareChannelResolver resolver = new BinderAwareChannelResolver( bindingService, bindableSubscribableChannelFactory, - new DynamicDestinationsBindable(), - (name, channel, props, extended) -> { + new DynamicDestinationsBindable(), (name, channel, props, extended) -> { callbackInvoked.set(true); assertThat(name).isEqualTo("foo"); assertThat(channel).isNotNull(); @@ -304,7 +301,8 @@ public class BindingServiceTests { props.setUseNativeEncoding(true); extendedProps.setProperty("bar", "baz"); }); - ConfigurableListableBeanFactory beanFactory = mock(ConfigurableListableBeanFactory.class); + ConfigurableListableBeanFactory beanFactory = mock( + ConfigurableListableBeanFactory.class); when(beanFactory.getBean("foo", MessageChannel.class)) .thenThrow(new NoSuchBeanDefinitionException(MessageChannel.class)); when(beanFactory.getBean("bar", MessageChannel.class)) @@ -329,22 +327,25 @@ public class BindingServiceTests { resolver.setBeanFactory(beanFactory); MessageChannel resolved = resolver.resolveDestination("foo"); assertThat(resolved).isSameAs(dynamic.get()); - ArgumentCaptor captor = ArgumentCaptor.forClass(ProducerProperties.class); + ArgumentCaptor captor = ArgumentCaptor + .forClass(ProducerProperties.class); verify(binder).bindProducer(eq("foo"), eq(dynamic.get()), captor.capture()); assertThat(captor.getValue().isUseNativeEncoding()).isTrue(); assertThat(captor.getValue()).isInstanceOf(ExtendedProducerProperties.class); - assertThat(((ExtendedProducerProperties) captor.getValue()).getExtension()).isSameAs(extendedProps); + assertThat(((ExtendedProducerProperties) captor.getValue()).getExtension()) + .isSameAs(extendedProps); doReturn(dynamic.get()).when(beanFactory).getBean("foo", MessageChannel.class); properties.setDynamicDestinations(new String[] { "foo" }); resolved = resolver.resolveDestination("foo"); assertThat(resolved).isSameAs(dynamic.get()); properties.setDynamicDestinations(new String[] { "test" }); try { - resolved = resolver.resolveDestination("bar"); - fail(); + resolver.resolveDestination("bar"); + fail("Should throw an exception"); } catch (DestinationResolutionException e) { - assertThat(e).hasMessageContaining("Failed to find MessageChannel bean with name 'bar'"); + assertThat(e).hasMessageContaining( + "Failed to find MessageChannel bean with name 'bar'"); } } @@ -368,13 +369,15 @@ public class BindingServiceTests { fail("Producer properties should be validated."); } catch (IllegalStateException e) { - assertThat(e).hasMessageContaining("Partition count should be greater than zero."); + assertThat(e) + .hasMessageContaining("Partition count should be greater than zero."); } } @Test public void testDefaultPropertyBehavior() { - ConfigurableApplicationContext run = SpringApplication.run(DefaultConsumerPropertiesTestSink.class, + ConfigurableApplicationContext run = SpringApplication.run( + DefaultConsumerPropertiesTestSink.class, "--spring.cloud.stream.default.contentType=text/plain", "--spring.cloud.stream.bindings.input1.contentType=application/json", "--spring.cloud.stream.default.group=foo", @@ -386,10 +389,10 @@ public class BindingServiceTests { "--spring.cloud.stream.bindings.output2.producer.partitionCount=1", "--spring.cloud.stream.bindings.inputXyz.contentType=application/json", "--spring.cloud.stream.bindings.inputFooBar.contentType=application/avro", - "--spring.cloud.stream.bindings.input_snake_case.contentType=application/avro" - ); + "--spring.cloud.stream.bindings.input_snake_case.contentType=application/avro"); - BindingServiceProperties bindingServiceProperties = run.getBeanFactory().getBean(BindingServiceProperties.class); + BindingServiceProperties bindingServiceProperties = run.getBeanFactory() + .getBean(BindingServiceProperties.class); Map bindings = bindingServiceProperties.getBindings(); assertThat(bindings.get("input1").getContentType()).isEqualTo("application/json"); @@ -400,49 +403,19 @@ public class BindingServiceTests { assertThat(bindings.get("input2").getConsumer().getConcurrency()).isEqualTo(1); assertThat(bindings.get("input1").getConsumer().isPartitioned()).isEqualTo(true); assertThat(bindings.get("input2").getConsumer().isPartitioned()).isEqualTo(false); - assertThat(bindings.get("output1").getProducer().getPartitionCount()).isEqualTo(10); - assertThat(bindings.get("output2").getProducer().getPartitionCount()).isEqualTo(1); + assertThat(bindings.get("output1").getProducer().getPartitionCount()) + .isEqualTo(10); + assertThat(bindings.get("output2").getProducer().getPartitionCount()) + .isEqualTo(1); - assertThat(bindings.get("inputXyz").getContentType()).isEqualTo("application/json"); - assertThat(bindings.get("inputFooBar").getContentType()).isEqualTo("application/avro"); - assertThat(bindings.get("inputFooBarBuzz").getContentType()).isEqualTo("text/plain"); - assertThat(bindings.get("input_snake_case").getContentType()).isEqualTo("application/avro"); - } - - @EnableBinding(FooBinding.class) - @EnableAutoConfiguration - public static class DefaultConsumerPropertiesTestSink { - @Bean - public Binder binder() { - return Mockito.mock(Binder.class, Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)); - } - } - - public interface FooBinding { - - @Input("input1") - SubscribableChannel in1(); - - @Input("input2") - SubscribableChannel in2(); - - @Output("output1") - MessageChannel out1(); - - @Output("output2") - MessageChannel out2(); - - @Input("inputXyz") - SubscribableChannel inXyz(); - - @Input("inputFooBar") - SubscribableChannel inFooBar(); - - @Input("inputFooBarBuzz") - SubscribableChannel inFooBarBuzz(); - - @Input("input_snake_case") - SubscribableChannel inWithSnakeCase(); + assertThat(bindings.get("inputXyz").getContentType()) + .isEqualTo("application/json"); + assertThat(bindings.get("inputFooBar").getContentType()) + .isEqualTo("application/avro"); + assertThat(bindings.get("inputFooBarBuzz").getContentType()) + .isEqualTo("text/plain"); + assertThat(bindings.get("input_snake_case").getContentType()) + .isEqualTo("application/avro"); } @Test @@ -458,15 +431,15 @@ public class BindingServiceTests { bindingProperties.put(inputChannelName, props); serviceProperties.setBindings(bindingProperties); DefaultBinderFactory binderFactory = createMockBinderFactory(); - BindingService service = new BindingService(serviceProperties, - binderFactory); + BindingService service = new BindingService(serviceProperties, binderFactory); MessageChannel inputChannel = new DirectChannel(); try { service.bindConsumer(inputChannel, inputChannelName); fail("Consumer properties should be validated."); } catch (IllegalStateException e) { - assertThat(e).hasMessageContaining("Concurrency should be greater than zero."); + assertThat(e) + .hasMessageContaining("Concurrency should be greater than zero."); } } @@ -477,7 +450,8 @@ public class BindingServiceTests { properties.put("spring.cloud.stream.bindings.input.binder", "mock"); properties.put("spring.cloud.stream.bindings.output.destination", "fooOutput"); properties.put("spring.cloud.stream.bindings.output.binder", "mockError"); - BindingServiceProperties bindingServiceProperties = createBindingServiceProperties(properties); + BindingServiceProperties bindingServiceProperties = createBindingServiceProperties( + properties); BindingService bindingService = new BindingService(bindingServiceProperties, createMockBinderFactory()); bindingService.bindConsumer(new DirectChannel(), "input"); @@ -498,7 +472,8 @@ public class BindingServiceTests { properties.put("spring.cloud.stream.defaultBinder", "mock1"); properties.put("spring.cloud.stream.binders.mock1.type", "mock"); properties.put("spring.cloud.stream.binders.kafka1.type", "kafka"); - BindingServiceProperties bindingServiceProperties = createBindingServiceProperties(properties); + BindingServiceProperties bindingServiceProperties = createBindingServiceProperties( + properties); BinderFactory binderFactory = new BindingServiceConfiguration() .binderFactory(createMockBinderTypeRegistry(), bindingServiceProperties); BindingService bindingService = new BindingService(bindingServiceProperties, @@ -516,7 +491,8 @@ public class BindingServiceTests { properties.put("spring.cloud.stream.bindings.output.type", "kafka1"); properties.put("spring.cloud.stream.binders.mock1.type", "mock"); properties.put("spring.cloud.stream.binders.kafka1.type", "kafka"); - BindingServiceProperties bindingServiceProperties = createBindingServiceProperties(properties); + BindingServiceProperties bindingServiceProperties = createBindingServiceProperties( + properties); BinderFactory binderFactory = new BindingServiceConfiguration() .binderFactory(createMockBinderTypeRegistry(), bindingServiceProperties); BindingService bindingService = new BindingService(bindingServiceProperties, @@ -533,7 +509,8 @@ public class BindingServiceTests { @Test public void testResolveBindableType() { - Class bindableType = GenericsUtils.getParameterType(FooBinder.class, Binder.class, 0); + Class bindableType = GenericsUtils.getParameterType(FooBinder.class, + Binder.class, 0); assertThat(bindableType).isSameAs(SomeBindableType.class); } @@ -563,12 +540,14 @@ public class BindingServiceTests { throw new RuntimeException("fail"); } return mockBinding; - }).when(binder).bindConsumer(eq("foo"), isNull(), same(inputChannel), any(ConsumerProperties.class)); - Collection> bindings = service.bindConsumer(inputChannel, inputChannelName); + }).when(binder).bindConsumer(eq("foo"), isNull(), same(inputChannel), + any(ConsumerProperties.class)); + Collection> bindings = service.bindConsumer(inputChannel, + inputChannelName); assertThat(fail.await(10, TimeUnit.SECONDS)).isTrue(); assertThat(bindings).hasSize(1); - Binding delegate = TestUtils.getPropertyValue(bindings.iterator().next(), "delegate", - Binding.class); + Binding delegate = TestUtils + .getPropertyValue(bindings.iterator().next(), "delegate", Binding.class); int n = 0; while (n++ < 300 && delegate == null) { Thread.sleep(400); @@ -606,8 +585,10 @@ public class BindingServiceTests { throw new RuntimeException("fail"); } return mockBinding; - }).when(binder).bindProducer(eq("foo"), same(outputChannel), any(ProducerProperties.class)); - Binding binding = service.bindProducer(outputChannel, outputChannelName); + }).when(binder).bindProducer(eq("foo"), same(outputChannel), + any(ProducerProperties.class)); + Binding binding = service.bindProducer(outputChannel, + outputChannelName); assertThat(fail.await(10, TimeUnit.SECONDS)).isTrue(); assertThat(binding).isNotNull(); Binding delegate = TestUtils.getPropertyValue(binding, "delegate", Binding.class); @@ -618,7 +599,8 @@ public class BindingServiceTests { } assertThat(delegate).isSameAs(mockBinding); service.unbindProducers(outputChannelName); - verify(binder, times(2)).bindProducer(eq("foo"), same(outputChannel), any(ProducerProperties.class)); + verify(binder, times(2)).bindProducer(eq("foo"), same(outputChannel), + any(ProducerProperties.class)); verify(delegate).unbind(); binderFactory.destroy(); scheduler.destroy(); @@ -628,30 +610,23 @@ public class BindingServiceTests { @Test public void testBindingAutostartup() throws Exception { ApplicationContext context = new SpringApplicationBuilder(FooConfiguration.class) - .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.input.consumer.auto-startup=false"); + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", + "--spring.cloud.stream.bindings.input.consumer.auto-startup=false"); BindingService bindingService = context.getBean(BindingService.class); - Field cbField = ReflectionUtils.findField(BindingService.class, "consumerBindings"); + Field cbField = ReflectionUtils.findField(BindingService.class, + "consumerBindings"); cbField.setAccessible(true); Map cbMap = (Map) cbField.get(bindingService); - Binding inputBinding = ((List>)cbMap.get("input")).get(0); - assertFalse(inputBinding.isRunning()); - } - - @EnableBinding(Sink.class) - @Import(TestChannelBinderConfiguration.class) - @EnableAutoConfiguration - public static class FooConfiguration { - @ServiceActivator(inputChannel=Processor.INPUT) - public void echo(Message value) throws Exception { - } + Binding inputBinding = ((List>) cbMap.get("input")).get(0); + assertThat(inputBinding.isRunning()).isFalse(); } private DefaultBinderFactory createMockBinderFactory() { BinderTypeRegistry binderTypeRegistry = createMockBinderTypeRegistry(); return new DefaultBinderFactory( - Collections.singletonMap("mock", new BinderConfiguration("mock", new HashMap<>(), true, true)), + Collections.singletonMap("mock", + new BinderConfiguration("mock", new HashMap<>(), true, true)), binderTypeRegistry); } @@ -660,15 +635,72 @@ public class BindingServiceTests { new BinderType("mock", new Class[] { MockBinderConfiguration.class }))); } - private BindingServiceProperties createBindingServiceProperties(HashMap properties) { + private BindingServiceProperties createBindingServiceProperties( + HashMap properties) { BindingServiceProperties bindingServiceProperties = new BindingServiceProperties(); - org.springframework.boot.context.properties.bind.Binder propertiesBinder = new org.springframework.boot.context.properties.bind.Binder(new MapConfigurationPropertySource(properties)); - propertiesBinder.bind("spring.cloud.stream", org.springframework.boot.context.properties.bind.Bindable.ofInstance(bindingServiceProperties)); + org.springframework.boot.context.properties.bind.Binder propertiesBinder; + propertiesBinder = new org.springframework.boot.context.properties.bind.Binder( + new MapConfigurationPropertySource(properties)); + propertiesBinder.bind("spring.cloud.stream", + org.springframework.boot.context.properties.bind.Bindable + .ofInstance(bindingServiceProperties)); return bindingServiceProperties; } + public interface FooBinding { + + @Input("input1") + SubscribableChannel in1(); + + @Input("input2") + SubscribableChannel in2(); + + @Output("output1") + MessageChannel out1(); + + @Output("output2") + MessageChannel out2(); + + @Input("inputXyz") + SubscribableChannel inXyz(); + + @Input("inputFooBar") + SubscribableChannel inFooBar(); + + @Input("inputFooBarBuzz") + SubscribableChannel inFooBarBuzz(); + + @Input("input_snake_case") + SubscribableChannel inWithSnakeCase(); + + } + + @EnableBinding(FooBinding.class) + @EnableAutoConfiguration + public static class DefaultConsumerPropertiesTestSink { + + @Bean + public Binder binder() { + return Mockito.mock(Binder.class, + Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)); + } + + } + + @EnableBinding(Sink.class) + @Import(TestChannelBinderConfiguration.class) + @EnableAutoConfiguration + public static class FooConfiguration { + + @ServiceActivator(inputChannel = Processor.INPUT) + public void echo(Message value) throws Exception { + } + + } + public static class FooBinder implements Binder { + @Override public Binding bindConsumer(String name, String group, SomeBindableType inboundBindTarget, @@ -682,9 +714,11 @@ public class BindingServiceTests { ProducerProperties producerProperties) { throw new UnsupportedOperationException(); } + } public static class SomeBindableType { + } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/CustomPartitionedProducerTest.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/CustomPartitionedProducerTest.java index f9633e32a..9c27a380c 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/CustomPartitionedProducerTest.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/CustomPartitionedProducerTest.java @@ -18,7 +18,6 @@ package org.springframework.cloud.stream.binding; import java.lang.reflect.Field; -import org.junit.Assert; import org.junit.Test; import org.springframework.boot.SpringApplication; @@ -42,6 +41,8 @@ import org.springframework.messaging.MessagingException; import org.springframework.messaging.support.ChannelInterceptor; import org.springframework.util.ReflectionUtils; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Ilayaperumal Gopinathan * @author Oleg Zhurakousky @@ -50,133 +51,150 @@ public class CustomPartitionedProducerTest { @Test public void testCustomPartitionedProducer() { - ApplicationContext context = SpringApplication.run(CustomPartitionedProducerTest.TestSource.class, - "--spring.jmx.enabled=false", - "--spring.main.web-application-type=none", - "--spring.cloud.stream.bindings.output.producer.partitionKeyExtractorClass=org.springframework.cloud.stream.partitioning.CustomPartitionKeyExtractorClass", - "--spring.cloud.stream.bindings.output.producer.partitionSelectorClass=org.springframework.cloud.stream.partitioning.CustomPartitionSelectorClass", + ApplicationContext context = SpringApplication.run( + CustomPartitionedProducerTest.TestSource.class, + "--spring.jmx.enabled=false", "--spring.main.web-application-type=none", + "--spring.cloud.stream.bindings.output.producer.partitionKeyExtractorClass=" + + "org.springframework.cloud.stream.partitioning.CustomPartitionKeyExtractorClass", + "--spring.cloud.stream.bindings.output.producer.partitionSelectorClass=" + + "org.springframework.cloud.stream.partitioning.CustomPartitionSelectorClass", "--spring.cloud.stream.default-binder=mock"); Source testSource = context.getBean(Source.class); DirectChannel messageChannel = (DirectChannel) testSource.output(); - for (ChannelInterceptor channelInterceptor : messageChannel.getChannelInterceptors()) { + for (ChannelInterceptor channelInterceptor : messageChannel + .getChannelInterceptors()) { if (channelInterceptor instanceof MessageConverterConfigurer.PartitioningInterceptor) { - Field partitionHandlerField = ReflectionUtils - .findField(MessageConverterConfigurer.PartitioningInterceptor.class, "partitionHandler"); + Field partitionHandlerField = ReflectionUtils.findField( + MessageConverterConfigurer.PartitioningInterceptor.class, + "partitionHandler"); ReflectionUtils.makeAccessible(partitionHandlerField); - PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils.getField(partitionHandlerField, - channelInterceptor); - Field partitonKeyExtractorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionKeyExtractorStrategy"); + PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils + .getField(partitionHandlerField, channelInterceptor); + Field partitonKeyExtractorField = ReflectionUtils.findField( + PartitionHandler.class, "partitionKeyExtractorStrategy"); ReflectionUtils.makeAccessible(partitonKeyExtractorField); - Field partitonSelectorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionSelectorStrategy"); + Field partitonSelectorField = ReflectionUtils + .findField(PartitionHandler.class, "partitionSelectorStrategy"); ReflectionUtils.makeAccessible(partitonSelectorField); - Assert.assertTrue(((PartitionKeyExtractorStrategy) ReflectionUtils.getField(partitonKeyExtractorField, - partitionHandler)).getClass().equals(CustomPartitionKeyExtractorClass.class)); - Assert.assertTrue( - ((PartitionSelectorStrategy) ReflectionUtils.getField(partitonSelectorField, partitionHandler)) - .getClass().equals(CustomPartitionSelectorClass.class)); + assertThat(((PartitionKeyExtractorStrategy) ReflectionUtils + .getField(partitonKeyExtractorField, partitionHandler)).getClass() + .equals(CustomPartitionKeyExtractorClass.class)).isTrue(); + assertThat(((PartitionSelectorStrategy) ReflectionUtils + .getField(partitonSelectorField, partitionHandler)).getClass() + .equals(CustomPartitionSelectorClass.class)).isTrue(); } } } @Test public void testCustomPartitionedProducerByName() { - ApplicationContext context = SpringApplication.run(CustomPartitionedProducerTest.TestSource.class, - "--spring.jmx.enabled=false", - "--spring.main.web-application-type=none", + ApplicationContext context = SpringApplication.run( + CustomPartitionedProducerTest.TestSource.class, + "--spring.jmx.enabled=false", "--spring.main.web-application-type=none", "--spring.cloud.stream.bindings.output.producer.partitionKeyExtractorName=customPartitionKeyExtractor", "--spring.cloud.stream.bindings.output.producer.partitionSelectorName=customPartitionSelector", "--spring.cloud.stream.default-binder=mock"); Source testSource = context.getBean(Source.class); DirectChannel messageChannel = (DirectChannel) testSource.output(); - for (ChannelInterceptor channelInterceptor : messageChannel.getChannelInterceptors()) { + for (ChannelInterceptor channelInterceptor : messageChannel + .getChannelInterceptors()) { if (channelInterceptor instanceof MessageConverterConfigurer.PartitioningInterceptor) { - Field partitionHandlerField = ReflectionUtils - .findField(MessageConverterConfigurer.PartitioningInterceptor.class, "partitionHandler"); + Field partitionHandlerField = ReflectionUtils.findField( + MessageConverterConfigurer.PartitioningInterceptor.class, + "partitionHandler"); ReflectionUtils.makeAccessible(partitionHandlerField); - PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils.getField(partitionHandlerField, - channelInterceptor); - Field partitonKeyExtractorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionKeyExtractorStrategy"); + PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils + .getField(partitionHandlerField, channelInterceptor); + Field partitonKeyExtractorField = ReflectionUtils.findField( + PartitionHandler.class, "partitionKeyExtractorStrategy"); ReflectionUtils.makeAccessible(partitonKeyExtractorField); - Field partitonSelectorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionSelectorStrategy"); + Field partitonSelectorField = ReflectionUtils + .findField(PartitionHandler.class, "partitionSelectorStrategy"); ReflectionUtils.makeAccessible(partitonSelectorField); - Assert.assertTrue(((PartitionKeyExtractorStrategy) ReflectionUtils.getField(partitonKeyExtractorField, - partitionHandler)).getClass().equals(CustomPartitionKeyExtractorClass.class)); - Assert.assertTrue( - ((PartitionSelectorStrategy) ReflectionUtils.getField(partitonSelectorField, partitionHandler)) - .getClass().equals(CustomPartitionSelectorClass.class)); + assertThat(((PartitionKeyExtractorStrategy) ReflectionUtils + .getField(partitonKeyExtractorField, partitionHandler)).getClass() + .equals(CustomPartitionKeyExtractorClass.class)).isTrue(); + assertThat(((PartitionSelectorStrategy) ReflectionUtils + .getField(partitonSelectorField, partitionHandler)).getClass() + .equals(CustomPartitionSelectorClass.class)).isTrue(); } } } @Test public void testCustomPartitionedProducerAsSingletons() { - ApplicationContext context = SpringApplication.run(CustomPartitionedProducerTest.TestSource.class, + ApplicationContext context = SpringApplication.run( + CustomPartitionedProducerTest.TestSource.class, "--spring.jmx.enabled=false", "--spring.main.web-application-type=none", "--spring.cloud.stream.default-binder=mock"); Source testSource = context.getBean(Source.class); DirectChannel messageChannel = (DirectChannel) testSource.output(); - for (ChannelInterceptor channelInterceptor : messageChannel.getChannelInterceptors()) { + for (ChannelInterceptor channelInterceptor : messageChannel + .getChannelInterceptors()) { if (channelInterceptor instanceof MessageConverterConfigurer.PartitioningInterceptor) { - Field partitionHandlerField = ReflectionUtils - .findField(MessageConverterConfigurer.PartitioningInterceptor.class, "partitionHandler"); + Field partitionHandlerField = ReflectionUtils.findField( + MessageConverterConfigurer.PartitioningInterceptor.class, + "partitionHandler"); ReflectionUtils.makeAccessible(partitionHandlerField); - PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils.getField(partitionHandlerField, - channelInterceptor); - Field partitonKeyExtractorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionKeyExtractorStrategy"); + PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils + .getField(partitionHandlerField, channelInterceptor); + Field partitonKeyExtractorField = ReflectionUtils.findField( + PartitionHandler.class, "partitionKeyExtractorStrategy"); ReflectionUtils.makeAccessible(partitonKeyExtractorField); - Field partitonSelectorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionSelectorStrategy"); + Field partitonSelectorField = ReflectionUtils + .findField(PartitionHandler.class, "partitionSelectorStrategy"); ReflectionUtils.makeAccessible(partitonSelectorField); - Assert.assertTrue(((PartitionKeyExtractorStrategy) ReflectionUtils.getField(partitonKeyExtractorField, - partitionHandler)).getClass().equals(CustomPartitionKeyExtractorClass.class)); - Assert.assertTrue( - ((PartitionSelectorStrategy) ReflectionUtils.getField(partitonSelectorField, partitionHandler)) - .getClass().equals(CustomPartitionSelectorClass.class)); + assertThat(((PartitionKeyExtractorStrategy) ReflectionUtils + .getField(partitonKeyExtractorField, partitionHandler)).getClass() + .equals(CustomPartitionKeyExtractorClass.class)).isTrue(); + assertThat(((PartitionSelectorStrategy) ReflectionUtils + .getField(partitonSelectorField, partitionHandler)).getClass() + .equals(CustomPartitionSelectorClass.class)).isTrue(); } } } public void testCustomPartitionedProducerMultipleInstances() { - ApplicationContext context = SpringApplication.run(CustomPartitionedProducerTest.TestSourceMultipleStrategies.class, - "--spring.jmx.enabled=false", - "--spring.main.web-application-type=none", + ApplicationContext context = SpringApplication.run( + CustomPartitionedProducerTest.TestSourceMultipleStrategies.class, + "--spring.jmx.enabled=false", "--spring.main.web-application-type=none", "--spring.cloud.stream.bindings.output.producer.partitionKeyExtractorName=customPartitionKeyExtractorOne", "--spring.cloud.stream.bindings.output.producer.partitionSelectorName=customPartitionSelectorTwo", "--spring.cloud.stream.default-binder=mock"); Source testSource = context.getBean(Source.class); DirectChannel messageChannel = (DirectChannel) testSource.output(); - for (ChannelInterceptor channelInterceptor : messageChannel.getChannelInterceptors()) { + for (ChannelInterceptor channelInterceptor : messageChannel + .getChannelInterceptors()) { if (channelInterceptor instanceof MessageConverterConfigurer.PartitioningInterceptor) { - Field partitionHandlerField = ReflectionUtils - .findField(MessageConverterConfigurer.PartitioningInterceptor.class, "partitionHandler"); + Field partitionHandlerField = ReflectionUtils.findField( + MessageConverterConfigurer.PartitioningInterceptor.class, + "partitionHandler"); ReflectionUtils.makeAccessible(partitionHandlerField); - PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils.getField(partitionHandlerField, - channelInterceptor); - Field partitonKeyExtractorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionKeyExtractorStrategy"); + PartitionHandler partitionHandler = (PartitionHandler) ReflectionUtils + .getField(partitionHandlerField, channelInterceptor); + Field partitonKeyExtractorField = ReflectionUtils.findField( + PartitionHandler.class, "partitionKeyExtractorStrategy"); ReflectionUtils.makeAccessible(partitonKeyExtractorField); - Field partitonSelectorField = ReflectionUtils.findField(PartitionHandler.class, - "partitionSelectorStrategy"); + Field partitonSelectorField = ReflectionUtils + .findField(PartitionHandler.class, "partitionSelectorStrategy"); ReflectionUtils.makeAccessible(partitonSelectorField); - Assert.assertTrue(((PartitionKeyExtractorStrategy) ReflectionUtils.getField(partitonKeyExtractorField, - partitionHandler)).getClass().equals(CustomPartitionKeyExtractorClass.class)); - Assert.assertTrue( - ((PartitionSelectorStrategy) ReflectionUtils.getField(partitonSelectorField, partitionHandler)) - .getClass().equals(CustomPartitionSelectorClass.class)); + assertThat(((PartitionKeyExtractorStrategy) ReflectionUtils + .getField(partitonKeyExtractorField, partitionHandler)).getClass() + .equals(CustomPartitionKeyExtractorClass.class)).isTrue(); + assertThat(((PartitionSelectorStrategy) ReflectionUtils + .getField(partitonSelectorField, partitionHandler)).getClass() + .equals(CustomPartitionSelectorClass.class)).isTrue(); } } } - @Test(expected=Exception.class) - // It actually throws UnsatisfiedDependencyException, but it is confusing when it comes to test + @Test(expected = Exception.class) + // It actually throws UnsatisfiedDependencyException, but it is confusing when it + // comes to test // But for the purposes of the test all we care about is that it fails public void testCustomPartitionedProducerMultipleInstancesFailNoFilter() { - SpringApplication.run(CustomPartitionedProducerTest.TestSourceMultipleStrategies.class, + SpringApplication.run( + CustomPartitionedProducerTest.TestSourceMultipleStrategies.class, "--spring.jmx.enabled=false", "--spring.main.web-application-type=none"); } @@ -205,6 +223,7 @@ public class CustomPartitionedProducerTest { } }; } + } @EnableBinding(Source.class) @@ -242,5 +261,7 @@ public class CustomPartitionedProducerTest { } }; } + } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/InvalidBindingConfigurationTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/InvalidBindingConfigurationTests.java index 416169888..7b5bb4381 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/InvalidBindingConfigurationTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/InvalidBindingConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,28 +31,18 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * @author Artem Bilan - * * @since 1.3 */ public class InvalidBindingConfigurationTests { @Test public void testDuplicateBeanByBindingConfig() { - assertThatThrownBy( - () -> SpringApplication.run(TestBindingConfig.class)) + assertThatThrownBy(() -> SpringApplication.run(TestBindingConfig.class)) .isInstanceOf(BeanDefinitionStoreException.class) .hasMessageContaining("bean definition with this name already exists") - .hasMessageContaining(TestInvalidBinding.NAME) - .hasNoCause(); + .hasMessageContaining(TestInvalidBinding.NAME).hasNoCause(); } - @EnableBinding(TestInvalidBinding.class) - @EnableAutoConfiguration - public static class TestBindingConfig { - - } - - public interface TestInvalidBinding { String NAME = "testName"; @@ -65,4 +55,10 @@ public class InvalidBindingConfigurationTests { } + @EnableBinding(TestInvalidBinding.class) + @EnableAutoConfiguration + public static class TestBindingConfig { + + } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/MessageConverterConfigurerTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/MessageConverterConfigurerTests.java index 2911823c2..412400da4 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/MessageConverterConfigurerTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/MessageConverterConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.MimeType; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.fail; /** * @author Gary Russell @@ -46,8 +46,7 @@ import static org.junit.Assert.fail; */ public class MessageConverterConfigurerTests { - - //@Test + // @Test public void testConfigureOutputChannelWithBadContentType() { BindingServiceProperties props = new BindingServiceProperties(); BindingProperties bindingProps = new BindingProperties(); @@ -55,11 +54,12 @@ public class MessageConverterConfigurerTests { props.setBindings(Collections.singletonMap("foo", bindingProps)); CompositeMessageConverterFactory converterFactory = new CompositeMessageConverterFactory( Collections.emptyList(), null); - MessageConverterConfigurer configurer = new MessageConverterConfigurer(props, converterFactory); + MessageConverterConfigurer configurer = new MessageConverterConfigurer(props, + converterFactory); QueueChannel out = new QueueChannel(); configurer.configureOutputChannel(out, "foo"); - out.send(new GenericMessage(new Foo(), - Collections. singletonMap(MessageHeaders.CONTENT_TYPE, "bad/ct"))); + out.send(new GenericMessage(new Foo(), Collections + .singletonMap(MessageHeaders.CONTENT_TYPE, "bad/ct"))); Message received = out.receive(0); assertThat(received).isNotNull(); assertThat(received.getPayload()).isInstanceOf(Foo.class); @@ -72,7 +72,8 @@ public class MessageConverterConfigurerTests { BindingProperties bindingProps = new BindingProperties(); bindingProps.setContentType("foo/bar"); props.setBindings(Collections.singletonMap("foo", bindingProps)); - MessageConverter converter = new AbstractMessageConverter(new MimeType("foo", "bar")) { + MessageConverter converter = new AbstractMessageConverter( + new MimeType("foo", "bar")) { @Override protected boolean supports(Class clazz) { @@ -80,23 +81,27 @@ public class MessageConverterConfigurerTests { } @Override - protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + protected Object convertToInternal(Object payload, MessageHeaders headers, + Object conversionHint) { return null; } }; CompositeMessageConverterFactory converterFactory = new CompositeMessageConverterFactory( Collections.singletonList(converter), null); - MessageConverterConfigurer configurer = new MessageConverterConfigurer(props, converterFactory); + MessageConverterConfigurer configurer = new MessageConverterConfigurer(props, + converterFactory); QueueChannel out = new QueueChannel(); configurer.configureOutputChannel(out, "foo"); try { out.send(new GenericMessage(new Foo(), - Collections. singletonMap(MessageHeaders.CONTENT_TYPE, "bad/ct"))); + Collections.singletonMap(MessageHeaders.CONTENT_TYPE, + "bad/ct"))); fail("Expected MessageConversionException: " + out.receive(0)); } catch (MessageConversionException e) { - assertThat(e.getMessage()).endsWith("to the configured output type: 'foo/bar'"); + assertThat(e.getMessage()) + .endsWith("to the configured output type: 'foo/bar'"); } } @@ -108,19 +113,19 @@ public class MessageConverterConfigurerTests { props.setBindings(Collections.singletonMap("foo", bindingProps)); CompositeMessageConverterFactory converterFactory = new CompositeMessageConverterFactory( Collections.emptyList(), null); - MessageConverterConfigurer configurer = new MessageConverterConfigurer(props, converterFactory); + MessageConverterConfigurer configurer = new MessageConverterConfigurer(props, + converterFactory); QueueChannel in = new QueueChannel(); configurer.configureInputChannel(in, "foo"); Foo foo = new Foo(); - in.send( - MessageBuilder.withPayload(foo) - .setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, "application/json") - .setHeader(BinderHeaders.SCST_VERSION, "1.x") - .build()); + in.send(MessageBuilder.withPayload(foo) + .setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, "application/json") + .setHeader(BinderHeaders.SCST_VERSION, "1.x").build()); Message received = in.receive(0); assertThat(received).isNotNull(); assertThat(received.getPayload()).isEqualTo(foo); - assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()).isEqualTo("application/json"); + assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()) + .isEqualTo("application/json"); } public static class Foo { diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderConfigurationParsingTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderConfigurationParsingTests.java index fd02dfff4..94331186e 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderConfigurationParsingTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderConfigurationParsingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. @@ -17,9 +17,12 @@ package org.springframework.cloud.stream.config; import java.io.ByteArrayInputStream; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; -import org.junit.Assert; import org.junit.Test; import org.springframework.cloud.stream.binder.BinderType; @@ -29,20 +32,15 @@ import org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationB; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; -import static org.hamcrest.Matchers.arrayContainingInAnyOrder; -import static org.hamcrest.Matchers.both; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItemInArray; -import static org.hamcrest.Matchers.hasProperty; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Marius Bogoevici */ public class BinderConfigurationParsingTests { - private static ClassLoader classLoader = BinderConfigurationParsingTests.class.getClassLoader(); + private static ClassLoader classLoader = BinderConfigurationParsingTests.class + .getClassLoader(); @Test public void testParseOneBinderConfiguration() throws Exception { @@ -50,16 +48,18 @@ public class BinderConfigurationParsingTests { // this is just checking that resources are passed and classes are loaded properly // class values used here are not binder configurations String oneBinderConfiguration = "binder1=org.springframework.cloud.stream.binder.stub1.StubBinder1Configuration"; - Resource resource = new InputStreamResource(new ByteArrayInputStream(oneBinderConfiguration.getBytes())); + Resource resource = new InputStreamResource( + new ByteArrayInputStream(oneBinderConfiguration.getBytes())); - Collection binderConfigurations = BinderFactoryConfiguration.parseBinderConfigurations(classLoader, - resource); + Collection binderConfigurations = BinderFactoryConfiguration + .parseBinderConfigurations(classLoader, resource); - Assert.assertNotNull(binderConfigurations); - Assert.assertThat(binderConfigurations.size(), equalTo(1)); - Assert.assertThat(binderConfigurations, contains( - both(hasProperty("defaultName", equalTo("binder1"))).and( - hasProperty("configurationClasses", hasItemInArray(StubBinder1Configuration.class))))); + assertThat(binderConfigurations).isNotNull(); + assertThat(binderConfigurations.size()).isEqualTo(1); + BinderType type = binderConfigurations.iterator().next(); + assertThat(type.getDefaultName()).isEqualTo("binder1"); + assertThat(type.getConfigurationClasses()) + .contains(StubBinder1Configuration.class); } @SuppressWarnings("unchecked") @@ -68,46 +68,55 @@ public class BinderConfigurationParsingTests { // this is just checking that resources are passed and classes are loaded properly // class values used here are not binder configurations String binderConfiguration = "binder1=org.springframework.cloud.stream.binder.stub1.StubBinder1Configuration\n" - + - "binder2=org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationA"; + + "binder2=org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationA"; Resource twoBinderConfigurationResource = new InputStreamResource( new ByteArrayInputStream(binderConfiguration.getBytes())); - Collection twoBinderConfigurations = BinderFactoryConfiguration.parseBinderConfigurations( - classLoader, - twoBinderConfigurationResource); + Collection twoBinderConfig = BinderFactoryConfiguration + .parseBinderConfigurations(classLoader, twoBinderConfigurationResource); - Assert.assertThat(twoBinderConfigurations.size(), equalTo(2)); - Assert.assertThat(twoBinderConfigurations, containsInAnyOrder( - both(hasProperty("defaultName", equalTo("binder1"))).and( - hasProperty("configurationClasses", hasItemInArray(StubBinder1Configuration.class))), - both(hasProperty("defaultName", equalTo("binder2"))).and( - hasProperty("configurationClasses", hasItemInArray(StubBinder2ConfigurationA.class))))); + assertThat(twoBinderConfig.size()).isEqualTo(2); + List stubBinder1 = stubBinders(twoBinderConfig, "binder1", + StubBinder1Configuration.class); + List stubBinder2 = stubBinders(twoBinderConfig, "binder2", + StubBinder2ConfigurationA.class); + assertThat(stubBinder1).isNotEmpty(); + assertThat(stubBinder2).isNotEmpty(); } + private List stubBinders(Collection twoBinderConfigurations, + String binderName, Class... configurationNames) { + return twoBinderConfigurations.stream() + .filter(binderType -> binderName.equals(binderType.getDefaultName()) + && !Collections.disjoint( + Arrays.asList(binderType.getConfigurationClasses()), + Arrays.asList(configurationNames))) + .collect(Collectors.toList()); + } + @Test @SuppressWarnings("unchecked") public void testParseTwoBindersWithMultipleClasses() throws Exception { // this is just checking that resources are passed and classes are loaded properly // class values used here are not binder configurations String binderConfiguration = "binder1=org.springframework.cloud.stream.binder.stub1.StubBinder1Configuration\n" - + - "binder2=org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationA," + - "org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationB"; + + "binder2=org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationA," + + "org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationB"; Resource binderConfigurationResource = new InputStreamResource( new ByteArrayInputStream(binderConfiguration.getBytes())); - Collection binderConfigurations = BinderFactoryConfiguration.parseBinderConfigurations(classLoader, - binderConfigurationResource); - - Assert.assertThat(binderConfigurations.size(), equalTo(2)); - Assert.assertThat(binderConfigurations, containsInAnyOrder( - both(hasProperty("defaultName", equalTo("binder1"))).and( - hasProperty("configurationClasses", hasItemInArray(StubBinder1Configuration.class))), - both(hasProperty("defaultName", equalTo("binder2"))).and( - hasProperty("configurationClasses", arrayContainingInAnyOrder(StubBinder2ConfigurationA.class, - StubBinder2ConfigurationB.class))))); + Collection binderConfigurations = BinderFactoryConfiguration + .parseBinderConfigurations(classLoader, binderConfigurationResource); + assertThat(binderConfigurations.size()).isEqualTo(2); + assertThat(binderConfigurations.size()).isEqualTo(2); + List stubBinder1 = stubBinders(binderConfigurations, "binder1", + StubBinder1Configuration.class); + List stubBinder2 = stubBinders(binderConfigurations, "binder2", + StubBinder2ConfigurationA.class, StubBinder2ConfigurationB.class); + assertThat(stubBinder1).isNotEmpty(); + assertThat(stubBinder2).isNotEmpty(); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderPropertiesTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderPropertiesTests.java index d524f2149..9687e9cea 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderPropertiesTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BinderPropertiesTests.java @@ -27,14 +27,12 @@ import org.springframework.boot.actuate.context.properties.ConfigurationProperti import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint.ContextConfigurationProperties; import org.springframework.context.support.StaticApplicationContext; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; /** - * This test primarily validates the correctness of BinderProperties - * where it as well as what it contains maintains the String-key/Object-value - * semantics. The use of {@link Properties} class does not exactly do that. - * + * This test primarily validates the correctness of BinderProperties where it as well as + * what it contains maintains the String-key/Object-value semantics. The use of + * {@link Properties} class does not exactly do that. * * @author Oleg Zhurakousky * @@ -45,7 +43,8 @@ public class BinderPropertiesTests { @Test public void testSerializationWithNonStringValues() { StaticApplicationContext context = new StaticApplicationContext(); - DefaultListableBeanFactory bf = (DefaultListableBeanFactory) context.getBeanFactory(); + DefaultListableBeanFactory bf = (DefaultListableBeanFactory) context + .getBeanFactory(); BindingServiceProperties bindingServiceProperties = new BindingServiceProperties(); bindingServiceProperties.setApplicationContext(context); bf.registerSingleton("bindingServiceProperties", bindingServiceProperties); @@ -57,20 +56,26 @@ public class BinderPropertiesTests { bp.getEnvironment().put("spring.rabbitmq.connection-timeout", 2345); bp.getEnvironment().put("foo", Collections.singletonMap("bar", "hello")); - // using Spring Boot class to ensure that reliance on the same ObjectMapper configuration + // using Spring Boot class to ensure that reliance on the same ObjectMapper + // configuration ConfigurationPropertiesReportEndpoint endpoint = new ConfigurationPropertiesReportEndpoint(); endpoint.setApplicationContext(context); + ContextConfigurationProperties configurationProperties = endpoint + .configurationProperties().getContexts().values().iterator().next(); - ContextConfigurationProperties configurationProperties = endpoint.configurationProperties().getContexts().values().iterator().next(); - - Map properties = configurationProperties.getBeans().get("bindingServiceProperties").getProperties(); - assertFalse(properties.containsKey("error")); - assertTrue(properties.containsKey("binders")); - Map testBinder = (Map) ((Map)properties.get("binders")).get("testBinder"); - Map environment = (Map) testBinder.get("environment"); - assertTrue(environment.get("spring.rabbitmq.connection-timeout") instanceof Integer); - assertTrue(environment.get("foo") instanceof Map); + Map properties = configurationProperties.getBeans() + .get("bindingServiceProperties").getProperties(); + assertThat(properties.containsKey("error")).isFalse(); + assertThat(properties.containsKey("binders")).isTrue(); + Map testBinder = (Map) ((Map) properties + .get("binders")).get("testBinder"); + Map environment = (Map) testBinder + .get("environment"); + assertThat( + environment.get("spring.rabbitmq.connection-timeout") instanceof Integer) + .isTrue(); + assertThat(environment.get("foo") instanceof Map).isTrue(); } -} +} diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingHandlerAdviseTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingHandlerAdviseTests.java index b165d2110..5d48a4fd4 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingHandlerAdviseTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingHandlerAdviseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -32,30 +32,31 @@ import org.springframework.cloud.stream.messaging.Sink; import org.springframework.context.annotation.Import; import org.springframework.validation.annotation.Validated; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; // see https://github.com/spring-cloud/spring-cloud-stream/issues/1573 for more details /** - * * @author Oleg Zhurakousky * */ public class BindingHandlerAdviseTests { - - @Test(expected=BeanCreationException.class) + + @Test(expected = BeanCreationException.class) public void testFailureWithWrongValue() { new SpringApplicationBuilder(SampleConfiguration.class) .web(WebApplicationType.NONE) .run("--props.value=-1", "--spring.jmx.enabled=false"); } - + @Test public void testValidatedValueValue() { - ValidatedProps validatedProps = new SpringApplicationBuilder(SampleConfiguration.class) - .web(WebApplicationType.NONE) - .run("--props.value=2", "--spring.jmx.enabled=false").getBean(ValidatedProps.class); - assertEquals(2, validatedProps.getValue()); + ValidatedProps validatedProps = new SpringApplicationBuilder( + SampleConfiguration.class).web(WebApplicationType.NONE) + .run("--props.value=2", "--spring.jmx.enabled=false") + .getBean(ValidatedProps.class); + assertThat(validatedProps.getValue()).isEqualTo(2); } + } @EnableBinding(Sink.class) @@ -63,7 +64,7 @@ public class BindingHandlerAdviseTests { @EnableAutoConfiguration @EnableConfigurationProperties(ValidatedProps.class) class SampleConfiguration { - + } @ConfigurationProperties("props") @@ -73,11 +74,12 @@ class ValidatedProps { @Min(0) private int value; + public int getValue() { + return this.value; + } + public void setValue(int value) { this.value = value; } - public int getValue() { - return value; - } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingServiceConfigurationTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingServiceConfigurationTests.java index fca595163..bdbe09341 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingServiceConfigurationTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/BindingServiceConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,10 +29,9 @@ import org.springframework.context.annotation.Import; import org.springframework.integration.annotation.ServiceActivator; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; /** - * * @author Oleg Zhurakousky * */ @@ -40,27 +39,35 @@ public class BindingServiceConfigurationTests { @Test public void valdateImportedConfiguartionHandlerPostProcessing() { - ApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration.getCompleteConfiguration(RootConfiguration.class)).web(WebApplicationType.NONE).run(); - Map beansOfType = context.getBeansOfType(AbstractReplyProducingMessageHandler.class); + ApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration + .getCompleteConfiguration(RootConfiguration.class)) + .web(WebApplicationType.NONE).run(); + Map beansOfType = context + .getBeansOfType(AbstractReplyProducingMessageHandler.class); for (AbstractReplyProducingMessageHandler handler : beansOfType.values()) { - assertTrue(handler.getNotPropagatedHeaders().contains("contentType")); + assertThat(handler.getNotPropagatedHeaders().contains("contentType")) + .isTrue(); } } @Configuration @Import(ImportedConfiguration.class) public static class RootConfiguration { - @ServiceActivator(inputChannel="input") + + @ServiceActivator(inputChannel = "input") public void rootService(String val) { } + } @Configuration public static class ImportedConfiguration { - @ServiceActivator(inputChannel="input") + + @ServiceActivator(inputChannel = "input") public void importedService(String val) { } + } - } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfigurationTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfigurationTests.java index 4fdd1dc1b..94f5b8b5e 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfigurationTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfigurationTests.java @@ -51,8 +51,8 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Artem Bilan */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpelExpressionConverterConfigurationTests.Config.class, - properties = {"expression: a.b"}) +@SpringBootTest(classes = SpelExpressionConverterConfigurationTests.Config.class, properties = { + "expression: a.b" }) public class SpelExpressionConverterConfigurationTests { @Autowired @@ -64,22 +64,23 @@ public class SpelExpressionConverterConfigurationTests { @Autowired private Config config; - @Test @SuppressWarnings("unchecked") public void converterCorrectlyInstalled() { - Expression expression = pojo.getExpression(); + Expression expression = this.pojo.getExpression(); assertThat(expression.getValue("{\"a\": {\"b\": 5}}").toString()).isEqualTo("5"); - List propertyAccessors = - TestUtils.getPropertyValue(this.evaluationContext, "propertyAccessors", List.class); + List propertyAccessors = TestUtils.getPropertyValue( + this.evaluationContext, "propertyAccessors", List.class); - assertThat(propertyAccessors).hasAtLeastOneElementOfType(JsonPropertyAccessor.class); + assertThat(propertyAccessors) + .hasAtLeastOneElementOfType(JsonPropertyAccessor.class); - propertyAccessors = - TestUtils.getPropertyValue(this.config.evaluationContext, "propertyAccessors", List.class); + propertyAccessors = TestUtils.getPropertyValue(this.config.evaluationContext, + "propertyAccessors", List.class); - assertThat(propertyAccessors).hasAtLeastOneElementOfType(JsonPropertyAccessor.class); + assertThat(propertyAccessors) + .hasAtLeastOneElementOfType(JsonPropertyAccessor.class); } @ConfigurationProperties @@ -88,12 +89,13 @@ public class SpelExpressionConverterConfigurationTests { private Expression expression; public Expression getExpression() { - return expression; + return this.expression; } public void setExpression(Expression expression) { this.expression = expression; } + } @Configuration @@ -118,7 +120,8 @@ public class SpelExpressionConverterConfigurationTests { @PostConstruct public void setup() { - this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory); + this.evaluationContext = ExpressionUtils + .createStandardEvaluationContext(this.beanFactory); } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/converter/KryoMessageConverterTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/converter/KryoMessageConverterTests.java index 7a40be35d..08ce27888 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/converter/KryoMessageConverterTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/converter/KryoMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import java.io.ByteArrayOutputStream; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Output; -import org.junit.Assert; import org.junit.Test; import org.springframework.integration.support.MessageBuilder; @@ -28,6 +27,8 @@ import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.converter.MessageConversionException; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Vinicius Carvalho */ @@ -35,53 +36,66 @@ public class KryoMessageConverterTests { @Test public void convertStringType() throws Exception { - KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null,true); - Message message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE,"application/x-java-object").build(); - Message converted = kryoMessageConverter.toMessage(message.getPayload(),message.getHeaders()); - Assert.assertNotNull(converted); - Assert.assertEquals("application/x-java-object;type=java.lang.String",converted.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()); + KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null, true); + Message message = MessageBuilder.withPayload("foo") + .setHeader(MessageHeaders.CONTENT_TYPE, "application/x-java-object") + .build(); + Message converted = kryoMessageConverter.toMessage(message.getPayload(), + message.getHeaders()); + assertThat(converted).isNotNull(); + assertThat(converted.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()) + .isEqualTo("application/x-java-object;type=java.lang.String"); } @Test public void readStringType() throws Exception { - KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null,true); + KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null, true); Kryo kryo = new Kryo(); String foo = "foo"; ByteArrayOutputStream baos = new ByteArrayOutputStream(); Output output = new Output(baos); - kryo.writeObject(output,foo); + kryo.writeObject(output, foo); output.close(); - Message message = MessageBuilder.withPayload(baos.toByteArray()).setHeader(MessageHeaders.CONTENT_TYPE,KryoMessageConverter.KRYO_MIME_TYPE+";type=java.lang.String").build(); - Object result = kryoMessageConverter.fromMessage(message,String.class); - Assert.assertEquals(foo,result); + Message message = MessageBuilder.withPayload(baos.toByteArray()) + .setHeader(MessageHeaders.CONTENT_TYPE, + KryoMessageConverter.KRYO_MIME_TYPE + ";type=java.lang.String") + .build(); + Object result = kryoMessageConverter.fromMessage(message, String.class); + assertThat(result).isEqualTo(foo); } @Test public void testMissingHeaders() throws Exception { - KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null,true); + KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null, true); Kryo kryo = new Kryo(); String foo = "foo"; ByteArrayOutputStream baos = new ByteArrayOutputStream(); Output output = new Output(baos); - kryo.writeObject(output,foo); + kryo.writeObject(output, foo); output.close(); Message message = MessageBuilder.withPayload(baos.toByteArray()).build(); - Object result = kryoMessageConverter.fromMessage(message,String.class); - Assert.assertNull(result); + Object result = kryoMessageConverter.fromMessage(message, String.class); + assertThat(result).isNull(); } @Test(expected = MessageConversionException.class) - public void readWithWrongPayloadType() throws Exception{ - KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null,true); - Message message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE,KryoMessageConverter.KRYO_MIME_TYPE+";type=java.lang.String").build(); - kryoMessageConverter.fromMessage(message,String.class); + public void readWithWrongPayloadType() throws Exception { + KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null, true); + Message message = MessageBuilder.withPayload("foo") + .setHeader(MessageHeaders.CONTENT_TYPE, + KryoMessageConverter.KRYO_MIME_TYPE + ";type=java.lang.String") + .build(); + kryoMessageConverter.fromMessage(message, String.class); } @Test(expected = MessageConversionException.class) - public void readWithWrongPayloadFormat() throws Exception{ - KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null,true); - Message message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE,KryoMessageConverter.KRYO_MIME_TYPE+";type=java.lang.String").build(); - kryoMessageConverter.fromMessage(message,String.class); + public void readWithWrongPayloadFormat() throws Exception { + KryoMessageConverter kryoMessageConverter = new KryoMessageConverter(null, true); + Message message = MessageBuilder.withPayload("foo") + .setHeader(MessageHeaders.CONTENT_TYPE, + KryoMessageConverter.KRYO_MIME_TYPE + ";type=java.lang.String") + .build(); + kryoMessageConverter.fromMessage(message, String.class); } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/FunctionInvokerTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/FunctionInvokerTests.java index b5f7bd906..aca260cc1 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/FunctionInvokerTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/FunctionInvokerTests.java @@ -21,8 +21,6 @@ import java.util.function.Consumer; import java.util.function.Function; import org.junit.Test; - - import reactor.core.publisher.Flux; import org.springframework.boot.WebApplicationType; @@ -50,38 +48,262 @@ import org.springframework.messaging.support.GenericMessage; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; /** - * * @author Oleg Zhurakousky * @author Tolga Kavukcu * */ public class FunctionInvokerTests { + private static String testWithFluxedConsumerValue; + @Test public void testFunctionHonorsOutboundBindingContentType() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(ConverterDoesNotProduceCTConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.jmx.enabled=false", - "--spring.cloud.stream.function.definition=func", - "--spring.cloud.stream.bindings.output.contentType=text/plain")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + ConverterDoesNotProduceCTConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false", + "--spring.cloud.stream.function.definition=func", + "--spring.cloud.stream.bindings.output.contentType=text/plain")) { InputDestination inputDestination = context.getBean(InputDestination.class); - OutputDestination outputDestination = context.getBean(OutputDestination.class); + OutputDestination outputDestination = context + .getBean(OutputDestination.class); - Message inputMessage = MessageBuilder.withPayload("{\"name\":\"bob\"}".getBytes()) + Message inputMessage = MessageBuilder + .withPayload("{\"name\":\"bob\"}".getBytes()) .setHeader(MessageHeaders.CONTENT_TYPE, "foo/bar").build(); inputDestination.send(inputMessage); Message outputMessage = outputDestination.receive(); - assertEquals("text/plain", outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE) + .toString()).isEqualTo("text/plain"); } } + @Test + public void testFunctionHonorsConverterSetContentType() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration( + ConverterInjectingCTConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false", + "--spring.cloud.stream.function.definition=func", + "--spring.cloud.stream.bindings.output.contentType=text/plain")) { + + InputDestination inputDestination = context.getBean(InputDestination.class); + OutputDestination outputDestination = context + .getBean(OutputDestination.class); + + Message inputMessage = MessageBuilder + .withPayload("{\"name\":\"bob\"}".getBytes()) + .setHeader(MessageHeaders.CONTENT_TYPE, "foo/bar").build(); + inputDestination.send(inputMessage); + + Message outputMessage = outputDestination.receive(); + assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE) + .toString()).isEqualTo("ping/pong"); + + } + } + + @Test + public void testSameMessageTypesAreNotConverted() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration + .getCompleteConfiguration(MyFunctionsConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false")) { + + Message inputMessage = new GenericMessage<>(new Foo()); + + StreamFunctionProperties functionProperties = createStreamFunctionProperties(); + + functionProperties.setDefinition("messageToMessageSameType"); + FunctionInvoker messageToMessageSameType = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + Message outputMessage = messageToMessageSameType + .apply(Flux.just(inputMessage)).blockFirst(); + assertThat(inputMessage).isSameAs(outputMessage); + + functionProperties.setDefinition("pojoToPojoSameType"); + FunctionInvoker pojoToPojoSameType = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + outputMessage = pojoToPojoSameType.apply(Flux.just(inputMessage)) + .blockFirst(); + assertThat(inputMessage.getPayload()).isEqualTo(outputMessage.getPayload()); + + functionProperties.setDefinition("messageToMessageNoType"); + FunctionInvoker messageToMessageNoType = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + outputMessage = messageToMessageNoType.apply(Flux.just(inputMessage)) + .blockFirst(); + assertThat(outputMessage).isInstanceOf(Message.class); + + functionProperties.setDefinition("withException"); + FunctionInvoker withException = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + + Flux> fluxOfMessages = Flux + .just(new GenericMessage<>(new ErrorFoo()), inputMessage); + Message resultMessage = withException.apply(fluxOfMessages).blockFirst(); + assertThat(resultMessage.getPayload()).isNotInstanceOf(ErrorFoo.class); + } + } + + @Test + public void testNativeEncodingEnabled() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration + .getCompleteConfiguration(MyFunctionsConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false")) { + + Message inputMessage = new GenericMessage<>(new Baz()); + + StreamFunctionProperties functionProperties = createStreamFunctionPropertiesWithNativeEncoding(); + + functionProperties.setDefinition("pojoToPojoNonEmptyPojo"); + FunctionInvoker pojoToPojoSameType = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + Message outputMessage = pojoToPojoSameType.apply(Flux.just(inputMessage)) + .blockFirst(); + assertThat(inputMessage.getPayload()).isEqualTo(outputMessage.getPayload()); + + Message inputMessageWithBaz = new GenericMessage<>(new Baz()); + + functionProperties.setDefinition("messageToMessageNoType"); + FunctionInvoker messageToMessageNoType = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + outputMessage = messageToMessageNoType.apply(Flux.just(inputMessageWithBaz)) + .blockFirst(); + assertThat(outputMessage).isInstanceOf(Message.class); + + functionProperties.setDefinition("withExceptionNativeEncodingEnabled"); + FunctionInvoker withException = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + + Flux> fluxOfMessages = Flux + .just(new GenericMessage<>(new ErrorBaz()), inputMessage); + Message resultMessage = withException.apply(fluxOfMessages).blockFirst(); + assertThat(resultMessage.getPayload()).isNotInstanceOf(ErrorFoo.class); + } + } + + @Test + public void testWithOutNativeEncodingEnabled() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration + .getCompleteConfiguration(MyFunctionsConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false")) { + + Message inputMessage = new GenericMessage<>(new Baz()); + + StreamFunctionProperties functionProperties = createStreamFunctionProperties(); + + functionProperties.setDefinition("pojoToPojoNonEmptyPojo"); + FunctionInvoker pojoToPojoSameType = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + Message outputMessage = pojoToPojoSameType.apply(Flux.just(inputMessage)) + .blockFirst(); + assertThat(inputMessage.getPayload()) + .isNotEqualTo(outputMessage.getPayload()); + + } + } + + @Test + public void testWithFluxedConsumer() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration + .getCompleteConfiguration(MyFunctionsConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false")) { + + String value = "Hello"; + Message inputMessage = new GenericMessage<>(value); + + StreamFunctionProperties functionProperties = createStreamFunctionProperties(); + + functionProperties.setDefinition("fluxConsumer"); + FunctionInvoker fluxedConsumer = new FunctionInvoker<>( + functionProperties, + new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), + context.getBean(FunctionInspector.class), + context.getBean(CompositeMessageConverterFactory.class)); + + fluxedConsumer.apply(Flux.just(inputMessage)).blockFirst(); + + assertThat(testWithFluxedConsumerValue).isEqualTo(value); + } + } + + private StreamFunctionProperties createStreamFunctionProperties() { + StreamFunctionProperties functionProperties = new StreamFunctionProperties(); + functionProperties.setInputDestinationName("input"); + functionProperties.setOutputDestinationName("output"); + BindingServiceProperties bindingServiceProperties = new BindingServiceProperties(); + bindingServiceProperties.getConsumerProperties("input").setMaxAttempts(3); + try { + Field f = ReflectionUtils.findField(StreamFunctionProperties.class, + "bindingServiceProperties"); + f.setAccessible(true); + f.set(functionProperties, bindingServiceProperties); + return functionProperties; + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } + + private StreamFunctionProperties createStreamFunctionPropertiesWithNativeEncoding() { + StreamFunctionProperties functionProperties = new StreamFunctionProperties(); + functionProperties.setInputDestinationName("input"); + functionProperties.setOutputDestinationName("output"); + BindingServiceProperties bindingServiceProperties = new BindingServiceProperties(); + bindingServiceProperties.getConsumerProperties("input").setMaxAttempts(3); + bindingServiceProperties.getProducerProperties("output") + .setUseNativeEncoding(true); + try { + Field bspField = ReflectionUtils.findField(StreamFunctionProperties.class, + "bindingServiceProperties"); + bspField.setAccessible(true); + bspField.set(functionProperties, bindingServiceProperties); + return functionProperties; + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } + @EnableAutoConfiguration @EnableBinding(Processor.class) public static class ConverterDoesNotProduceCTConfiguration { @@ -98,41 +320,21 @@ public class FunctionInvokerTests { @Override public Message toMessage(Object payload, MessageHeaders headers) { - return new GenericMessage(((String)payload).getBytes()); + return new GenericMessage(((String) payload).getBytes()); } @Override public Object fromMessage(Message message, Class targetClass) { - String contentType = (String) message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString(); + String contentType = (String) message.getHeaders() + .get(MessageHeaders.CONTENT_TYPE).toString(); if (contentType.equals("foo/bar")) { - return new String((byte[])message.getPayload()); + return new String((byte[]) message.getPayload()); } return null; } }; } - } - @Test - public void testFunctionHonorsConverterSetContentType() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(ConverterInjectingCTConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.jmx.enabled=false", - "--spring.cloud.stream.function.definition=func", - "--spring.cloud.stream.bindings.output.contentType=text/plain")) { - - InputDestination inputDestination = context.getBean(InputDestination.class); - OutputDestination outputDestination = context.getBean(OutputDestination.class); - - Message inputMessage = MessageBuilder.withPayload("{\"name\":\"bob\"}".getBytes()) - .setHeader(MessageHeaders.CONTENT_TYPE, "foo/bar").build(); - inputDestination.send(inputMessage); - - Message outputMessage = outputDestination.receive(); - assertEquals("ping/pong", outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()); - - } } @EnableAutoConfiguration @@ -151,172 +353,22 @@ public class FunctionInvokerTests { @Override public Message toMessage(Object payload, MessageHeaders headers) { - return MessageBuilder.withPayload(((String)payload).getBytes()).setHeader(MessageHeaders.CONTENT_TYPE, "ping/pong").build(); + return MessageBuilder.withPayload(((String) payload).getBytes()) + .setHeader(MessageHeaders.CONTENT_TYPE, "ping/pong").build(); } @Override public Object fromMessage(Message message, Class targetClass) { - String contentType = (String) message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString(); + String contentType = (String) message.getHeaders() + .get(MessageHeaders.CONTENT_TYPE).toString(); if (contentType.equals("foo/bar")) { - return new String((byte[])message.getPayload()); + return new String((byte[]) message.getPayload()); } return null; } }; } - } - @Test - public void testSameMessageTypesAreNotConverted() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(MyFunctionsConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.jmx.enabled=false")) { - - Message inputMessage = new GenericMessage<>(new Foo()); - - StreamFunctionProperties functionProperties = createStreamFunctionProperties(); - - functionProperties.setDefinition("messageToMessageSameType"); - FunctionInvoker messageToMessageSameType = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - Message outputMessage = messageToMessageSameType.apply(Flux.just(inputMessage)).blockFirst(); - assertThat(inputMessage).isSameAs(outputMessage); - - functionProperties.setDefinition("pojoToPojoSameType"); - FunctionInvoker pojoToPojoSameType = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - outputMessage = pojoToPojoSameType.apply(Flux.just(inputMessage)).blockFirst(); - assertThat(inputMessage.getPayload()).isEqualTo(outputMessage.getPayload()); - - - functionProperties.setDefinition("messageToMessageNoType"); - FunctionInvoker messageToMessageNoType = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - outputMessage = messageToMessageNoType.apply(Flux.just(inputMessage)).blockFirst(); - assertThat(outputMessage).isInstanceOf(Message.class); - - functionProperties.setDefinition("withException"); - FunctionInvoker withException = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - - Flux> fluxOfMessages = Flux.just(new GenericMessage<>(new ErrorFoo()), inputMessage); - Message resultMessage = withException.apply(fluxOfMessages).blockFirst(); - assertThat(resultMessage.getPayload()).isNotInstanceOf(ErrorFoo.class); - } - } - - @Test - public void testNativeEncodingEnabled() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(MyFunctionsConfiguration.class)) - .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) { - - Message inputMessage = new GenericMessage<>(new Baz()); - - StreamFunctionProperties functionProperties = createStreamFunctionPropertiesWithNativeEncoding(); - - functionProperties.setDefinition("pojoToPojoNonEmptyPojo"); - FunctionInvoker pojoToPojoSameType = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), - context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - Message outputMessage = pojoToPojoSameType.apply(Flux.just(inputMessage)).blockFirst(); - assertThat(inputMessage.getPayload()).isEqualTo(outputMessage.getPayload()); - - Message inputMessageWithBaz = new GenericMessage<>(new Baz()); - - functionProperties.setDefinition("messageToMessageNoType"); - FunctionInvoker messageToMessageNoType = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - outputMessage = messageToMessageNoType.apply(Flux.just(inputMessageWithBaz)).blockFirst(); - assertThat(outputMessage).isInstanceOf(Message.class); - - functionProperties.setDefinition("withExceptionNativeEncodingEnabled"); - FunctionInvoker withException = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), - context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - - Flux> fluxOfMessages = Flux.just(new GenericMessage<>(new ErrorBaz()), inputMessage); - Message resultMessage = withException.apply(fluxOfMessages).blockFirst(); - assertThat(resultMessage.getPayload()).isNotInstanceOf(ErrorFoo.class); - } - } - - @Test - public void testWithOutNativeEncodingEnabled() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(MyFunctionsConfiguration.class)) - .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) { - - Message inputMessage = new GenericMessage<>(new Baz()); - - StreamFunctionProperties functionProperties = createStreamFunctionProperties(); - - functionProperties.setDefinition("pojoToPojoNonEmptyPojo"); - FunctionInvoker pojoToPojoSameType = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), - context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - Message outputMessage = pojoToPojoSameType.apply(Flux.just(inputMessage)).blockFirst(); - assertThat(inputMessage.getPayload()).isNotEqualTo(outputMessage.getPayload()); - - } - } - - private static String testWithFluxedConsumerValue; - - @Test - public void testWithFluxedConsumer() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(MyFunctionsConfiguration.class)) - .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) { - - String value = "Hello"; - Message inputMessage = new GenericMessage<>(value); - - StreamFunctionProperties functionProperties = createStreamFunctionProperties(); - - functionProperties.setDefinition("fluxConsumer"); - FunctionInvoker fluxedConsumer = new FunctionInvoker<>(functionProperties, - new FunctionCatalogWrapper(context.getBean(FunctionCatalog.class)), - context.getBean(FunctionInspector.class), context.getBean(CompositeMessageConverterFactory.class)); - - fluxedConsumer.apply(Flux.just(inputMessage)).blockFirst(); - - assertEquals(value, testWithFluxedConsumerValue); - } - } - - private StreamFunctionProperties createStreamFunctionProperties() { - StreamFunctionProperties functionProperties = new StreamFunctionProperties(); - functionProperties.setInputDestinationName("input"); - functionProperties.setOutputDestinationName("output"); - BindingServiceProperties bindingServiceProperties = new BindingServiceProperties(); - bindingServiceProperties.getConsumerProperties("input").setMaxAttempts(3); - try { - Field f = ReflectionUtils.findField(StreamFunctionProperties.class, "bindingServiceProperties"); - f.setAccessible(true); - f.set(functionProperties, bindingServiceProperties); - return functionProperties; - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - - private StreamFunctionProperties createStreamFunctionPropertiesWithNativeEncoding() { - StreamFunctionProperties functionProperties = new StreamFunctionProperties(); - functionProperties.setInputDestinationName("input"); - functionProperties.setOutputDestinationName("output"); - BindingServiceProperties bindingServiceProperties = new BindingServiceProperties(); - bindingServiceProperties.getConsumerProperties("input").setMaxAttempts(3); - bindingServiceProperties.getProducerProperties("output").setUseNativeEncoding(true); - try { - Field bspField = ReflectionUtils.findField(StreamFunctionProperties.class, "bindingServiceProperties"); - bspField.setAccessible(true); - bspField.set(functionProperties, bindingServiceProperties); - return functionProperties; - } catch (Exception e) { - throw new IllegalStateException(e); - } } @EnableAutoConfiguration @@ -332,17 +384,20 @@ public class FunctionInvokerTests { @Bean public Function, Message> messageToMessageDifferentType() { - return x -> MessageBuilder.withPayload(new Bar()).copyHeaders(x.getHeaders()).build(); + return x -> MessageBuilder.withPayload(new Bar()).copyHeaders(x.getHeaders()) + .build(); } @Bean public Function, Message> messageToMessageAnyType() { - return x -> MessageBuilder.withPayload(new Bar()).copyHeaders(x.getHeaders()).build(); + return x -> MessageBuilder.withPayload(new Bar()).copyHeaders(x.getHeaders()) + .build(); } @Bean public Function, Message> messageToMessageNoType() { - return x -> MessageBuilder.withPayload(new Bar()).copyHeaders(x.getHeaders()).build(); + return x -> MessageBuilder.withPayload(new Bar()).copyHeaders(x.getHeaders()) + .build(); } @Bean @@ -380,7 +435,8 @@ public class FunctionInvokerTests { if (x instanceof ErrorBaz) { System.out.println("Throwing exception "); throw new RuntimeException("Boom!"); - } else { + } + else { System.out.println("All is good "); return x; } @@ -400,4 +456,5 @@ public class FunctionInvokerTests { private static class Bar { } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/GreenfieldFunctionEnableBindingTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/GreenfieldFunctionEnableBindingTests.java index 8234370c8..ed906fcdf 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/GreenfieldFunctionEnableBindingTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/GreenfieldFunctionEnableBindingTests.java @@ -58,7 +58,8 @@ import org.springframework.messaging.support.MessageBuilder; import static org.assertj.core.api.Assertions.assertThat; /** - * This test validates proper function binding for applications where EnableBinding is declared. + * This test validates proper function binding for applications where EnableBinding is + * declared. * * @author Oleg Zhurakousky * @author Artem Bilan @@ -68,16 +69,23 @@ public class GreenfieldFunctionEnableBindingTests { @Test public void testSourceFromSupplier() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(SourceFromSupplier.class)).web( - WebApplicationType.NONE).run("--spring.cloud.stream.function.definition=date", "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration + .getCompleteConfiguration(SourceFromSupplier.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=date", + "--spring.jmx.enabled=false")) { OutputDestination target = context.getBean(OutputDestination.class); Message sourceMessage = target.receive(10000); - Date date = (Date) new CompositeMessageConverterFactory().getMessageConverterForAllRegistered().fromMessage(sourceMessage, Date.class); + Date date = (Date) new CompositeMessageConverterFactory() + .getMessageConverterForAllRegistered() + .fromMessage(sourceMessage, Date.class); assertThat(date).isEqualTo(new Date(12345L)); sourceMessage = target.receive(10000); - date = (Date) new CompositeMessageConverterFactory().getMessageConverterForAllRegistered().fromMessage(sourceMessage, Date.class); + date = (Date) new CompositeMessageConverterFactory() + .getMessageConverterForAllRegistered() + .fromMessage(sourceMessage, Date.class); assertThat(date).isEqualTo(new Date(12345L)); } } @@ -85,21 +93,27 @@ public class GreenfieldFunctionEnableBindingTests { @Test public void testProcessorFromFunction() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(ProcessorFromFunction.class)).web( - WebApplicationType.NONE).run("--spring.cloud.stream.function.definition=toUpperCase", "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + ProcessorFromFunction.class)).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.function.definition=toUpperCase", + "--spring.jmx.enabled=false")) { InputDestination source = context.getBean(InputDestination.class); source.send(new GenericMessage("John Doe".getBytes())); OutputDestination target = context.getBean(OutputDestination.class); - assertThat(target.receive(10000).getPayload()).isEqualTo("JOHN DOE".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(10000).getPayload()) + .isEqualTo("JOHN DOE".getBytes(StandardCharsets.UTF_8)); } } @Test public void testSinkFromConsumer() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(SinkFromConsumer.class)).web( - WebApplicationType.NONE).run("--spring.cloud.stream.function.definition=sink", "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration + .getCompleteConfiguration(SinkFromConsumer.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=sink", + "--spring.jmx.enabled=false")) { InputDestination source = context.getBean(InputDestination.class); PollableChannel result = context.getBean("result", PollableChannel.class); @@ -111,14 +125,15 @@ public class GreenfieldFunctionEnableBindingTests { @Test public void testHttpEndpoint() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(HttpInboundEndpoint.class)) - .web(WebApplicationType.SERVLET) - .run("--spring.cloud.stream.function.definition=upperCase", - "--spring.jmx.enabled=false", - "--server.port=0")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + HttpInboundEndpoint.class)).web(WebApplicationType.SERVLET).run( + "--spring.cloud.stream.function.definition=upperCase", + "--spring.jmx.enabled=false", "--server.port=0")) { TestRestTemplate restTemplate = new TestRestTemplate(); restTemplate.postForLocation( - "http://localhost:" + context.getEnvironment().getProperty("local.server.port"), "hello"); + "http://localhost:" + + context.getEnvironment().getProperty("local.server.port"), + "hello"); OutputDestination target = context.getBean(OutputDestination.class); String result = new String(target.receive(10000).getPayload()); @@ -130,9 +145,11 @@ public class GreenfieldFunctionEnableBindingTests { @Test public void testPojoReturn() throws IOException { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(FooTransform.class)).web( - WebApplicationType.NONE).run("--spring.cloud.stream.function.definition=fooFunction", "--spring.jmx" - + ".enabled=false", "--logging.level.org.springframework.integration=TRACE")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + FooTransform.class)).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.function.definition=fooFunction", + "--spring.jmx" + ".enabled=false", + "--logging.level.org.springframework.integration=TRACE")) { MessageChannel input = context.getBean("input", MessageChannel.class); OutputDestination target = context.getBean(OutputDestination.class); @@ -147,7 +164,6 @@ public class GreenfieldFunctionEnableBindingTests { } } - @EnableAutoConfiguration @EnableBinding(Source.class) public static class SourceFromSupplier { @@ -205,8 +221,8 @@ public class GreenfieldFunctionEnableBindingTests { public HttpRequestHandlingEndpointSupport doFoo() { HttpRequestHandlerEndpointSpec httpRequestHandler = Http .inboundChannelAdapter("/*") - .requestMapping(requestMapping -> requestMapping.methods(HttpMethod.POST) - .consumes("*/*")) + .requestMapping(requestMapping -> requestMapping + .methods(HttpMethod.POST).consumes("*/*")) .requestChannel(this.source.output()); return httpRequestHandler.get(); } @@ -233,7 +249,7 @@ public class GreenfieldFunctionEnableBindingTests { return m -> { Foo foo = new Foo(); foo.setBar(m.getPayload().toString()); - return MessageBuilder.withPayload(foo).setHeader("foo","foo").build(); + return MessageBuilder.withPayload(foo).setHeader("foo", "foo").build(); }; } @@ -244,12 +260,13 @@ public class GreenfieldFunctionEnableBindingTests { String bar; public String getBar() { - return bar; + return this.bar; } public void setBar(String bar) { this.bar = bar; } + } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ProcessorToFunctionsSupportTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ProcessorToFunctionsSupportTests.java index b88c0fbdc..3ee708a19 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ProcessorToFunctionsSupportTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ProcessorToFunctionsSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-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. @@ -54,43 +54,47 @@ public class ProcessorToFunctionsSupportTests { @After public void cleanUp() { - context.close(); + this.context.close(); } @Test public void testPathThrough() { - context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(FunctionsConfiguration.class)).web( - WebApplicationType.NONE).run("--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); + this.context = new SpringApplicationBuilder(TestChannelBinderConfiguration + .getCompleteConfiguration(FunctionsConfiguration.class)) + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false"); + InputDestination source = this.context.getBean(InputDestination.class); + OutputDestination target = this.context.getBean(OutputDestination.class); source.send(new GenericMessage("hello".getBytes(StandardCharsets.UTF_8))); - assertThat(target.receive(1000).getPayload()).isEqualTo("hello".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(1000).getPayload()) + .isEqualTo("hello".getBytes(StandardCharsets.UTF_8)); } @Test public void testSingleFunction() { - context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(FunctionsConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=toUpperCase", "--spring.jmx.enabled=false"); + this.context = new SpringApplicationBuilder(TestChannelBinderConfiguration + .getCompleteConfiguration(FunctionsConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=toUpperCase", + "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); + InputDestination source = this.context.getBean(InputDestination.class); + OutputDestination target = this.context.getBean(OutputDestination.class); source.send(new GenericMessage("hello".getBytes(StandardCharsets.UTF_8))); - assertThat(target.receive(1000).getPayload()).isEqualTo("HELLO".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(1000).getPayload()) + .isEqualTo("HELLO".getBytes(StandardCharsets.UTF_8)); } @Test public void testComposedFunction() { - context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(FunctionsConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", - "--spring.jmx" + ".enabled=false", "--logging.level.org.springframework.integration=DEBUG"); + this.context = new SpringApplicationBuilder(TestChannelBinderConfiguration + .getCompleteConfiguration(FunctionsConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", + "--spring.jmx" + ".enabled=false", + "--logging.level.org.springframework.integration=DEBUG"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); + InputDestination source = this.context.getBean(InputDestination.class); + OutputDestination target = this.context.getBean(OutputDestination.class); source.send(new GenericMessage("hello".getBytes(StandardCharsets.UTF_8))); String result = new String(target.receive(1000).getPayload()); System.out.println(result); @@ -99,18 +103,25 @@ public class ProcessorToFunctionsSupportTests { @Test public void testConsumer() { - context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(ConsumerConfiguration.class)).web( - WebApplicationType.NONE).run("--spring.cloud.stream.function.definition=log", "--spring.jmx.enabled=false"); + this.context = new SpringApplicationBuilder(TestChannelBinderConfiguration + .getCompleteConfiguration(ConsumerConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=log", + "--spring.jmx.enabled=false"); - InputDestination source = context.getBean(InputDestination.class); - OutputDestination target = context.getBean(OutputDestination.class); + InputDestination source = this.context.getBean(InputDestination.class); + OutputDestination target = this.context.getBean(OutputDestination.class); source.send(new GenericMessage("hello".getBytes(StandardCharsets.UTF_8))); - source.send(new GenericMessage("hello1".getBytes(StandardCharsets.UTF_8))); - source.send(new GenericMessage("hello2".getBytes(StandardCharsets.UTF_8))); - assertThat(target.receive(1000).getPayload()).isEqualTo("hello".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(1000).getPayload()).isEqualTo("hello1".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(1000).getPayload()).isEqualTo("hello2".getBytes(StandardCharsets.UTF_8)); + source.send( + new GenericMessage("hello1".getBytes(StandardCharsets.UTF_8))); + source.send( + new GenericMessage("hello2".getBytes(StandardCharsets.UTF_8))); + assertThat(target.receive(1000).getPayload()) + .isEqualTo("hello".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(1000).getPayload()) + .isEqualTo("hello1".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(1000).getPayload()) + .isEqualTo("hello2".getBytes(StandardCharsets.UTF_8)); } @EnableAutoConfiguration @@ -126,6 +137,7 @@ public class ProcessorToFunctionsSupportTests { public Function concatWithSelf() { return x -> x + ":" + x; } + } @EnableAutoConfiguration @@ -138,16 +150,17 @@ public class ProcessorToFunctionsSupportTests { @Bean public Consumer log() { return x -> { - DirectFieldAccessor dfa = new DirectFieldAccessor(out); + DirectFieldAccessor dfa = new DirectFieldAccessor(this.out); MessageChannel channel = (MessageChannel) dfa.getPropertyValue("channel"); channel.send(new GenericMessage(x.getBytes())); }; } + } /** - * This configuration essentially emulates our existing app-starters for Processor - * and essentially demonstrates how a function(s) could be applied to an existing + * This configuration essentially emulates our existing app-starters for Processor and + * essentially demonstrates how a function(s) could be applied to an existing * processor app via {@link IntegrationFlowFunctionSupport} class. */ @EnableBinding(Processor.class) @@ -159,9 +172,10 @@ public class ProcessorToFunctionsSupportTests { @Bean public IntegrationFlow fromChannel() { - return IntegrationFlows.from(processor.input()) - .channel(processor.output()).get(); + return IntegrationFlows.from(this.processor.input()) + .channel(this.processor.output()).get(); } } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/SourceToFunctionsSupportTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/SourceToFunctionsSupportTests.java index 08ab6c9ee..5e1666731 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/SourceToFunctionsSupportTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/SourceToFunctionsSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -48,8 +48,6 @@ import org.springframework.util.Assert; import org.springframework.util.MimeTypeUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; /** * @author Oleg Zhurakousky @@ -64,111 +62,130 @@ public class SourceToFunctionsSupportTests { @Test public void testFunctionIsAppliedToExistingMessageSource() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(FunctionsConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=toUpperCase", "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + FunctionsConfiguration.class)).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.function.definition=toUpperCase", + "--spring.jmx.enabled=false")) { OutputDestination target = context.getBean(OutputDestination.class); - assertThat(target.receive(1000).getPayload()).isEqualTo("HELLO FUNCTION".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(1000).getPayload()) + .isEqualTo("HELLO FUNCTION".getBytes(StandardCharsets.UTF_8)); } } @Test public void testComposedFunctionIsAppliedToExistingMessageSource() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(FunctionsConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", - "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + FunctionsConfiguration.class)).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", + "--spring.jmx.enabled=false")) { OutputDestination target = context.getBean(OutputDestination.class); assertThat(target.receive(1000).getPayload()).isEqualTo( - "HELLO FUNCTION:HELLO FUNCTION".getBytes(StandardCharsets.UTF_8)); + "HELLO FUNCTION:HELLO FUNCTION".getBytes(StandardCharsets.UTF_8)); } } @Test public void testFailedInputTypeConversion() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration( - FunctionsConfigurationNoConversionPossible.class)).web(WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", - "--spring.jmx.enabled=false")) { - PollableChannel errorChannel = context.getBean("errorChannel", PollableChannel.class); + TestChannelBinderConfiguration.getCompleteConfiguration( + FunctionsConfigurationNoConversionPossible.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", + "--spring.jmx.enabled=false")) { + PollableChannel errorChannel = context.getBean("errorChannel", + PollableChannel.class); OutputDestination target = context.getBean(OutputDestination.class); - assertNull(target.receive(1000)); - assertNotNull(errorChannel.receive(10000)); + assertThat(target.receive(1000)).isNull(); + assertThat(errorChannel.receive(10000)).isNotNull(); } } @Test public void testComposedFunctionIsAppliedToExistingMessageSourceFailedTypeConversion() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration( - FunctionsConfigurationNoConversionPossible.class)).web(WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", - "--spring.jmx.enabled=false")) { - PollableChannel errorChannel = context.getBean("errorChannel", PollableChannel.class); + TestChannelBinderConfiguration.getCompleteConfiguration( + FunctionsConfigurationNoConversionPossible.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=toUpperCase|concatWithSelf", + "--spring.jmx.enabled=false")) { + PollableChannel errorChannel = context.getBean("errorChannel", + PollableChannel.class); OutputDestination target = context.getBean(OutputDestination.class); - assertNull(target.receive(1000)); - assertNotNull(errorChannel.receive(10000)); + assertThat(target.receive(1000)).isNull(); + assertThat(errorChannel.receive(10000)).isNotNull(); } } @Test public void testMessageSourceIsCreatedFromProvidedSupplier() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=number", "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration + .getCompleteConfiguration(SupplierConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=number", + "--spring.jmx.enabled=false")) { OutputDestination target = context.getBean(OutputDestination.class); - assertThat(target.receive(10000).getPayload()).isEqualTo("1".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(10000).getPayload()).isEqualTo("2".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(10000).getPayload()).isEqualTo("3".getBytes(StandardCharsets.UTF_8)); - //etc + assertThat(target.receive(10000).getPayload()) + .isEqualTo("1".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(10000).getPayload()) + .isEqualTo("2".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(10000).getPayload()) + .isEqualTo("3".getBytes(StandardCharsets.UTF_8)); + // etc } } @Test public void testMessageSourceIsCreatedFromProvidedSupplierComposedWithSingleFunction() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=number|concatWithSelf", "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + SupplierConfiguration.class)).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.function.definition=number|concatWithSelf", + "--spring.jmx.enabled=false")) { OutputDestination target = context.getBean(OutputDestination.class); - assertThat(target.receive(10000).getPayload()).isEqualTo("11".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(10000).getPayload()).isEqualTo("22".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(10000).getPayload()).isEqualTo("33".getBytes(StandardCharsets.UTF_8)); - //etc + assertThat(target.receive(10000).getPayload()) + .isEqualTo("11".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(10000).getPayload()) + .isEqualTo("22".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(10000).getPayload()) + .isEqualTo("33".getBytes(StandardCharsets.UTF_8)); + // etc } } @Test public void testMessageSourceIsCreatedFromProvidedSupplierComposedWithMultipleFunctions() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=number|concatWithSelf|multiplyByTwo", - "--spring.jmx.enabled=false")) { + TestChannelBinderConfiguration.getCompleteConfiguration( + SupplierConfiguration.class)).web(WebApplicationType.NONE).run( + "--spring.cloud.stream.function.definition=number|concatWithSelf|multiplyByTwo", + "--spring.jmx.enabled=false")) { OutputDestination target = context.getBean(OutputDestination.class); - assertThat(target.receive(10000).getPayload()).isEqualTo("22".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(10000).getPayload()).isEqualTo("44".getBytes(StandardCharsets.UTF_8)); - assertThat(target.receive(10000).getPayload()).isEqualTo("66".getBytes(StandardCharsets.UTF_8)); - //etc + assertThat(target.receive(10000).getPayload()) + .isEqualTo("22".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(10000).getPayload()) + .isEqualTo("44".getBytes(StandardCharsets.UTF_8)); + assertThat(target.receive(10000).getPayload()) + .isEqualTo("66".getBytes(StandardCharsets.UTF_8)); + // etc } } @Test public void testFunctionDoesNotExist() { - expectedException.expect(BeanCreationException.class); + this.expectedException.expect(BeanCreationException.class); - new SpringApplicationBuilder( - TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class)).web( - WebApplicationType.NONE) - .run("--spring.cloud.stream.function.definition=doesNotExist", "--spring.jmx.enabled=false"); + new SpringApplicationBuilder(TestChannelBinderConfiguration + .getCompleteConfiguration(SupplierConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.cloud.stream.function.definition=doesNotExist", + "--spring.jmx.enabled=false"); } @EnableAutoConfiguration @@ -179,7 +196,7 @@ public class SourceToFunctionsSupportTests { @Bean public Supplier number() { - return () -> String.valueOf(counter.incrementAndGet()); + return () -> String.valueOf(this.counter.incrementAndGet()); } @Bean @@ -232,9 +249,9 @@ public class SourceToFunctionsSupportTests { } /** - * This configuration essentially emulates our existing app-starters for Sources - * and essentially demonstrates how a function(s) could be applied to an existing - * source via {@link IntegrationFlowFunctionSupport} class. + * This configuration essentially emulates our existing app-starters for Sources and + * essentially demonstrates how a function(s) could be applied to an existing source + * via {@link IntegrationFlowFunctionSupport} class. */ @EnableBinding(Source.class) public static class ExistingMessageSourceConfiguration { @@ -243,14 +260,15 @@ public class SourceToFunctionsSupportTests { private Source source; @Bean - public IntegrationFlow messageSourceFlow(IntegrationFlowFunctionSupport functionSupport) { - Supplier> messageSource = () -> MessageBuilder.withPayload("hello function") - .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) - .build(); + public IntegrationFlow messageSourceFlow( + IntegrationFlowFunctionSupport functionSupport) { + Supplier> messageSource = () -> MessageBuilder + .withPayload("hello function") + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN) + .build(); return functionSupport.integrationFlowFromProvidedSupplier(messageSource) - .channel(this.source.output()) - .get(); + .channel(this.source.output()).get(); } } @@ -262,14 +280,15 @@ public class SourceToFunctionsSupportTests { private Source source; @Bean - public IntegrationFlow messageSourceFlow(IntegrationFlowFunctionSupport functionSupport) { - Supplier> messageSource = () -> MessageBuilder.withPayload("hello function") - .setHeader(MessageHeaders.CONTENT_TYPE, "application/octet-stream") - .build(); + public IntegrationFlow messageSourceFlow( + IntegrationFlowFunctionSupport functionSupport) { + Supplier> messageSource = () -> MessageBuilder + .withPayload("hello function") + .setHeader(MessageHeaders.CONTENT_TYPE, "application/octet-stream") + .build(); return functionSupport.integrationFlowFromProvidedSupplier(messageSource) - .channel(this.source.output()) - .get(); + .channel(this.source.output()).get(); } } @@ -284,10 +303,13 @@ public class SourceToFunctionsSupportTests { private StreamFunctionProperties functionProperties; @Bean - public IntegrationFlow messageSourceFlow(IntegrationFlowFunctionSupport functionSupport) { - Assert.hasText(this.functionProperties.getDefinition(), "Supplier name must be provided"); + public IntegrationFlow messageSourceFlow( + IntegrationFlowFunctionSupport functionSupport) { + Assert.hasText(this.functionProperties.getDefinition(), + "Supplier name must be provided"); - return functionSupport.integrationFlowFromNamedSupplier().channel(this.source.output()).get(); + return functionSupport.integrationFlowFromNamedSupplier() + .channel(this.source.output()).get(); } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/Baz.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/Baz.java index d2e907c12..120305121 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/Baz.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/Baz.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -16,19 +16,21 @@ package org.springframework.cloud.stream.function.pojo; - /** * Serializable pojo with object mapper. + * * @author Tolga Kavukcu */ public class Baz { + private String baz = "baz"; public String getBaz() { - return baz; + return this.baz; } public void setBaz(String baz) { this.baz = baz; } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/ErrorBaz.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/ErrorBaz.java index 17443da1b..ee55c990e 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/ErrorBaz.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/pojo/ErrorBaz.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -16,19 +16,21 @@ package org.springframework.cloud.stream.function.pojo; - /** * Serializable pojo with object mapper. + * * @author Tolga Kavukcu */ -public class ErrorBaz extends Baz{ +public class ErrorBaz extends Baz { + private String baz = "bazError"; public String getBaz() { - return baz; + return this.baz; } public void setBaz(String baz) { this.baz = baz; } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/interceptor/BoundChannelsInterceptedTest.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/interceptor/BoundChannelsInterceptedTest.java index bee474540..9530fbeff 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/interceptor/BoundChannelsInterceptedTest.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/interceptor/BoundChannelsInterceptedTest.java @@ -46,21 +46,27 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Oleg Zhurakousky */ @RunWith(SpringJUnit4ClassRunner.class) +// @checkstyle:off @SpringBootTest(classes = BoundChannelsInterceptedTest.Foo.class, properties = "spring.cloud.stream.default-binder=mock") public class BoundChannelsInterceptedTest { - public static final Message TEST_MESSAGE = MessageBuilder.withPayload("bar").setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON).build(); + // @checkstyle:on - @Autowired - private Sink sink; + public static final Message TEST_MESSAGE = MessageBuilder.withPayload("bar") + .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON) + .build(); @Autowired ChannelInterceptor channelInterceptor; + @Autowired + private Sink sink; + @Test public void testBoundChannelsIntercepted() { - sink.input().send(TEST_MESSAGE); - verify(this.channelInterceptor).preSend(Mockito.any(), Mockito.eq(this.sink.input())); + this.sink.input().send(TEST_MESSAGE); + verify(this.channelInterceptor).preSend(Mockito.any(), + Mockito.eq(this.sink.input())); verifyNoMoreInteractions(this.channelInterceptor); } @@ -79,4 +85,5 @@ public class BoundChannelsInterceptedTest { } } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionKeyExtractorClass.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionKeyExtractorClass.java index e4c02d4a1..260baab80 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionKeyExtractorClass.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionKeyExtractorClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,4 +28,5 @@ public class CustomPartitionKeyExtractorClass implements PartitionKeyExtractorSt public String extractKey(Message message) { return (String) message.getHeaders().get("key"); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionSelectorClass.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionSelectorClass.java index b4f19cc66..4f93a41b1 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionSelectorClass.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/CustomPartitionSelectorClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2017-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,4 +27,5 @@ public class CustomPartitionSelectorClass implements PartitionSelectorStrategy { public int selectPartition(Object key, int partitionCount) { return Integer.valueOf((String) key); } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/PartitionedConsumerTest.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/PartitionedConsumerTest.java index 38c24fd92..f410c9db6 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/PartitionedConsumerTest.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/partitioning/PartitionedConsumerTest.java @@ -16,10 +16,8 @@ package org.springframework.cloud.stream.partitioning; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; - import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; @@ -37,7 +35,7 @@ import org.springframework.context.annotation.PropertySource; import org.springframework.messaging.MessageChannel; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import static org.hamcrest.Matchers.equalTo; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.verify; @@ -49,9 +47,11 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; * @author Janne Valkealahti */ @RunWith(SpringJUnit4ClassRunner.class) +// @checkstyle:off @SpringBootTest(classes = PartitionedConsumerTest.TestSink.class, properties = "spring.cloud.stream.default-binder=mock") public class PartitionedConsumerTest { + // @checkstyle:on @Autowired private BinderFactory binderFactory; @@ -59,14 +59,15 @@ public class PartitionedConsumerTest { private Sink testSink; @Test - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) public void testBindingPartitionedConsumer() { Binder binder = this.binderFactory.getBinder(null, MessageChannel.class); - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(ConsumerProperties.class); + ArgumentCaptor argumentCaptor = ArgumentCaptor + .forClass(ConsumerProperties.class); verify(binder).bindConsumer(eq("partIn"), isNull(), eq(this.testSink.input()), argumentCaptor.capture()); - Assert.assertThat(argumentCaptor.getValue().getInstanceIndex(), equalTo(0)); - Assert.assertThat(argumentCaptor.getValue().getInstanceCount(), equalTo(2)); + assertThat(argumentCaptor.getValue().getInstanceIndex()).isEqualTo(0); + assertThat(argumentCaptor.getValue().getInstanceCount()).isEqualTo(2); verifyNoMoreInteractions(binder); } @@ -84,6 +85,7 @@ public class PartitionedConsumerTest { public boolean matches(ConsumerProperties argument) { return argument instanceof ConsumerProperties; } + } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooBindingProperties.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooBindingProperties.java index c0c7ab006..8d47fb6f5 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooBindingProperties.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooBindingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -28,7 +28,7 @@ public class FooBindingProperties implements BinderSpecificPropertiesProvider { private FooConsumerProperties consumer = new FooConsumerProperties(); public FooProducerProperties getProducer() { - return producer; + return this.producer; } public void setProducer(FooProducerProperties producer) { @@ -36,10 +36,11 @@ public class FooBindingProperties implements BinderSpecificPropertiesProvider { } public FooConsumerProperties getConsumer() { - return consumer; + return this.consumer; } public void setConsumer(FooConsumerProperties consumer) { this.consumer = consumer; } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooConsumerProperties.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooConsumerProperties.java index 6bd3cb2e4..654a8f68b 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooConsumerProperties.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooConsumerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -24,10 +24,11 @@ public class FooConsumerProperties { String extendedProperty; public String getExtendedProperty() { - return extendedProperty; + return this.extendedProperty; } public void setExtendedProperty(String extendedProperty) { this.extendedProperty = extendedProperty; } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooExtendedBindingProperties.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooExtendedBindingProperties.java index 7df1746ea..7cef77766 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooExtendedBindingProperties.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooExtendedBindingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -24,7 +24,8 @@ import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider; * @author Soby Chacko */ @ConfigurationProperties("spring.cloud.stream.foo") -public class FooExtendedBindingProperties extends AbstractExtendedBindingProperties { +public class FooExtendedBindingProperties extends + AbstractExtendedBindingProperties { private static final String DEFAULTS_PREFIX = "spring.cloud.stream.foo.default"; @@ -37,5 +38,5 @@ public class FooExtendedBindingProperties extends AbstractExtendedBindingPropert public Class getExtendedPropertiesEntryClass() { return FooBindingProperties.class; } -} +} diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooProducerProperties.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooProducerProperties.java index 69d4c2a42..dbf06e04b 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooProducerProperties.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/FooProducerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -24,10 +24,11 @@ public class FooProducerProperties { String extendedProperty; public String getExtendedProperty() { - return extendedProperty; + return this.extendedProperty; } public void setExtendedProperty(String extendedProperty) { this.extendedProperty = extendedProperty; } + } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockBinderConfiguration.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockBinderConfiguration.java index 0a1f67447..38791b58a 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockBinderConfiguration.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockBinderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ public class MockBinderConfiguration { @Bean public Binder binder() { - return Mockito.mock(Binder.class, Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)); + return Mockito.mock(Binder.class, + Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)); } } diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockExtendedBinderConfiguration.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockExtendedBinderConfiguration.java index c55c58e11..edcc9447e 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockExtendedBinderConfiguration.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/utils/MockExtendedBinderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or 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. @@ -42,13 +42,17 @@ public class MockExtendedBinderConfiguration { @SuppressWarnings("rawtypes") @Bean public Binder extendedPropertiesBinder() { - Binder mock = Mockito.mock(Binder.class, Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS) - .extraInterfaces(ExtendedPropertiesBinder.class)); + Binder mock = Mockito.mock(Binder.class, + Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS) + .extraInterfaces(ExtendedPropertiesBinder.class)); ConfigurableEnvironment environment = new StandardEnvironment(); Map propertiesToAdd = new HashMap<>(); - propertiesToAdd.put("spring.cloud.stream.foo.default.consumer.extendedProperty", "someFancyExtension"); - propertiesToAdd.put("spring.cloud.stream.foo.default.producer.extendedProperty", "someFancyExtension"); - environment.getPropertySources().addLast(new MapPropertySource("extPropertiesConfig", propertiesToAdd)); + propertiesToAdd.put("spring.cloud.stream.foo.default.consumer.extendedProperty", + "someFancyExtension"); + propertiesToAdd.put("spring.cloud.stream.foo.default.producer.extendedProperty", + "someFancyExtension"); + environment.getPropertySources() + .addLast(new MapPropertySource("extPropertiesConfig", propertiesToAdd)); ConfigurableApplicationContext applicationContext = new GenericApplicationContext(); applicationContext.setEnvironment(environment); @@ -56,13 +60,15 @@ public class MockExtendedBinderConfiguration { FooExtendedBindingProperties fooExtendedBindingProperties = new FooExtendedBindingProperties(); fooExtendedBindingProperties.setApplicationContext(applicationContext); - final FooConsumerProperties fooConsumerProperties = fooExtendedBindingProperties.getExtendedConsumerProperties("input"); - final FooProducerProperties fooProducerProperties = fooExtendedBindingProperties.getExtendedProducerProperties("output"); + final FooConsumerProperties fooConsumerProperties = fooExtendedBindingProperties + .getExtendedConsumerProperties("input"); + final FooProducerProperties fooProducerProperties = fooExtendedBindingProperties + .getExtendedProducerProperties("output"); - when (((ExtendedPropertiesBinder)mock).getExtendedConsumerProperties("input")) + when(((ExtendedPropertiesBinder) mock).getExtendedConsumerProperties("input")) .thenReturn(fooConsumerProperties); - when (((ExtendedPropertiesBinder)mock).getExtendedProducerProperties("output")) + when(((ExtendedPropertiesBinder) mock).getExtendedProducerProperties("output")) .thenReturn(fooProducerProperties); return mock; diff --git a/spring-cloud-stream/src/test/resources/binder1/META-INF/spring.binders b/spring-cloud-stream/src/test/resources/binder1/META-INF/spring.binders index d3bb4866b..1d4a3007d 100644 --- a/spring-cloud-stream/src/test/resources/binder1/META-INF/spring.binders +++ b/spring-cloud-stream/src/test/resources/binder1/META-INF/spring.binders @@ -1 +1 @@ -binder1=org.springframework.cloud.stream.binder.stub1.StubBinder1Configuration \ No newline at end of file +binder1=org.springframework.cloud.stream.binder.stub1.StubBinder1Configuration diff --git a/spring-cloud-stream/src/test/resources/binder2/META-INF/spring.binders b/spring-cloud-stream/src/test/resources/binder2/META-INF/spring.binders index f5bb5abaa..26dc2bc5e 100644 --- a/spring-cloud-stream/src/test/resources/binder2/META-INF/spring.binders +++ b/spring-cloud-stream/src/test/resources/binder2/META-INF/spring.binders @@ -1,3 +1,3 @@ binder2:\ org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationA,\ -org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationB \ No newline at end of file +org.springframework.cloud.stream.binder.stub2.StubBinder2ConfigurationB diff --git a/spring-cloud-stream/src/test/resources/org/springframework/cloud/stream/binder/cloud-function-test.properties b/spring-cloud-stream/src/test/resources/org/springframework/cloud/stream/binder/cloud-function-test.properties index 2f517c8e6..9c3e4cf55 100644 --- a/spring-cloud-stream/src/test/resources/org/springframework/cloud/stream/binder/cloud-function-test.properties +++ b/spring-cloud-stream/src/test/resources/org/springframework/cloud/stream/binder/cloud-function-test.properties @@ -1,2 +1,2 @@ -spring.cloud.stream.function.producerProperties.useNativeEncoding: true -spring.cloud.stream.function.consumerProperties.maxAttempts: 5 +spring.cloud.stream.function.producerProperties.useNativeEncoding:true +spring.cloud.stream.function.consumerProperties.maxAttempts:5