Added checkstyle

This commit is contained in:
Marcin Grzejszczak
2019-02-04 15:55:35 +01:00
parent c6d238085f
commit a8cbf77794
362 changed files with 8885 additions and 6508 deletions

14
.editorconfig Normal file
View File

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

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

@@ -0,0 +1,110 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
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();
}
}

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

Binary file not shown.

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

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

View File

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

View File

@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-core-docs</artifactId>
<parent>
@@ -15,36 +17,35 @@
<main.basedir>${basedir}/..</main.basedir>
</properties>
<profiles>
<profile>
<id>docs</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<inherited>false</inherited>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<profile>
<id>docs</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<inherited>false</inherited>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -88,7 +88,7 @@ public class StreamApplicationTests {
@Test
public void contextLoads() {
assertNotNull(this.sink.input());
assertThat(this.sink.input()).isNotNull();
}
}
----

169
mvnw vendored
View File

@@ -54,38 +54,16 @@ case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
#
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
# for the new JDKs provided by Oracle.
#
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
#
# Oracle JDKs
#
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
#
# Apple JDKs
#
export JAVA_HOME=`/usr/libexec/java_home`
fi
;;
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
@@ -130,7 +108,7 @@ if $cygwin ; then
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Migwn, ensure paths are in UNIX format before anything is touched
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
@@ -184,27 +162,28 @@ fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
local basedir=$(pwd)
local wdir=$(pwd)
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
wdir=$(cd "$wdir/.."; pwd)
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
@@ -216,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 '\!<parent!,\!</parent!d' `dirname $0`/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!' )
echo "The found version is [${VERSION}]"
if echo $VERSION | egrep -q 'M|RC'; then
echo Activating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
else
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
fi
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 "$@"

26
mvnw.cmd vendored Normal file → Executable file
View File

@@ -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

548
pom.xml
View File

@@ -1,282 +1,276 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-parent</artifactId>
<version>2.1.1.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>2.1.0.BUILD-SNAPSHOT</version>
<relativePath/>
</parent>
<scm>
<url>https://github.com/spring-cloud/spring-cloud-stream</url>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-stream.git</connection>
<developerConnection>scm:git:ssh://git@github.com/spring-cloud/spring-cloud-stream.git</developerConnection>
<tag>HEAD</tag>
</scm>
<properties>
<java.version>1.8</java.version>
<spring.tuple.version>1.0.0.RELEASE</spring.tuple.version>
<spring.integration.tuple.version>1.0.0.RELEASE</spring.integration.tuple.version>
<reactor.version>Californium-RELEASE</reactor.version>
<kryo-shaded.version>3.0.3</kryo-shaded.version>
<objenesis.version>2.1</objenesis.version>
<spring-cloud-function.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-function.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
<version>${spring-cloud-function.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-tools</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-schema-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-test</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tuple</artifactId>
<version>${spring.tuple.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-tuple</artifactId>
<version>${spring.integration.tuple.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support-internal</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo-shaded</artifactId>
<version>${kryo-shaded.version}</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>${reactor.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>${objenesis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
<classifier>test-binder</classifier>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>spring-cloud-stream</module>
<module>spring-cloud-stream-binder-test</module>
<module>spring-cloud-stream-test-support</module>
<module>spring-cloud-stream-test-support-internal</module>
<module>spring-cloud-stream-integration-tests</module>
<module>spring-cloud-stream-reactive</module>
<module>spring-cloud-stream-schema</module>
<module>spring-cloud-stream-schema-server</module>
<module>spring-cloud-stream-tools</module>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-parent</artifactId>
<version>2.1.1.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>2.1.3.BUILD-SNAPSHOT</version>
<relativePath/>
</parent>
<scm>
<url>https://github.com/spring-cloud/spring-cloud-stream</url>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-stream.git
</connection>
<developerConnection>
scm:git:ssh://git@github.com/spring-cloud/spring-cloud-stream.git
</developerConnection>
<tag>HEAD</tag>
</scm>
<properties>
<java.version>1.8</java.version>
<spring.tuple.version>1.0.0.RELEASE</spring.tuple.version>
<spring.integration.tuple.version>1.0.0.RELEASE</spring.integration.tuple.version>
<reactor.version>Californium-RELEASE</reactor.version>
<kryo-shaded.version>3.0.3</kryo-shaded.version>
<objenesis.version>2.1</objenesis.version>
<spring-cloud-function.version>2.0.0.BUILD-SNAPSHOT
</spring-cloud-function.version>
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError>
<maven-checkstyle-plugin.failsOnViolation>true
</maven-checkstyle-plugin.failsOnViolation>
<maven-checkstyle-plugin.includeTestSourceDirectory>true
</maven-checkstyle-plugin.includeTestSourceDirectory>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
<version>${spring-cloud-function.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-tools</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-schema-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-test</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tuple</artifactId>
<version>${spring.tuple.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-tuple</artifactId>
<version>${spring.integration.tuple.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-support-internal</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo-shaded</artifactId>
<version>${kryo-shaded.version}</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>${reactor.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>${objenesis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
<classifier>test-binder</classifier>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>spring-cloud-stream</module>
<module>spring-cloud-stream-binder-test</module>
<module>spring-cloud-stream-test-support</module>
<module>spring-cloud-stream-test-support-internal</module>
<module>spring-cloud-stream-integration-tests</module>
<module>spring-cloud-stream-reactive</module>
<module>spring-cloud-stream-schema</module>
<module>spring-cloud-stream-schema-server</module>
<module>docs</module>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>7.1</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<quiet>true</quiet>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<quiet>true</quiet>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerArgument>-parameters</compilerArgument>
</configuration>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<executions>
<execution>
<id>checkstyle-validation</id>
<phase>validate</phase>
<configuration>
<configLocation>spring-cloud-stream-tools/src/main/resources/checkstyle.xml</configLocation>
<headerLocation>spring-cloud-stream-tools/src/main/resources/checkstyle-header.txt</headerLocation>
<suppressionsLocation>spring-cloud-stream-tools/src/main/resources/checkstyle-suppressions.xml</suppressionsLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>spring</id>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>coverage</id>
<activation>
<property>
<name>env.TRAVIS</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>spring</id>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>coverage</id>
<activation>
<property>
<name>env.TRAVIS</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-binder-test</artifactId>

View File

@@ -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<B extends AbstractTestBinder<? extends AbstractBinder<MessageChannel, CP, PP>, 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<B extends AbstractTestBinder<? extends
*/
protected double timeoutMultiplier = 1.0D;
@Before
public void before() {
this.messageConverter = new CompositeMessageConverterFactory()
.getMessageConverterForAllRegistered();
}
/**
* Attempt to receive a message on the given channel, waiting up to 1s (times the
* {@link #timeoutMultiplier}).
@@ -114,9 +116,9 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
protected Message<?> 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<B extends AbstractTestBinder<? extends
@SuppressWarnings("rawtypes")
public void testClean() throws Exception {
Binder binder = getBinder();
Binding<MessageChannel> foo0ProducerBinding = binder.bindProducer(String.format("foo%s0",
getDestinationNameDelimiter()), this.createBindableChannel("output", new BindingProperties()),
Binding<MessageChannel> foo0ProducerBinding = binder.bindProducer(
String.format("foo%s0", getDestinationNameDelimiter()),
this.createBindableChannel("output", new BindingProperties()),
createProducerProperties());
Binding<MessageChannel> foo0ConsumerBinding = binder.bindConsumer(String.format("foo%s0",
getDestinationNameDelimiter()), "testClean", this.createBindableChannel("input",
new BindingProperties()), createConsumerProperties());
Binding<MessageChannel> foo1ProducerBinding = binder.bindProducer(String.format("foo%s1",
getDestinationNameDelimiter()), this.createBindableChannel("output", new BindingProperties()),
Binding<MessageChannel> foo0ConsumerBinding = binder.bindConsumer(
String.format("foo%s0", getDestinationNameDelimiter()), "testClean",
this.createBindableChannel("input", new BindingProperties()),
createConsumerProperties());
Binding<MessageChannel> foo1ProducerBinding = binder.bindProducer(
String.format("foo%s1", getDestinationNameDelimiter()),
this.createBindableChannel("output", new BindingProperties()),
createProducerProperties());
Binding<MessageChannel> foo1ConsumerBinding = binder.bindConsumer(String.format("foo%s1",
getDestinationNameDelimiter()), "testClean", this.createBindableChannel("input",
new BindingProperties()), createConsumerProperties());
Binding<MessageChannel> foo2ProducerBinding = binder.bindProducer(String.format("foo%s2",
getDestinationNameDelimiter()), this.createBindableChannel("output", new BindingProperties()),
Binding<MessageChannel> foo1ConsumerBinding = binder.bindConsumer(
String.format("foo%s1", getDestinationNameDelimiter()), "testClean",
this.createBindableChannel("input", new BindingProperties()),
createConsumerProperties());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
@Test
public void testSendAndReceive() throws Exception {
Binder binder = getBinder();
BindingProperties outputBindingProperties = createProducerBindingProperties(createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", outputBindingProperties);
BindingProperties outputBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output",
outputBindingProperties);
BindingProperties inputBindingProperties = createConsumerBindingProperties(createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", inputBindingProperties);
BindingProperties inputBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input",
inputBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("foo%s0",
getDestinationNameDelimiter()), moduleOutputChannel, outputBindingProperties.getProducer());
Binding<MessageChannel> 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<MessageChannel> producerBinding = binder.bindProducer(
String.format("foo%s0", getDestinationNameDelimiter()),
moduleOutputChannel, outputBindingProperties.getProducer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
Assert.isTrue(latch.await(5, TimeUnit.SECONDS), "Failed to receive message");
assertThat(inboundMessageRef.get().getPayload()).isEqualTo("foo".getBytes());
assertThat(inboundMessageRef.get().getHeaders().get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)).isNull();
assertThat(inboundMessageRef.get().getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()).isEqualTo("text/plain");
assertThat(inboundMessageRef.get().getHeaders()
.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)).isNull();
assertThat(inboundMessageRef.get().getHeaders().get(MessageHeaders.CONTENT_TYPE)
.toString()).isEqualTo("text/plain");
producerBinding.unbind();
consumerBinding.unbind();
}
private class Foo {
private String name;
@SuppressWarnings("unused")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Test
@SuppressWarnings({"rawtypes","deprecation"})
@SuppressWarnings({ "rawtypes", "deprecation" })
public void testSendAndReceiveKryo() throws Exception {
Binder binder = getBinder();
BindingProperties outputBindingProperties = createProducerBindingProperties(createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", outputBindingProperties);
BindingProperties outputBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output",
outputBindingProperties);
BindingProperties inputBindingProperties = createConsumerBindingProperties(createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", inputBindingProperties);
BindingProperties inputBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input",
inputBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("foo%s0x",
getDestinationNameDelimiter()), moduleOutputChannel, outputBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("foo%s0x",
getDestinationNameDelimiter()), "testSendAndReceiveKryo", moduleInputChannel, inputBindingProperties.getConsumer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("foo%s0x", getDestinationNameDelimiter()),
moduleOutputChannel, outputBindingProperties.getProducer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
KryoMessageConverter kryo = new KryoMessageConverter(null, true);
Foo fooPayload = (Foo) kryo.fromMessage(inboundMessageRef.get(), Foo.class);
assertNotNull(fooPayload);
assertThat(inboundMessageRef.get().getHeaders().get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)).isNull();
assertThat(fooPayload).isNotNull();
assertThat(inboundMessageRef.get().getHeaders()
.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)).isNull();
producerBinding.unbind();
consumerBinding.unbind();
}
@Test
@SuppressWarnings({"rawtypes","deprecation"})
@SuppressWarnings({ "rawtypes", "deprecation" })
public void testSendAndReceiveJavaSerialization() throws Exception {
Binder binder = getBinder();
BindingProperties outputBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties outputBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", outputBindingProperties);
DirectChannel moduleOutputChannel = createBindableChannel("output",
outputBindingProperties);
BindingProperties inputBindingProperties = createConsumerBindingProperties(createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", inputBindingProperties);
BindingProperties inputBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input",
inputBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("foo%s0y",
getDestinationNameDelimiter()), moduleOutputChannel, outputBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("foo%s0y", getDestinationNameDelimiter()),
moduleOutputChannel, outputBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("foo%s0y",
getDestinationNameDelimiter()), "testSendAndReceiveJavaSerialization", moduleInputChannel,
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
Assert.isTrue(latch.await(5, TimeUnit.SECONDS), "Failed to receive message");
JavaSerializationMessageConverter converter = new JavaSerializationMessageConverter();
SerializableFoo serializableFoo = (SerializableFoo) converter.convertFromInternal(inboundMessageRef.get(), SerializableFoo.class, null);
assertNotNull(serializableFoo);
assertThat(inboundMessageRef.get().getHeaders().get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)).isNull();
assertThat(inboundMessageRef.get().getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT);
SerializableFoo serializableFoo = (SerializableFoo) converter.convertFromInternal(
inboundMessageRef.get(), SerializableFoo.class, null);
assertThat(serializableFoo).isNotNull();
assertThat(inboundMessageRef.get().getHeaders()
.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)).isNull();
assertThat(inboundMessageRef.get().getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT);
producerBinding.unbind();
consumerBinding.unbind();
}
@@ -311,25 +330,33 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
public void testSendAndReceiveMultipleTopics() throws Exception {
Binder binder = getBinder();
BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties producerBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel1 = createBindableChannel("output1", producerBindingProperties);
DirectChannel moduleOutputChannel1 = createBindableChannel("output1",
producerBindingProperties);
DirectChannel moduleOutputChannel2 = createBindableChannel("output2", producerBindingProperties);
DirectChannel moduleOutputChannel2 = createBindableChannel("output2",
producerBindingProperties);
QueueChannel moduleInputChannel = new QueueChannel();
Binding<MessageChannel> producerBinding1 = binder.bindProducer(String.format("foo%sxy",
getDestinationNameDelimiter()), moduleOutputChannel1, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding2 = binder.bindProducer(String.format("foo%syz",
Binding<MessageChannel> producerBinding1 = binder.bindProducer(
String.format("foo%sxy", getDestinationNameDelimiter()),
moduleOutputChannel1, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding2 = binder.bindProducer(
String.format("foo%syz",
getDestinationNameDelimiter()), moduleOutputChannel2, producerBindingProperties.getProducer());
getDestinationNameDelimiter()),
moduleOutputChannel2, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding1 = binder.bindConsumer(String.format("foo%sxy",
getDestinationNameDelimiter()), "testSendAndReceiveMultipleTopics", moduleInputChannel,
Binding<MessageChannel> consumerBinding1 = binder.bindConsumer(
String.format("foo%sxy", getDestinationNameDelimiter()),
"testSendAndReceiveMultipleTopics", moduleInputChannel,
createConsumerProperties());
Binding<MessageChannel> consumerBinding2 = binder.bindConsumer(String.format("foo%syz",
getDestinationNameDelimiter()), "testSendAndReceiveMultipleTopics", moduleInputChannel,
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output",
producerBindingProperties);
BindingProperties inputBindingProperties = createConsumerBindingProperties(createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", inputBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("bar%s0",
getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("bar%s0",
getDestinationNameDelimiter()), "testSendAndReceiveNoOriginalContentType", moduleInputChannel,
BindingProperties inputBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input",
inputBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("bar%s0", getDestinationNameDelimiter()),
moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(
String.format("bar%s0", getDestinationNameDelimiter()),
"testSendAndReceiveNoOriginalContentType", moduleInputChannel,
createConsumerProperties());
binderBindUnbindLatency();
@@ -400,8 +431,8 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
Assert.isTrue(latch.await(5, TimeUnit.SECONDS), "Failed to receive message");
assertThat(inboundMessageRef.get()).isNotNull();
assertThat(inboundMessageRef.get().getPayload()).isEqualTo("foo".getBytes());
assertThat(inboundMessageRef.get().getHeaders().get(MessageHeaders.CONTENT_TYPE).toString())
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
assertThat(inboundMessageRef.get().getHeaders().get(MessageHeaders.CONTENT_TYPE)
.toString()).isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
producerBinding.unbind();
consumerBinding.unbind();
}
@@ -412,7 +443,8 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
protected abstract PP createProducerProperties();
protected final BindingProperties createConsumerBindingProperties(CP consumerProperties) {
protected final BindingProperties createConsumerBindingProperties(
CP consumerProperties) {
BindingProperties bindingProperties = new BindingProperties();
bindingProperties.setConsumer(consumerProperties);
return bindingProperties;
@@ -426,14 +458,16 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
protected DirectChannel createBindableChannel(String channelName,
BindingProperties bindingProperties) throws Exception {
// The 'channelName.contains("input")' is strictly for convenience to avoid modifications in multiple tests
return this.createBindableChannel(channelName, bindingProperties, channelName.contains("input"));
// The 'channelName.contains("input")' is strictly for convenience to avoid
// modifications in multiple tests
return this.createBindableChannel(channelName, bindingProperties,
channelName.contains("input"));
}
protected DirectChannel createBindableChannel(String channelName,
BindingProperties bindingProperties, boolean inputChannel) throws Exception {
MessageConverterConfigurer messageConverterConfigurer = createConverterConfigurer(channelName,
bindingProperties);
MessageConverterConfigurer messageConverterConfigurer = createConverterConfigurer(
channelName, bindingProperties);
DirectChannel channel = new DirectChannel();
channel.setBeanName(channelName);
if (inputChannel) {
@@ -447,8 +481,11 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
protected DefaultPollableMessageSource createBindableMessageSource(String bindingName,
BindingProperties bindingProperties) throws Exception {
DefaultPollableMessageSource source = new DefaultPollableMessageSource(new CompositeMessageConverterFactory().getMessageConverterForAllRegistered());
createConverterConfigurer(bindingName, bindingProperties).configurePolledMessageSource(source, bindingName);
DefaultPollableMessageSource source = new DefaultPollableMessageSource(
new CompositeMessageConverterFactory()
.getMessageConverterForAllRegistered());
createConverterConfigurer(bindingName, bindingProperties)
.configurePolledMessageSource(source, bindingName);
return source;
}
@@ -470,8 +507,8 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
@After
public void cleanup() {
if (testBinder != null) {
testBinder.cleanup();
if (this.testBinder != null) {
this.testBinder.cleanup();
}
}
@@ -488,7 +525,7 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
* the 'connection' from its actual usage, which may be needed by some implementations
* to see messages sent after connection creation.
*/
public abstract Spy spyOn(final String name);
public abstract Spy spyOn(String name);
/**
* Set the delimiter that will be used in the message source/target name. Some brokers
@@ -508,19 +545,25 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
Binder binder = getBinder();
BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties producerBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", producerBindingProperties);
DirectChannel moduleOutputChannel = createBindableChannel("output",
producerBindingProperties);
BindingProperties consumerBindingProperties = createConsumerBindingProperties(createConsumerProperties());
BindingProperties consumerBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", consumerBindingProperties);
DirectChannel moduleInputChannel = createBindableChannel("input",
consumerBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("bad%s0a",
getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("bad%s0a", getDestinationNameDelimiter()),
moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("bad%s0a",
getDestinationNameDelimiter()), "test-1", moduleInputChannel, consumerBindingProperties.getConsumer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
QueueChannel replyChannel = (QueueChannel) handler.getOutputChannel();
Message<?> 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<B extends AbstractTestBinder<? extends
Binder binder = getBinder();
BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties producerBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", producerBindingProperties);
DirectChannel moduleOutputChannel = createBindableChannel("output",
producerBindingProperties);
BindingProperties consumerBindingProperties = createConsumerBindingProperties(createConsumerProperties());
BindingProperties consumerBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", consumerBindingProperties);
DirectChannel moduleInputChannel = createBindableChannel("input",
consumerBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("bad%s0b",
getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("bad%s0b", getDestinationNameDelimiter()),
moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("bad%s0b",
getDestinationNameDelimiter()), "test-2", moduleInputChannel, consumerBindingProperties.getConsumer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
QueueChannel replyChannel = (QueueChannel) handler.getOutputChannel();
Message<?> 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<B extends AbstractTestBinder<? extends
public void testStreamListenerJavaSerializationNonSerializable() throws Exception {
Binder binder = getBinder();
BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties producerBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", producerBindingProperties);
DirectChannel moduleOutputChannel = createBindableChannel("output",
producerBindingProperties);
BindingProperties consumerBindingProperties = createConsumerBindingProperties(createConsumerProperties());
BindingProperties consumerBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", consumerBindingProperties);
DirectChannel moduleInputChannel = createBindableChannel("input",
consumerBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("bad%s0c",
getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("bad%s0c", getDestinationNameDelimiter()),
moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("bad%s0c",
getDestinationNameDelimiter()), "test-3", moduleInputChannel, consumerBindingProperties.getConsumer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
AbstractBinderTests.class, "echoStation", Station.class);
Binder binder = getBinder();
BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties producerBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", producerBindingProperties);
DirectChannel moduleOutputChannel = createBindableChannel("output",
producerBindingProperties);
BindingProperties consumerBindingProperties = createConsumerBindingProperties(createConsumerProperties());
BindingProperties consumerBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", consumerBindingProperties);
DirectChannel moduleInputChannel = createBindableChannel("input",
consumerBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("bad%s0d",
getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("bad%s0d", getDestinationNameDelimiter()),
moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("bad%s0d",
getDestinationNameDelimiter()), "test-4", moduleInputChannel, consumerBindingProperties.getConsumer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
Message<Station> reply = (Message<Station>) 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<B extends AbstractTestBinder<? extends
AbstractBinderTests.class, "echoStationString", String.class);
Binder binder = getBinder();
BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties producerBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", producerBindingProperties);
DirectChannel moduleOutputChannel = createBindableChannel("output",
producerBindingProperties);
BindingProperties consumerBindingProperties = createConsumerBindingProperties(createConsumerProperties());
BindingProperties consumerBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", consumerBindingProperties);
DirectChannel moduleInputChannel = createBindableChannel("input",
consumerBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("bad%s0e",
getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("bad%s0e", getDestinationNameDelimiter()),
moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("bad%s0e",
getDestinationNameDelimiter()), "test-5", moduleInputChannel, consumerBindingProperties.getConsumer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
Message<String> reply = (Message<String>) 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<B extends AbstractTestBinder<? extends
AbstractBinderTests.class, "echoStation", Station.class);
Binder binder = getBinder();
BindingProperties producerBindingProperties = createProducerBindingProperties(createProducerProperties());
BindingProperties producerBindingProperties = createProducerBindingProperties(
createProducerProperties());
DirectChannel moduleOutputChannel = createBindableChannel("output", producerBindingProperties);
DirectChannel moduleOutputChannel = createBindableChannel("output",
producerBindingProperties);
BindingProperties consumerBindingProperties = createConsumerBindingProperties(createConsumerProperties());
BindingProperties consumerBindingProperties = createConsumerBindingProperties(
createConsumerProperties());
DirectChannel moduleInputChannel = createBindableChannel("input", consumerBindingProperties);
DirectChannel moduleInputChannel = createBindableChannel("input",
consumerBindingProperties);
Binding<MessageChannel> producerBinding = binder.bindProducer(String.format("bad%s0f",
getDestinationNameDelimiter()), moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("bad%s0f", getDestinationNameDelimiter()),
moduleOutputChannel, producerBindingProperties.getProducer());
Binding<MessageChannel> consumerBinding = binder.bindConsumer(String.format("bad%s0f",
getDestinationNameDelimiter()), "test-6", moduleInputChannel, consumerBindingProperties.getConsumer());
Binding<MessageChannel> 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<B extends AbstractTestBinder<? extends
Message<Station> reply = (Message<Station>) 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<B extends AbstractTestBinder<? extends
StreamListenerMessageHandler.class, InvocableHandlerMethod.class,
boolean.class, String[].class);
StreamListenerMessageHandler handler = (StreamListenerMessageHandler) c
.newInstance(method, false, new String[] { });
.newInstance(method, false, new String[] {});
handler.setOutputChannelName(channelName);
handler.setBeanFactory(context);
handler.afterPropertiesSet();
@@ -769,7 +844,7 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
List<Readings> readings = new ArrayList<>();
public List<Readings> getReadings() {
return readings;
return this.readings;
}
public void setReadings(List<Readings> readings) {
@@ -786,7 +861,7 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
public String timestamp;
public String getStationid() {
return stationid;
return this.stationid;
}
public void setStationid(String stationid) {
@@ -794,7 +869,7 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
}
public String getCustomerid() {
return customerid;
return this.customerid;
}
public void setCustomerid(String customerid) {
@@ -802,12 +877,30 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
}
public String getTimestamp() {
return timestamp;
return this.timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
}
}
private class Foo {
private String name;
@SuppressWarnings("unused")
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@@ -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,26 +20,34 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
/**
* @param <C> binder type
* @param <CP> consumer properties type
* @param <PP> producer properties type
* @author Gary Russell
* @since 2.0
*
*/
public abstract class AbstractPollableConsumerTestBinder<C extends AbstractBinder<MessageChannel, CP, PP>,
CP extends ConsumerProperties, PP extends ProducerProperties> extends AbstractTestBinder<C, CP, PP>
implements PollableConsumerBinder<MessageHandler, CP>{
// @checkstyle:off
public abstract class AbstractPollableConsumerTestBinder<C extends AbstractBinder<MessageChannel, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties>
extends AbstractTestBinder<C, CP, PP>
implements PollableConsumerBinder<MessageHandler, CP> {
// @checkstyle:on
private PollableConsumerBinder<MessageHandler, CP> binder;
@SuppressWarnings("unchecked")
public void setPollableConsumerBinder(PollableConsumerBinder<MessageHandler, CP> binder) {
public void setPollableConsumerBinder(
PollableConsumerBinder<MessageHandler, CP> binder) {
super.setBinder((C) binder);
this.binder = binder;
}
@Override
public Binding<PollableSource<MessageHandler>> bindPollableConsumer(String name, String group,
PollableSource<MessageHandler> inboundBindTarget, CP consumerProperties) {
return this.binder.bindPollableConsumer(name, group, inboundBindTarget, consumerProperties);
public Binding<PollableSource<MessageHandler>> bindPollableConsumer(String name,
String group, PollableSource<MessageHandler> inboundBindTarget,
CP consumerProperties) {
return this.binder.bindPollableConsumer(name, group, inboundBindTarget,
consumerProperties);
}
}

View File

@@ -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 <C> binder type
* @param <CP> consumer properties type
* @param <PP> producer properties type
* @author Ilayaperumal Gopinathan
* @author Gary Russell
* @author Mark Fisher
* @author Oleg Zhurakousky
*/
// @checkstyle:off
public abstract class AbstractTestBinder<C extends AbstractBinder<MessageChannel, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties>
implements Binder<MessageChannel, CP, PP> {
// @checkstyle:on
protected Set<String> queues = new HashSet<String>();
private C binder;
@Override
public Binding<MessageChannel> bindConsumer(String name, String group, MessageChannel moduleInputChannel,
CP properties) {
public Binding<MessageChannel> 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<MessageChannel> bindProducer(String name, MessageChannel moduleOutputChannel, PP properties) {
queues.add(name);
return binder.bindProducer(name, moduleOutputChannel, properties);
public Binding<MessageChannel> 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<C extends AbstractBinder<MessageChannel
/*
* This will ensure that any MessageChannel that was passed to one of the bind*()
* methods was properly configured (i.e., interceptors, converters etc).
* see org.springframework.cloud.stream.binding.MessageConverterConfigurer
* methods was properly configured (i.e., interceptors, converters etc). see
* org.springframework.cloud.stream.binding.MessageConverterConfigurer
*/
private void checkChannelIsConfigured(MessageChannel messageChannel, CP properties) {
if (messageChannel instanceof AbstractSubscribableChannel && !properties.isUseNativeDecoding()){
Assert.isTrue(!CollectionUtils.isEmpty(((AbstractSubscribableChannel)messageChannel).getChannelInterceptors()),
"'messageChannel' appears to be misconfigured. Consider creating channel via AbstractBinderTest.createBindableChannel(..)");
if (messageChannel instanceof AbstractSubscribableChannel
&& !properties.isUseNativeDecoding()) {
Assert.isTrue(
!CollectionUtils
.isEmpty(((AbstractSubscribableChannel) messageChannel)
.getChannelInterceptors()),
"'messageChannel' appears to be misconfigured. "
+ "Consider creating channel via AbstractBinderTest.createBindableChannel(..)");
}
}
}

View File

@@ -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,10 +33,14 @@ import org.springframework.core.env.MapPropertySource;
public class BinderTestEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
Map<String, Object> 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));
}
}

View File

@@ -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);
}

View File

@@ -46,30 +46,39 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Marius Bogoevici
* @author Vinicius Carvalho
*/
// @checkstyle:off
public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<? extends AbstractBinder<MessageChannel, CP, PP>, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties>
extends AbstractBinderTests<B, CP, PP> {
// @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<MessageChannel> producerBinding = binder.bindProducer(String.format("defaultGroup%s0",
getDestinationNameDelimiter()), output, (PP) producerBindingProperties.getProducer());
Binding<MessageChannel> producerBinding = binder.bindProducer(
String.format("defaultGroup%s0", getDestinationNameDelimiter()), output,
(PP) producerBindingProperties.getProducer());
QueueChannel input1 = new QueueChannel();
Binding<MessageChannel> binding1 = binder.bindConsumer(String.format("defaultGroup%s0",
getDestinationNameDelimiter()), null, input1, createConsumerProperties());
Binding<MessageChannel> binding1 = binder.bindConsumer(
String.format("defaultGroup%s0", getDestinationNameDelimiter()), null,
input1, createConsumerProperties());
QueueChannel input2 = new QueueChannel();
Binding<MessageChannel> binding2 = binder.bindConsumer(String.format("defaultGroup%s0",
getDestinationNameDelimiter()), null, input2, createConsumerProperties());
Binding<MessageChannel> 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<byte[]> receivedMessage1 = (Message<byte[]>) receive(input1);
assertThat(receivedMessage1).isNotNull();
@@ -82,12 +91,17 @@ public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<?
binding2.unbind();
String testPayload2 = "foo-" + UUID.randomUUID().toString();
output.send(MessageBuilder.withPayload(testPayload2).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build());
output.send(MessageBuilder.withPayload(testPayload2)
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build());
binding2 = binder.bindConsumer(String.format("defaultGroup%s0", getDestinationNameDelimiter()), null, input2,
createConsumerProperties());
binding2 = binder.bindConsumer(
String.format("defaultGroup%s0", getDestinationNameDelimiter()), null,
input2, createConsumerProperties());
String testPayload3 = "foo-" + UUID.randomUUID().toString();
output.send(MessageBuilder.withPayload(testPayload3).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN).build());
output.send(MessageBuilder.withPayload(testPayload3)
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build());
receivedMessage1 = (Message<byte[]>) receive(input1);
assertThat(receivedMessage1).isNotNull();
@@ -109,23 +123,29 @@ public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<?
public void testOneRequiredGroup() throws Exception {
B binder = getBinder();
PP producerProperties = createProducerProperties();
DirectChannel output = createBindableChannel("output", createProducerBindingProperties(producerProperties));
DirectChannel output = createBindableChannel("output",
createProducerBindingProperties(producerProperties));
String testDestination = "testDestination" + UUID.randomUUID().toString().replace("-", "");
String testDestination = "testDestination"
+ UUID.randomUUID().toString().replace("-", "");
producerProperties.setRequiredGroups("test1");
Binding<MessageChannel> producerBinding = binder.bindProducer(testDestination, output, producerProperties);
Binding<MessageChannel> 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<MessageChannel> consumerBinding = binder.bindConsumer(testDestination, "test1", inbound1,
createConsumerProperties());
Binding<MessageChannel> 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<B extends AbstractTestBinder<?
B binder = getBinder();
PP producerProperties = createProducerProperties();
DirectChannel output = createBindableChannel("output", createProducerBindingProperties(producerProperties));
DirectChannel output = createBindableChannel("output",
createProducerBindingProperties(producerProperties));
String testDestination = "testDestination" + UUID.randomUUID().toString().replace("-", "");
String testDestination = "testDestination"
+ UUID.randomUUID().toString().replace("-", "");
producerProperties.setRequiredGroups("test1", "test2");
Binding<MessageChannel> producerBinding = binder.bindProducer(testDestination, output, producerProperties);
Binding<MessageChannel> 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<MessageChannel> consumerBinding1 = binder.bindConsumer(testDestination, "test1", inbound1,
createConsumerProperties());
Binding<MessageChannel> consumerBinding1 = binder.bindConsumer(testDestination,
"test1", inbound1, createConsumerProperties());
QueueChannel inbound2 = new QueueChannel();
Binding<MessageChannel> consumerBinding2 = binder.bindConsumer(testDestination, "test2", inbound2,
createConsumerProperties());
Binding<MessageChannel> 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<B extends AbstractTestBinder<?
consumerProperties.setPartitioned(true);
QueueChannel input0 = new QueueChannel();
input0.setBeanName("test.input0S");
Binding<MessageChannel> input0Binding = binder.bindConsumer(String.format("part%s0",
getDestinationNameDelimiter()), "testPartitionedModuleSpEL", input0, consumerProperties);
Binding<MessageChannel> input0Binding = binder.bindConsumer(
String.format("part%s0", getDestinationNameDelimiter()),
"testPartitionedModuleSpEL", input0, consumerProperties);
consumerProperties.setInstanceIndex(1);
QueueChannel input1 = new QueueChannel();
input1.setBeanName("test.input1S");
Binding<MessageChannel> input1Binding = binder.bindConsumer(String.format("part%s0",
getDestinationNameDelimiter()), "testPartitionedModuleSpEL", input1, consumerProperties);
Binding<MessageChannel> input1Binding = binder.bindConsumer(
String.format("part%s0", getDestinationNameDelimiter()),
"testPartitionedModuleSpEL", input1, consumerProperties);
consumerProperties.setInstanceIndex(2);
QueueChannel input2 = new QueueChannel();
input2.setBeanName("test.input2S");
Binding<MessageChannel> input2Binding = binder.bindConsumer(String.format("part%s0",
getDestinationNameDelimiter()), "testPartitionedModuleSpEL", input2, consumerProperties);
Binding<MessageChannel> 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<MessageChannel> outputBinding = binder.bindProducer(String.format("part%s0",
getDestinationNameDelimiter()), output, producerProperties);
Binding<MessageChannel> 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<B extends AbstractTestBinder<?
Message<String> 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<B extends AbstractTestBinder<?
Condition<Message<?>> correlationHeadersForPayload2 = new Condition<Message<?>>() {
@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<B extends AbstractTestBinder<?
assertThat(receive2).has(correlationHeadersForPayload2);
}
else {
List<Message<?>> receivedMessages = Arrays.asList(receive0, receive1, receive2);
assertThat(receivedMessages).extracting("payload").containsExactlyInAnyOrder("0".getBytes(), "1".getBytes(), "2".getBytes());
List<Message<?>> receivedMessages = Arrays.asList(receive0, receive1,
receive2);
assertThat(receivedMessages).extracting("payload").containsExactlyInAnyOrder(
"0".getBytes(), "1".getBytes(), "2".getBytes());
Condition<Message<?>> payloadIs2 = new Condition<Message<?>>() {
@Override
@@ -246,7 +288,8 @@ public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<?
return value.getPayload().equals("2".getBytes());
}
};
assertThat(receivedMessages).filteredOn(payloadIs2).areExactly(1, correlationHeadersForPayload2);
assertThat(receivedMessages).filteredOn(payloadIs2).areExactly(1,
correlationHeadersForPayload2);
}
input0Binding.unbind();
@@ -257,8 +300,9 @@ public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<?
protected void checkRkExpressionForPartitionedModuleSpEL(Object endpoint) {
assertThat(getEndpointRouting(endpoint))
.contains(getExpectedRoutingBaseDestination(String.format("part%s0", getDestinationNameDelimiter()),
"test") + "-' + headers['partition']");
.contains(getExpectedRoutingBaseDestination(
String.format("part%s0", getDestinationNameDelimiter()), "test")
+ "-' + headers['partition']");
}
@Test
@@ -273,36 +317,49 @@ public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<?
consumerProperties.setPartitioned(true);
QueueChannel input0 = new QueueChannel();
input0.setBeanName("test.input0J");
Binding<MessageChannel> input0Binding = binder.bindConsumer(String.format("partJ%s0",
getDestinationNameDelimiter()), "testPartitionedModuleJava", input0, consumerProperties);
Binding<MessageChannel> input0Binding = binder.bindConsumer(
String.format("partJ%s0", getDestinationNameDelimiter()),
"testPartitionedModuleJava", input0, consumerProperties);
consumerProperties.setInstanceIndex(1);
QueueChannel input1 = new QueueChannel();
input1.setBeanName("test.input1J");
Binding<MessageChannel> input1Binding = binder.bindConsumer(String.format("partJ%s0",
getDestinationNameDelimiter()), "testPartitionedModuleJava", input1, consumerProperties);
Binding<MessageChannel> input1Binding = binder.bindConsumer(
String.format("partJ%s0", getDestinationNameDelimiter()),
"testPartitionedModuleJava", input1, consumerProperties);
consumerProperties.setInstanceIndex(2);
QueueChannel input2 = new QueueChannel();
input2.setBeanName("test.input2J");
Binding<MessageChannel> input2Binding = binder.bindConsumer(String.format("partJ%s0",
getDestinationNameDelimiter()), "testPartitionedModuleJava", input2, consumerProperties);
Binding<MessageChannel> 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<MessageChannel> outputBinding = binder.bindProducer("partJ.0", output, producerProperties);
Binding<MessageChannel> 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<B extends AbstractTestBinder<?
assertThat(receive2.getPayload()).isEqualTo("2".getBytes());
}
else {
List<Message<?>> receivedMessages = Arrays.asList(receive0, receive1, receive2);
assertThat(receivedMessages).extracting("payload").containsExactlyInAnyOrder("0".getBytes(), "1".getBytes(), "2".getBytes());
List<Message<?>> 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<B extends AbstractTestBinder<?
DirectFieldAccessor accessor = new DirectFieldAccessor(binding);
return (Lifecycle) accessor.getPropertyValue("lifecycle");
}
}

View File

@@ -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.
@@ -21,7 +21,8 @@ import org.springframework.messaging.Message;
/**
* @author Gary Russell
*/
public class PartitionTestSupport implements PartitionKeyExtractorStrategy, PartitionSelectorStrategy {
public class PartitionTestSupport
implements PartitionKeyExtractorStrategy, PartitionSelectorStrategy {
@Override
public int selectPartition(Object key, int divisor) {

View File

@@ -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,15 +16,13 @@
package org.springframework.cloud.stream.binder;
import java.io.Serializable;
/**
*
* @author Oleg Zhurakousky
*
*/
public class SerializableFoo implements Serializable{
public class SerializableFoo implements Serializable {
/**
*

View File

@@ -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,4 +25,5 @@ package org.springframework.cloud.stream.binder;
public interface Spy {
Object receive(boolean expectNull) throws Exception;
}

View File

@@ -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.
@@ -20,7 +20,10 @@ import org.springframework.beans.DirectFieldAccessor;
import org.springframework.util.Assert;
/**
* Copy of class in org.springframework.amqp.utils.test to avoid dependency on spring-amqp
* Copy of class in org.springframework.amqp.utils.test to avoid dependency on
* spring-amqp.
*
* @author David Turanski
*/
public abstract class TestUtils {
@@ -61,4 +64,5 @@ public abstract class TestUtils {
}
return (T) value;
}
}

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-integration-tests</artifactId>

View File

@@ -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<String> received = (Message<String>) ((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<String> received = (Message<String>) ((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 {
}
}

View File

@@ -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<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(10, TimeUnit.SECONDS);
Message<String> received = (Message<String>) ((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<String> 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();
}
}
}

View File

@@ -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<String> received = (Message<String>) ((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<String> received = (Message<String>) ((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;
}
}
}

View File

@@ -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<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<String> received = (Message<String>) ((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<String> 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();
}
}
}

View File

@@ -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<String> received = (Message<String>) ((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<String> received = (Message<String>) ((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();
}
}
}

View File

@@ -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<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<String> received = (Message<String>) ((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;
}
}
}

View File

@@ -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<byte[]> received = (Message<byte[]>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<byte[]> received = (Message<byte[]>) ((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)

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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 {
}
}

View File

@@ -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<String, Object>) testPojoWithAnnotatedArguments.receivedArguments.get(1))
.containsEntry(MessageHeaders.CONTENT_TYPE, MimeType.valueOf("application/json"));
assertThat((Map<String, String>) 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<String, Object>) testPojoWithAnnotatedArguments.receivedArguments
.get(1)).containsEntry(MessageHeaders.CONTENT_TYPE,
MimeType.valueOf("application/json"));
assertThat((Map<String, String>) 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<Object> receivedArguments = new ArrayList<>();
@StreamListener(Processor.INPUT)
public void receive(@Valid StreamListenerTestUtils.PojoWithValidation pojoWithValidation) {
public void receive(
@Valid StreamListenerTestUtils.PojoWithValidation pojoWithValidation) {
this.receivedArguments.add(pojoWithValidation);
}
}
}

View File

@@ -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<String, Object> 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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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<T extends Base> {
void testMethod(T msg);
}
public interface Base {
@@ -98,16 +105,19 @@ public class StreamListenerDuplicateMappingTests {
public String receiveDuplicateMapping(Message<String> fooMessage) {
return null;
}
}
@EnableBinding(Sink.class)
@EnableAutoConfiguration
public static class TestDuplicateMappingFromAbstractMethod implements GenericSink<TestBase> {
public static class TestDuplicateMappingFromAbstractMethod
implements GenericSink<TestBase> {
@Override
@StreamListener(Sink.INPUT)
public void testMethod(TestBase msg) {
}
}
public class TestBase implements Base {

View File

@@ -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<String> message = (Message<String>) collector.forChannel(
processor.output()).poll(1, TimeUnit.SECONDS);
Assertions.assertThat(handlerBean.receivedPojos.get(0))
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
Message<String> message = (Message<String>) 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 {

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<byte[]> 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<byte[]> 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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> result = (Message<String>) messageCollector.forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> convertMessageBody(Message<String> 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());
}
});
}
}
}

View File

@@ -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<String> message = (Message<String>) 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<Message<String>> receivedMessages = new ArrayList<>();
}
}

View File

@@ -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 {
}
}
}

View File

@@ -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<String> message = (Message<String>) collector.forChannel(processor.output()).poll(1,
TimeUnit.SECONDS);
Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0))
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
Message<String> message = (Message<String>) 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<String> message = (Message<String>) 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<StreamListenerTestUtils.FooPojo> receivedPojos = new ArrayList<>();
}
}

View File

@@ -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<StreamListenerSetupMethodOrchestrator> field1 =
(LinkedHashSet<StreamListenerSetupMethodOrchestrator>)ReflectionUtils.getField(field, streamListenerAnnotationBeanPostProcessor);
Set<StreamListenerSetupMethodOrchestrator> field1;
field1 = (LinkedHashSet<StreamListenerSetupMethodOrchestrator>) ReflectionUtils
.getField(field, this.streamListenerAnnotationBeanPostProcessor);
List<StreamListenerSetupMethodOrchestrator> 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
}
}
}

View File

@@ -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<String> message = (Message<String>) 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<StreamListenerTestUtils.FooPojo> receivedPojos = new ArrayList<>();
}
}

View File

@@ -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<StreamListenerTestUtils.FooPojo> receivedPojos = new ArrayList<>();
}
}

View File

@@ -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;
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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());
}
});
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<String> received = (Message<String>) ((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<String> received = (Message<String>)((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<String> received = (Message<String>) ((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<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<String> received = (Message<String>) ((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 + "'}";
}
}

View File

@@ -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<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
this.testProcessor.input()
.send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").build());
Message<String> received = (Message<String>) ((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 + "'}";
}
}

View File

@@ -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<String> received = (Message<String>) (testSupportBinder.messageCollector().forChannel(processorOutput)
.poll(5, TimeUnit.SECONDS));
Assert.assertThat(received, notNullValue());
Assert.assertTrue(received.getPayload().endsWith("processed"));
Message<String> received = (Message<String>) (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 {
}
}

View File

@@ -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<String> 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();
}
}

View File

@@ -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<String>() {
@Override
public Message<String> 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();
}
};
}
}

View File

@@ -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<String> message = (Message<String>) 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<String> message = (Message<String>) 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<byte[]> message = (Message<byte[]>) 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<byte[]> message = (Message<byte[]>) 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<byte[]> message = (Message<byte[]>) 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<User> message = (Message<User>) collector
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
.includes(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT));
Message<User> message = (Message<User>) 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<User> message = (Message<User>) collector
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
Message<User> message = (Message<User>) 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<String> message = (Message<String>) 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<byte[]> message = (Message<byte[]>) 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<String,Object> headers = (Map<String, Object>) 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<String, Object> headers = (Map<String, Object>) 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<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
Map<String, Object> headers = (Map<String, Object>) 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<String, Object>) 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<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
User received = (User)sourceApp.arguments.pop();
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
Map<String, Object> headers = (Map<String, Object>) 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<String,Object> headers = (Map<String, Object>) 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<String, Object> headers = (Map<String, Object>) 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<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
User received = (User)sourceApp.arguments.pop();
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
Map<String, Object> headers = (Map<String, Object>) 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<? super Object> arguments = new LinkedList<>();
@StreamListener("POJO_INPUT")
public void receive(User user, @Headers Map<String, Object> 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<String, Object> 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<? super Object> arguments = new LinkedList<>();
@StreamListener("POJO_INPUT")
public void receive(User user, @Headers Map<String, Object> 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<String, Object> headers) {
this.arguments.push(data);
this.arguments.push(headers);
}
}
}

View File

@@ -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();
}
}

View File

@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-parent</artifactId>

View File

@@ -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<Object> consumer;
private Log log = LogFactory.getLog(DefaultFluxSender.class);
private volatile Disposable disposable;
private final Consumer<Object> consumer;
DefaultFluxSender(Consumer<Object> consumer) {
Assert.notNull(consumer, "Consumer must not be null");
this.consumer = consumer;
@@ -54,12 +53,8 @@ class DefaultFluxSender implements FluxSender {
MonoProcessor<Void> 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;
}

View File

@@ -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 {

View File

@@ -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()));
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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;
* <pre class="code">
* &#064;StreamEmitter
* &#064;Output(Source.OUTPUT)
* public Flux<String> emit() {
* public Flux&lt;String&gt; emit() {
* return Flux.intervalMillis(1000)
* .map(l -> "Hello World!!");
* }
* </pre>
*
* 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.
*
* <pre class="code">
* &#064;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 {
}

View File

@@ -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<Closeable> closeableFluxResources = new ArrayList<>();
private final Lock lock = new ReentrantLock();
@SuppressWarnings("rawtypes")
private Collection<StreamListenerParameterAdapter> parameterAdapters;
@@ -72,148 +77,39 @@ public class StreamEmitterAnnotationBeanPostProcessor
@SuppressWarnings("rawtypes")
private Collection<StreamListenerResultAdapter> resultAdapters;
private final List<Closeable> closeableFluxResources = new ArrayList<>();
private ConfigurableApplicationContext applicationContext;
private MultiValueMap<Object, Method> 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<?, Object> 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<?, Object> 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();
}

View File

@@ -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";
}

View File

@@ -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<String> 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<?>> message) {
// do nothing - we just reference this method from the test
}
}

View File

@@ -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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<Message<String>> emit() {
AtomicInteger atomicInteger = new AtomicInteger();
return IntegrationFlows.from(() ->
new GenericMessage<>("Hello World!!" + atomicInteger.getAndIncrement()),
e -> e.poller(p -> p.fixedDelay(1)))
.<String, String>transform(String::toUpperCase)
.toReactivePublisher();
return IntegrationFlows
.from(() -> new GenericMessage<>(
"Hello World!!" + atomicInteger.getAndIncrement()),
e -> e.poller(p -> p.fixedDelay(1)))
.<String, String>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<String> 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<String> 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<String> 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<String> 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();
}
}

View File

@@ -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<String> 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<String> 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<String> 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<String> 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";
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000,
TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> {
}
public static class TestGenericStringFluxInputOutputArgsWithMessageImpl2
extends TestGenericFluxInputOutputArgsWithMessage2<String> {
}
@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()));
}
}
}

View File

@@ -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<String> 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();
});
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> input, @Output(Processor.OUTPUT) FluxSender output) {
public void receive(@Input(Processor.INPUT) Flux<String> input,
@Output(Processor.OUTPUT) FluxSender output) {
output.send(input.map(m -> m.toUpperCase()));
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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()));
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<Message<String>> 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()));
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<Message<String>> 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()));
}
}
}

View File

@@ -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<String> input, @Output(Processor.OUTPUT) FluxSender output) {
public void receive(Flux<String> 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<String> receive(@Input(Processor.INPUT) Flux<String> input) {
return input.map(m -> m.toUpperCase());
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> receive(@Input(Processor.INPUT) Flux<String> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(
@Input(Processor.INPUT) Flux<String> input) {
return input.map(m -> m.toUpperCase());
}
}
@EnableBinding(Processor.class)
@@ -103,6 +108,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
public Flux<String> receive(Flux<String> input) {
return input.map(m -> m.toUpperCase());
}
}
@EnableBinding(Processor.class)
@@ -114,6 +120,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
public Flux<String> receive(Flux<String> input) {
return input.map(m -> m.toUpperCase());
}
}
@EnableBinding(Processor.class)
@@ -125,5 +132,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
public Flux<String> receive(@Input(Processor.INPUT) Flux<String> input) {
return input.map(m -> m.toUpperCase());
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> receive(@Input(Processor.INPUT) Flux<String> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(
@Input(Processor.INPUT) Flux<String> 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<String> receive(Flux<String> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(Flux<String> 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<String> receive(Flux<String> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(Flux<String> 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<String> receive(@Input(Processor.INPUT) Flux<String> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(
@Input(Processor.INPUT) Flux<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
} else {
}
else {
throw new RuntimeException();
}
});
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<String> receive(@Input(Processor.INPUT) Flux<Message<String>> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(
@Input(Processor.INPUT) Flux<Message<String>> 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<String> receive(Flux<Message<String>> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(
Flux<Message<String>> 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<String> receive(Flux<Message<String>> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(
Flux<Message<String>> 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<String> receive(@Input(Processor.INPUT) Flux<Message<String>> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(
@Input(Processor.INPUT) Flux<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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<BarPojo> receive(@Input(Processor.INPUT) Flux<FooPojo> input) {
public @Output(Processor.OUTPUT) Flux<BarPojo> receive(
@Input(Processor.INPUT) Flux<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@EnableBinding(Processor.class)
@@ -99,6 +103,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public @Output(Processor.OUTPUT) Flux<BarPojo> receive(Flux<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@EnableBinding(Processor.class)
@@ -109,6 +114,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public @SendTo(Processor.OUTPUT) Flux<BarPojo> receive(Flux<FooPojo> 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<BarPojo> receive(@Input(Processor.INPUT) Flux<FooPojo> input) {
public @SendTo(Processor.OUTPUT) Flux<BarPojo> receive(
@Input(Processor.INPUT) Flux<FooPojo> 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;
}
}
}

View File

@@ -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<String> result = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> result = (Message<String>) 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()));
}
}
}

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-schema-server</artifactId>

View File

@@ -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 {
}

View File

@@ -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

View File

@@ -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()));
}
}
};

View File

@@ -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;
}
}

View File

@@ -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<Schema> registeredEntities = this.repository.findBySubjectAndFormatOrderByVersion(
schema.getSubject(), schema.getFormat());
List<Schema> 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<Schema> 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<List<Schema>> findBySubjectAndVersion(@PathVariable("subject") String subject,
public ResponseEntity<List<Schema>> findBySubjectAndVersion(
@PathVariable("subject") String subject,
@PathVariable("format") String format) {
List<Schema> schemas = repository.findBySubjectAndFormatOrderByVersion(subject, format);
List<Schema> 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<List<Schema>>(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 {

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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<Schema, Integer> {
@Transactional
List<Schema> findBySubjectAndFormatOrderByVersion(String subject,
String format);
List<Schema> findBySubjectAndFormatOrderByVersion(String subject, String format);
@Transactional
Schema findOneBySubjectAndFormatAndVersion(String subject, String format,
Integer version);
}

View File

@@ -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";
}
}

View File

@@ -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);
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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}

View File

@@ -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);
}
}

View File

@@ -2,4 +2,5 @@ spring:
application:
name: SchemaRegistryServer
server:
port: 8990
port: 8990

View File

@@ -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<Schema> response = client.postForEntity("http://localhost:8990/",
schema, Schema.class);
Assert.assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
ResponseEntity<Schema> 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<Schema> response = client.postForEntity("http://localhost:8990/",
schema, Schema.class);
Assert.assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
ResponseEntity<Schema> 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<Schema> 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<Schema> response = this.client
.postForEntity("http://localhost:8990/", schema, Schema.class);
assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
assertThat(response.getBody().getVersion()).isEqualTo(new Integer(1));
List<String> location = response.getHeaders().get(HttpHeaders.LOCATION);
Assert.assertNotNull(location);
ResponseEntity<Schema> persistedSchema = client.getForEntity(location.get(0),
assertThat(location).isNotNull();
ResponseEntity<Schema> 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<Schema> response = client.postForEntity("http://localhost:8990/",
schema, Schema.class);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
Assert.assertEquals(new Integer(1), response.getBody().getVersion());
ResponseEntity<Schema> response = this.client
.postForEntity("http://localhost:8990/", schema, Schema.class);
assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
assertThat(response.getBody().getVersion()).isEqualTo(new Integer(1));
List<String> location = response.getHeaders().get(HttpHeaders.LOCATION);
Assert.assertNotNull(location);
assertThat(location).isNotNull();
ResponseEntity<Schema> response2 = client.postForEntity("http://localhost:8990/",
schema2, Schema.class);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
Assert.assertEquals(new Integer(2), response2.getBody().getVersion());
ResponseEntity<Schema> response2 = this.client
.postForEntity("http://localhost:8990/", schema2, Schema.class);
assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
assertThat(response2.getBody().getVersion()).isEqualTo(new Integer(2));
List<String> 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<Schema> 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<Schema> response = this.client
.postForEntity("http://localhost:8990/", schema, Schema.class);
assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
assertThat(response.getBody().getVersion()).isEqualTo(new Integer(1));
List<String> location = response.getHeaders().get(HttpHeaders.LOCATION);
Assert.assertNotNull(location);
ResponseEntity<Schema> response2 = client.postForEntity("http://localhost:8990/",
schema, Schema.class);
Assert.assertEquals(response.getBody().getId(), response2.getBody().getId());
assertThat(location).isNotNull();
ResponseEntity<Schema> 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<Schema> response = client
ResponseEntity<Schema> 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<Schema> 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<Schema> response2 = client
schema.setDefinition(this.USER_SCHEMA_V1);
ResponseEntity<Schema> 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<Schema> 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<Schema> response1 = client.postForEntity("http://localhost:8990/",
schema, Schema.class);
Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
ResponseEntity<Schema> response2 = client
schema.setDefinition(this.USER_SCHEMA_V1);
ResponseEntity<Schema> response1 = this.client
.postForEntity("http://localhost:8990/", schema, Schema.class);
assertThat(response1.getStatusCode().is2xxSuccessful()).isTrue();
ResponseEntity<Schema> 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<Schema> response3 = client
assertThat(response2.getStatusCode()).isEqualTo(HttpStatus.OK);
this.schemaServerProperties.setAllowSchemaDeletion(true);
this.client.delete("http://localhost:8990/schemas/1");
ResponseEntity<Schema> 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<Schema> 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<Schema> 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<Schema> 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<Schema> response4 = client
schema2.setDefinition(this.USER_SCHEMA_V2);
ResponseEntity<Schema> 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<Schema> response4 = this.client
.getForEntity("http://localhost:8990/test/avro/v1", Schema.class);
Assert.assertEquals(HttpStatus.NOT_FOUND, response4.getStatusCode());
ResponseEntity<Schema> response5 = client
assertThat(response4.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
ResponseEntity<Schema> 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<Schema> response1 = client.postForEntity("http://localhost:8990/",
schema, Schema.class);
Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
ResponseEntity<Object> deleteBySubjectFormatVersion = client.exchange("http://localhost:8990/test/avro/v1",
HttpMethod.DELETE,
null, Object.class);
assertThat(deleteBySubjectFormatVersion.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
ResponseEntity<Object> deleteBySubject = client.exchange("http://localhost:8990/test", HttpMethod.DELETE,
null, Object.class);
assertThat(deleteBySubject.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
ResponseEntity<Object> deleteById = client.exchange("http://localhost:8990/schemas/1", HttpMethod.DELETE,
null, Object.class);
schema.setDefinition(this.USER_SCHEMA_V1);
ResponseEntity<Schema> response1 = this.client
.postForEntity("http://localhost:8990/", schema, Schema.class);
assertThat(response1.getStatusCode().is2xxSuccessful()).isTrue();
ResponseEntity<Object> deleteBySubjectFormatVersion = this.client.exchange(
"http://localhost:8990/test/avro/v1", HttpMethod.DELETE, null,
Object.class);
assertThat(deleteBySubjectFormatVersion.getStatusCode())
.isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
ResponseEntity<Object> deleteBySubject = this.client.exchange(
"http://localhost:8990/test", HttpMethod.DELETE, null, Object.class);
assertThat(deleteBySubject.getStatusCode())
.isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
ResponseEntity<Object> 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<Schema> response1 = client.postForEntity("http://localhost:8990/",
v1, Schema.class);
Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
v1.setDefinition(this.USER_SCHEMA_V1);
ResponseEntity<Schema> 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<Schema> response2 = client.postForEntity("http://localhost:8990/",
v2, Schema.class);
Assert.assertTrue(response2.getStatusCode().is2xxSuccessful());
ResponseEntity<Schema> response2 = this.client
.postForEntity("http://localhost:8990/", v2, Schema.class);
assertThat(response2.getStatusCode().is2xxSuccessful()).isTrue();
ResponseEntity<List<Schema>> schemaResponse = client.exchange("http://localhost:8990/test/avro", HttpMethod.GET,
null, new ParameterizedTypeReference<List<Schema>>() {
ResponseEntity<List<Schema>> schemaResponse = this.client.exchange(
"http://localhost:8990/test/avro", HttpMethod.GET, null,
new ParameterizedTypeReference<List<Schema>>() {
});
Assert.assertTrue(schemaResponse.getStatusCode().is2xxSuccessful());
Assert.assertEquals(2, schemaResponse.getBody().size());
assertThat(schemaResponse.getStatusCode().is2xxSuccessful()).isTrue();
assertThat(schemaResponse.getBody().size()).isEqualTo(2);
}
}

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