Migrate the latest source code of spring-integration-hazelcast

* Mention in the README.md why it was deprecated in Spring Integration
This commit is contained in:
Artem Bilan
2025-02-27 11:24:07 -05:00
parent 101ae1e511
commit 86b4df68c6
76 changed files with 1433 additions and 2488 deletions

View File

@@ -1,12 +0,0 @@
language: java
jdk: oraclejdk8
sudo: false
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
install: true
script:
- ./gradlew check --refresh-dependencies --no-daemon

View File

@@ -1,7 +1,9 @@
SPRING INTEGRATION HAZELCAST SUPPORT
====================================
> **_IMPORTANT:_**: Starting with Spring Integration `6.0` this project has been migrated as a module into a [core project](https://github.com/spring-projects/spring-integration/tree/main/spring-integration-hazelcast).
> **_IMPORTANT:_**: Starting with Spring Integration `6.5` the respective `spring-integration-hazelcast` module has been deprecated due to migrating of many Hazelcast feature to the [Enterprise Edition](https://docs.hazelcast.com/hazelcast/5.5/migrate/community-to-enterprise).
This contradicst to the Open Source practice, therefore we just stopping support this module.
The source code of the module is present in this directory for historical reasons and future considerations.
## HAZELCAST EVENT-DRIVEN INBOUND CHANNEL ADAPTER

View File

@@ -1,244 +0,0 @@
plugins {
id 'java'
id 'eclipse'
id 'idea'
id 'jacoco'
id 'org.sonarqube' version '2.8'
id 'checkstyle'
id "io.spring.dependency-management" version '1.0.10.RELEASE'
}
description = 'Spring Integration Hazelcast Support'
apply from: "${rootProject.projectDir}/publish-maven.gradle"
group = 'org.springframework.integration'
repositories {
mavenCentral()
if (version.endsWith('SNAPSHOT')) {
maven { url 'https://repo.spring.io/libs-snapshot' }
}
maven { url 'https://repo.spring.io/libs-milestone' }
}
compileJava {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
ext {
hazelcastVersion = '4.0.3'
slf4jVersion = '1.7.30'
springIntegrationVersion = '5.4.0'
idPrefix = 'hazelcast'
linkHomepage = 'https://github.com/spring-projects/spring-integration-extensions'
linkCi = 'https://build.spring.io/browse/INTEXT'
linkIssue = 'https://github.com/spring-projects/spring-integration-extensions/issues'
linkScmUrl = 'https://github.com/spring-projects/spring-integration-extensions'
linkScmConnection = 'https://github.com/spring-projects/spring-integration-extensions.git'
linkScmDevConnection = 'git@github.com:spring-projects/spring-integration-extensions.git'
}
eclipse.project.natures += 'org.springframework.ide.eclipse.core.springnature'
sourceSets {
test {
resources {
srcDirs = ['src/test/resources', 'src/test/java']
}
}
}
jacoco {
toolVersion = '0.8.6'
}
checkstyle {
configDirectory.set(rootProject.file("src/checkstyle"))
toolVersion = '8.36.2'
}
// enable all compiler warnings; individual projects may customize further
[compileJava, compileTestJava]*.options*.compilerArgs = ['-Xlint:all,-options,-processing']
dependencies {
compile "org.springframework.integration:spring-integration-core:$springIntegrationVersion"
compile "com.hazelcast:hazelcast:$hazelcastVersion"
testCompile "org.springframework.integration:spring-integration-test:$springIntegrationVersion"
testRuntime "org.slf4j:slf4j-log4j12:$slf4jVersion"
}
test {
// suppress all console output during testing unless running `gradle -i`
logging.captureStandardOutput(LogLevel.INFO)
jvmArgs '-Dhazelcast.logging.type=slf4j'
maxHeapSize = '1024m'
}
jacocoTestReport {
dependsOn test
reports {
xml.enabled false
csv.enabled false
html.destination file("$buildDir/reports/jacoco/html")
}
}
task sourcesJar(type: Jar) {
archiveClassifier = 'sources'
from sourceSets.main.allJava
}
task javadocJar(type: Jar) {
archiveClassifier = 'javadoc'
from javadoc
}
artifacts {
archives sourcesJar
archives javadocJar
}
sonarqube {
properties {
property 'sonar.jacoco.reportPath', "${buildDir.name}/jacoco.exec"
property 'sonar.links.homepage', linkHomepage
property 'sonar.links.ci', linkCi
property 'sonar.links.issue', linkIssue
property 'sonar.links.scm', linkScmUrl
property 'sonar.links.scm_dev', linkScmDevConnection
property 'sonar.java.coveragePlugin', 'jacoco'
}
}
task api(type: Javadoc) {
group = 'Documentation'
description = 'Generates the Javadoc API documentation.'
title = "${rootProject.description} ${version} API"
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
options.author = true
options.header = rootProject.description
options.overview = 'src/api/overview.html'
options.stylesheetFile = file('src/api/stylesheet.css')
source = sourceSets.main.allJava
classpath = project.sourceSets.main.compileClasspath
destinationDir = new File(buildDir, 'api')
}
task schemaZip(type: Zip) {
group = 'Distribution'
archiveClassifier = 'schema'
description = "Builds -${archiveClassifier} archive containing all " +
"XSDs for deployment at static.springframework.org/schema."
duplicatesStrategy = 'exclude'
def Properties schemas = new Properties();
def shortName = idPrefix.replaceFirst("${idPrefix}-", '')
project.sourceSets.main.resources.find {
it.path.endsWith("META-INF${File.separator}spring.schemas")
}?.withInputStream { schemas.load(it) }
for (def key : schemas.keySet()) {
File xsdFile = project.sourceSets.main.resources.find {
it.path.replaceAll('\\\\', '/').endsWith(schemas.get(key))
}
assert xsdFile != null
into("integration/${shortName}") {
from xsdFile.path
}
}
}
task docsZip(type: Zip) {
group = 'Distribution'
archiveClassifier = 'docs'
description = "Builds -${archiveClassifier} archive containing api " +
"for deployment at static.spring.io/spring-integration/docs."
from('src/dist') {
include 'changelog.txt'
}
from(api) {
into 'api'
}
}
task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
group = 'Distribution'
archiveClassifier = 'dist'
description = "Builds -${archiveClassifier} archive, containing all jars and docs, " +
"suitable for community download page."
ext.baseDir = "${project.name}-${project.version}";
from('src/dist') {
include 'readme.txt'
include 'license.txt'
include 'notice.txt'
into "${baseDir}"
}
from(zipTree(docsZip.archiveFile)) {
into "${baseDir}/docs"
}
from(zipTree(schemaZip.archiveFile)) {
into "${baseDir}/schema"
}
into("${baseDir}/libs") {
from project.jar
from project.sourcesJar
from project.javadocJar
}
}
// Create an optional "with dependencies" distribution.
// Not published by default; only for use when building from source.
task depsZip(type: Zip, dependsOn: distZip) { zipTask ->
group = 'Distribution'
archiveClassifier = 'dist-with-deps'
description = "Builds -${archiveClassifier} archive, containing everything " +
"in the -${distZip.archiveClassifier} archive plus all dependencies."
from zipTree(distZip.archiveFile)
gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask(":${zipTask.name}")) {
def projectName = rootProject.name
def artifacts = new HashSet()
rootProject.configurations.runtime.resolvedConfiguration.resolvedArtifacts.each { artifact ->
def dependency = artifact.moduleVersion.id
if (!projectName.equals(dependency.name)) {
artifacts << artifact.file
}
}
zipTask.from(artifacts) {
into "${distZip.baseDir}/deps"
}
}
}
}
artifacts {
archives distZip
archives docsZip
archives schemaZip
}
task dist(dependsOn: assemble) {
group = 'Distribution'
description = 'Builds -dist, -docs and -schema distribution archives.'
}

View File

@@ -1,4 +0,0 @@
version=3.0.1-SNAPSHOT
org.gradle.jvmargs=-Xmx1536m -Dfile.encoding=UTF-8
org.gradle.caching=true
org.gradle.parallel=true

View File

@@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,185 +0,0 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

View File

@@ -1,89 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,82 +0,0 @@
apply plugin: 'maven'
ext.optionalDeps = []
ext.providedDeps = []
ext.optional = { optionalDeps << it }
ext.provided = { providedDeps << it }
install {
repositories.mavenInstaller {
customizePom(pom, project)
}
}
def customizePom(pom, gradleProject) {
pom.whenConfigured { generatedPom ->
// sort to make pom dependencies order consistent to ease comparison of older poms
generatedPom.dependencies = generatedPom.dependencies.sort { dep ->
"$dep.scope:$dep.groupId:$dep.artifactId"
}
def managedVersions = dependencyManagement.managedVersions
generatedPom.dependencies.findAll{dep -> !dep.version }.each { dep ->
dep.version = managedVersions["${dep.groupId}:${dep.artifactId}"]
}
// respect 'optional' and 'provided' dependencies
gradleProject.optionalDeps.each { dep ->
generatedPom.dependencies.find { it.artifactId == dep.name }?.optional = true
}
gradleProject.providedDeps.each { dep ->
generatedPom.dependencies.find { it.artifactId == dep.name }?.scope = 'provided'
}
// eliminate test-scoped dependencies (no need in maven central poms)
generatedPom.dependencies.removeAll { dep ->
dep.scope == 'test'
}
// add all items necessary for maven central publication
generatedPom.project {
name = gradleProject.description
description = gradleProject.description
url = 'https://github.com/spring-projects/spring-integration-aws'
organization {
name = 'SpringIO'
url = 'https://spring.io'
}
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'https://www.apache.org/licenses/LICENSE-2.0.txt'
distribution 'repo'
}
}
scm {
url = 'https://github.com/spring-projects/spring-integration-aws'
connection = 'scm:git:git://github.com/spring-projects/spring-integration-aws'
developerConnection = 'scm:git:git://github.com/spring-projects/spring-integration-aws'
}
developers {
developer {
id = 'amolnayak311'
name = 'Amol Nayak'
email = 'amolnayak311@gmail.com'
}
developer {
id = 'ghillert'
name = 'Gunnar Hillert'
email = 'ghillert@pivotal.io'
}
developer {
id = 'abilan'
name = 'Artem Bilan'
email = 'abilan@pivotal.io'
}
}
}
}
}

View File

@@ -1 +0,0 @@
rootProject.name = 'spring-integration-hazelcast'

View File

@@ -1,22 +0,0 @@
<html>
<body>
This document is the API specification for Spring Integration Hazelcast Support project
<hr/>
<div id="overviewBody">
<p>
For further API reference and developer documentation, see the
<a href="https://docs.spring.io/spring-integration/reference/"
target="_top">Spring Integration Reference Documentation</a>.
That documentation contains more detailed, developer-targeted
descriptions, with conceptual overviews, definitions of terms,
workarounds, and working code examples.
</p>
<p>
If you are interested in commercial training, consultancy, and
support for Spring Integration, please visit <a href="https://spring.io/" target="_top">
https://spring.io</a>
</p>
</div>
</body>
</html>

View File

@@ -1,598 +0,0 @@
/* Javadoc style sheet */
/*
Overall document style
*/
@import url('resources/fonts/dejavu.css');
body {
background-color:#ffffff;
color:#353833;
font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
font-size:14px;
margin:0;
}
a:link, a:visited {
text-decoration:none;
color:#4A6782;
}
a:hover, a:focus {
text-decoration:none;
color:#bb7a2a;
}
a:active {
text-decoration:none;
color:#4A6782;
}
a[name] {
color:#353833;
}
a[name]:hover {
text-decoration:none;
color:#353833;
}
pre {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
}
h1 {
font-size:20px;
}
h2 {
font-size:18px;
}
h3 {
font-size:16px;
font-style:italic;
}
h4 {
font-size:13px;
}
h5 {
font-size:12px;
}
h6 {
font-size:11px;
}
ul {
list-style-type:disc;
}
code, tt {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
padding-top:4px;
margin-top:8px;
line-height:1.4em;
}
dt code {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
padding-top:4px;
}
table tr td dt code {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
vertical-align:top;
padding-top:4px;
}
sup {
font-size:8px;
}
/*
Document title and Copyright styles
*/
.clear {
clear:both;
height:0px;
overflow:hidden;
}
.aboutLanguage {
float:right;
padding:0px 21px;
font-size:11px;
z-index:200;
margin-top:-9px;
}
.legalCopy {
margin-left:.5em;
}
.bar a, .bar a:link, .bar a:visited, .bar a:active {
color:#FFFFFF;
text-decoration:none;
}
.bar a:hover, .bar a:focus {
color:#bb7a2a;
}
.tab {
background-color:#0066FF;
color:#ffffff;
padding:8px;
width:5em;
font-weight:bold;
}
/*
Navigation bar styles
*/
.bar {
background-color:#4D7A97;
color:#FFFFFF;
padding:.8em .5em .4em .8em;
height:auto;/*height:1.8em;*/
font-size:11px;
margin:0;
}
.topNav {
background-color:#4D7A97;
color:#FFFFFF;
float:left;
padding:0;
width:100%;
clear:right;
height:2.8em;
padding-top:10px;
overflow:hidden;
font-size:12px;
}
.bottomNav {
margin-top:10px;
background-color:#4D7A97;
color:#FFFFFF;
float:left;
padding:0;
width:100%;
clear:right;
height:2.8em;
padding-top:10px;
overflow:hidden;
font-size:12px;
}
.subNav {
background-color:#dee3e9;
float:left;
width:100%;
overflow:hidden;
font-size:12px;
}
.subNav div {
clear:left;
float:left;
padding:0 0 5px 6px;
text-transform:uppercase;
}
ul.navList, ul.subNavList {
float:left;
margin:0 25px 0 0;
padding:0;
}
ul.navList li{
list-style:none;
float:left;
padding: 5px 6px;
text-transform:uppercase;
}
ul.subNavList li{
list-style:none;
float:left;
}
.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
color:#FFFFFF;
text-decoration:none;
text-transform:uppercase;
}
.topNav a:hover, .bottomNav a:hover {
text-decoration:none;
color:#bb7a2a;
text-transform:uppercase;
}
.navBarCell1Rev {
background-color:#F8981D;
color:#253441;
margin: auto 5px;
}
.skipNav {
position:absolute;
top:auto;
left:-9999px;
overflow:hidden;
}
/*
Page header and footer styles
*/
.header, .footer {
clear:both;
margin:0 20px;
padding:5px 0 0 0;
}
.indexHeader {
margin:10px;
position:relative;
}
.indexHeader span{
margin-right:15px;
}
.indexHeader h1 {
font-size:13px;
}
.title {
color:#2c4557;
margin:10px 0;
}
.subTitle {
margin:5px 0 0 0;
}
.header ul {
margin:0 0 15px 0;
padding:0;
}
.footer ul {
margin:20px 0 5px 0;
}
.header ul li, .footer ul li {
list-style:none;
font-size:13px;
}
/*
Heading styles
*/
div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
background-color:#dee3e9;
border:1px solid #d0d9e0;
margin:0 0 6px -8px;
padding:7px 5px;
}
ul.blockList ul.blockList ul.blockList li.blockList h3 {
background-color:#dee3e9;
border:1px solid #d0d9e0;
margin:0 0 6px -8px;
padding:7px 5px;
}
ul.blockList ul.blockList li.blockList h3 {
padding:0;
margin:15px 0;
}
ul.blockList li.blockList h2 {
padding:0px 0 20px 0;
}
/*
Page layout container styles
*/
.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
clear:both;
padding:10px 20px;
position:relative;
}
.indexContainer {
margin:10px;
position:relative;
font-size:12px;
}
.indexContainer h2 {
font-size:13px;
padding:0 0 3px 0;
}
.indexContainer ul {
margin:0;
padding:0;
}
.indexContainer ul li {
list-style:none;
padding-top:2px;
}
.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
font-size:12px;
font-weight:bold;
margin:10px 0 0 0;
color:#4E4E4E;
}
.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
margin:5px 0 10px 0px;
font-size:14px;
font-family:'DejaVu Sans Mono',monospace;
}
.serializedFormContainer dl.nameValue dt {
margin-left:1px;
font-size:1.1em;
display:inline;
font-weight:bold;
}
.serializedFormContainer dl.nameValue dd {
margin:0 0 0 1px;
font-size:1.1em;
display:inline;
}
/*
List styles
*/
ul.horizontal li {
display:inline;
font-size:0.9em;
}
ul.inheritance {
margin:0;
padding:0;
}
ul.inheritance li {
display:inline;
list-style:none;
}
ul.inheritance li ul.inheritance {
margin-left:15px;
padding-left:15px;
padding-top:1px;
}
ul.blockList, ul.blockListLast {
margin:10px 0 10px 0;
padding:0;
}
ul.blockList li.blockList, ul.blockListLast li.blockList {
list-style:none;
margin-bottom:15px;
line-height:1.4;
}
ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
padding:0px 20px 5px 10px;
border:1px solid #ededed;
background-color:#f8f8f8;
}
ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
padding:0 0 5px 8px;
background-color:#ffffff;
border:none;
}
ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
margin-left:0;
padding-left:0;
padding-bottom:15px;
border:none;
}
ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
list-style:none;
border-bottom:none;
padding-bottom:0;
}
table tr td dl, table tr td dl dt, table tr td dl dd {
margin-top:0;
margin-bottom:1px;
}
/*
Table styles
*/
.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {
width:100%;
border-left:1px solid #EEE;
border-right:1px solid #EEE;
border-bottom:1px solid #EEE;
}
.overviewSummary, .memberSummary {
padding:0px;
}
.overviewSummary caption, .memberSummary caption, .typeSummary caption,
.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {
position:relative;
text-align:left;
background-repeat:no-repeat;
color:#253441;
font-weight:bold;
clear:none;
overflow:hidden;
padding:0px;
padding-top:10px;
padding-left:1px;
margin:0px;
white-space:pre;
}
.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,
.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,
.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {
color:#FFFFFF;
}
.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {
white-space:nowrap;
padding-top:5px;
padding-left:12px;
padding-right:12px;
padding-bottom:7px;
display:inline-block;
float:left;
background-color:#F8981D;
border: none;
height:16px;
}
.memberSummary caption span.activeTableTab span {
white-space:nowrap;
padding-top:5px;
padding-left:12px;
padding-right:12px;
margin-right:3px;
display:inline-block;
float:left;
background-color:#F8981D;
height:16px;
}
.memberSummary caption span.tableTab span {
white-space:nowrap;
padding-top:5px;
padding-left:12px;
padding-right:12px;
margin-right:3px;
display:inline-block;
float:left;
background-color:#4D7A97;
height:16px;
}
.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {
padding-top:0px;
padding-left:0px;
padding-right:0px;
background-image:none;
float:none;
display:inline;
}
.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {
display:none;
width:5px;
position:relative;
float:left;
background-color:#F8981D;
}
.memberSummary .activeTableTab .tabEnd {
display:none;
width:5px;
margin-right:3px;
position:relative;
float:left;
background-color:#F8981D;
}
.memberSummary .tableTab .tabEnd {
display:none;
width:5px;
margin-right:3px;
position:relative;
background-color:#4D7A97;
float:left;
}
.overviewSummary td, .memberSummary td, .typeSummary td,
.useSummary td, .constantsSummary td, .deprecatedSummary td {
text-align:left;
padding:0px 0px 12px 10px;
width:100%;
}
th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,
td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{
vertical-align:top;
padding-right:0px;
padding-top:8px;
padding-bottom:3px;
}
th.colFirst, th.colLast, th.colOne, .constantsSummary th {
background:#dee3e9;
text-align:left;
padding:8px 3px 3px 7px;
}
td.colFirst, th.colFirst {
white-space:nowrap;
font-size:13px;
}
td.colLast, th.colLast {
font-size:13px;
}
td.colOne, th.colOne {
font-size:13px;
}
.overviewSummary td.colFirst, .overviewSummary th.colFirst,
.overviewSummary td.colOne, .overviewSummary th.colOne,
.memberSummary td.colFirst, .memberSummary th.colFirst,
.memberSummary td.colOne, .memberSummary th.colOne,
.typeSummary td.colFirst{
width:25%;
vertical-align:top;
}
td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
font-weight:bold;
}
.tableSubHeadingColor {
background-color:#EEEEFF;
}
.altColor {
background-color:#FFFFFF;
}
.rowColor {
background-color:#EEEEEF;
}
/*
Content styles
*/
.description pre {
margin-top:0;
}
.deprecatedContent {
margin:0;
padding:10px 0;
}
.docSummary {
padding:0;
}
ul.blockList ul.blockList ul.blockList li.blockList h3 {
font-style:normal;
}
div.block {
font-size:14px;
font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
}
td.colLast div {
padding-top:0px;
}
td.colLast a {
padding-bottom:3px;
}
/*
Formatting effect styles
*/
.sourceLineNo {
color:green;
padding:0 30px 0 0;
}
h1.hidden {
visibility:hidden;
overflow:hidden;
font-size:10px;
}
.block {
display:block;
margin:3px 10px 2px 0px;
color:#474747;
}
.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,
.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,
.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {
font-weight:bold;
}
.deprecationComment, .emphasizedPhrase, .interfaceName {
font-style:italic;
}
div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
div.block div.block span.interfaceName {
font-style:normal;
}
div.contentContainer ul.blockList li.blockList h2{
padding-bottom:0px;
}
/*
Spring
*/
pre.code {
background-color: #F8F8F8;
border: 1px solid #CCCCCC;
border-radius: 3px 3px 3px 3px;
overflow: auto;
padding: 10px;
margin: 4px 20px 2px 0px;
}
pre.code code, pre.code code * {
font-size: 1em;
}
pre.code code, pre.code code * {
padding: 0 !important;
margin: 0 !important;
}

View File

@@ -1,17 +0,0 @@
^\Q/*\E$
^\Q * Copyright \E20\d\d(\-20\d\d)?\Q the original author or authors.\E$
^\Q *\E$
^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$
^\Q * you may not use this file except in compliance with the License.\E$
^\Q * You may obtain a copy of the License at\E$
^\Q *\E$
^\Q * https://www.apache.org/licenses/LICENSE-2.0\E$
^\Q *\E$
^\Q * Unless required by applicable law or agreed to in writing, software\E$
^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$
^\Q * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\E$
^\Q * See the License for the specific language governing permissions and\E$
^\Q * limitations under the License.\E$
^\Q */\E$
^$
^.*$

View File

@@ -1,10 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files="package-info\.java" checks=".*" />
<suppress files="[\\/]test[\\/]" checks="AvoidStaticImport" />
<suppress files="[\\/]test[\\/]" checks="InnerTypeLast" />
<suppress files="[\\/]test[\\/]" checks="Javadoc*" />
</suppressions>

View File

@@ -1,179 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "https://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
<module name="SuppressionFilter">
<property name="file" value="src/checkstyle/checkstyle-suppressions.xml" />
</module>
<!-- Root Checks -->
<module name="RegexpHeader">
<property name="headerFile" value="src/checkstyle/checkstyle-header.txt" />
<property name="fileExtensions" value="java" />
</module>
<module name="NewlineAtEndOfFile"/>
<!-- TreeWalker Checks -->
<module name="TreeWalker">
<!-- Annotations -->
<module name="AnnotationUseStyle">
<property name="elementStyle" value="compact" />
</module>
<module name="MissingOverride" />
<module name="PackageAnnotation" />
<module name="AnnotationLocation">
<property name="allowSamelineSingleParameterlessAnnotation"
value="false" />
</module>
<!-- Block Checks -->
<module name="EmptyBlock">
<property name="option" value="text" />
</module>
<module name="LeftCurly" />
<module name="RightCurly">
<property name="option" value="alone" />
</module>
<module name="NeedBraces" />
<module name="AvoidNestedBlocks" />
<!-- Class Design -->
<module name="FinalClass" />
<module name="InterfaceIsType" />
<module name="HideUtilityClassConstructor" />
<module name="MutableException" />
<module name="InnerTypeLast" />
<module name="OneTopLevelClass" />
<!-- Coding -->
<module name="CovariantEquals" />
<module name="EmptyStatement" />
<module name="EqualsHashCode" />
<module name="InnerAssignment" />
<module name="SimplifyBooleanExpression" />
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="NestedForDepth">
<property name="max" value="3" />
</module>
<module name="NestedIfDepth">
<property name="max" value="4" />
</module>
<module name="NestedTryDepth">
<property name="max" value="3" />
</module>
<module name="MultipleVariableDeclarations" />
<module name="RequireThis">
<property name="checkMethods" value="false" />
</module>
<module name="OneStatementPerLine" />
<!-- Imports -->
<module name="AvoidStarImport" />
<module name="AvoidStaticImport">
<property name="excludes"
value="org.assertj.core.api.Assertions.*,
org.junit.Assert.*,
org.junit.Assume.*,
org.junit.internal.matchers.ThrowableMessageMatcher.*,
org.hamcrest.CoreMatchers.*,
org.hamcrest.Matchers.*,
org.mockito.Mockito.*,
org.mockito.BDDMockito.*,
org.mockito.Matchers.*" />
</module>
<module name="IllegalImport" />
<module name="RedundantImport" />
<module name="UnusedImports">
<property name="processJavadoc" value="true" />
</module>
<module name="ImportOrder">
<property name="groups" value="java,/^javax?\./,org,org.springframework,*" />
<property name="ordered" value="true" />
<property name="separated" value="true" />
<property name="option" value="top" />
<property name="sortStaticImportsAlphabetically" value="true" />
</module>
<!-- Javadoc Comments -->
<module name="JavadocType">
<property name="scope" value="package"/>
<property name="authorFormat" value=".+\s.+"/>
</module>
<module name="JavadocMethod"/>
<module name="JavadocVariable">
<property name="scope" value="public"/>
</module>
<module name="JavadocStyle">
<property name="checkEmptyJavadoc" value="true"/>
</module>
<module name="NonEmptyAtclauseDescription" />
<module name="JavadocTagContinuationIndentation">
<property name="offset" value="0"/>
</module>
<module name="AtclauseOrder">
<property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF"/>
<property name="tagOrder" value="@param, @author, @since, @see, @version, @serial, @deprecated"/>
</module>
<module name="AtclauseOrder">
<property name="target" value="METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
<property name="tagOrder" value="@param, @return, @throws, @since, @deprecated, @see"/>
</module>
<!-- Miscellaneous -->
<module name="CommentsIndentation">
<property name="tokens" value="BLOCK_COMMENT_BEGIN" />
</module>
<module name="UpperEll" />
<module name="ArrayTypeStyle" />
<module name="OuterTypeFilename" />
<!-- Modifiers -->
<module name="RedundantModifier" />
<!-- Regexp -->
<module name="RegexpSinglelineJava">
<property name="format" value="^\t* +\t*\S" />
<property name="message"
value="Line has leading space characters; indentation should be performed with tabs only." />
<property name="ignoreComments" value="true" />
</module>
<module name="RegexpSinglelineJava">
<property name="maximum" value="0"/>
<property name="format" value="org\.mockito\..*Mockito\.(when|doThrow|doAnswer)" />
<property name="message"
value="Please use BDDMockito instead of Mockito.(when|doThrow|doAnswer)." />
<property name="ignoreComments" value="true" />
</module>
<!--<module name="RegexpSinglelineJava">
<property name="maximum" value="0"/>
<property name="format" value="org\.junit\.Assert\.assert" />
<property name="message"
value="Please use AssertJ imports." />
<property name="ignoreComments" value="true" />
</module>-->
<module name="Regexp">
<property name="format" value="[ \t]+$" />
<property name="illegalPattern" value="true" />
<property name="message" value="Trailing whitespace" />
</module>
<module name="Regexp">
<property name="format" value="System.(out|err).print" />
<property name="illegalPattern" value="true" />
<property name="message" value="System.out or .err" />
</module>
<!-- Whitespace -->
<module name="GenericWhitespace" />
<module name="MethodParamPad" />
<module name="NoWhitespaceAfter" >
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS, ARRAY_DECLARATOR"/>
</module>
<module name="NoWhitespaceBefore" />
<module name="ParenPad" />
<module name="TypecastParenPad" />
<module name="WhitespaceAfter" />
<module name="WhitespaceAround" />
</module>
</module>

View File

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

View File

@@ -1,21 +0,0 @@
========================================================================
== NOTICE file corresponding to section 4 d of the Apache License, ==
== Version 2.0, in this case for the Spring Integration distribution. ==
========================================================================
This product includes software developed by
the Apache Software Foundation (https://www.apache.org).
The end-user documentation included with a redistribution, if any,
must include the following acknowledgement:
"This product includes software developed by the Spring Framework
Project (https://www.spring.io)."
Alternatively, this acknowledgement may appear in the software itself,
if and wherever such third-party acknowledgements normally appear.
The names "Spring", "Spring Framework", and "Spring Integration" must
not be used to endorse or promote products derived from this software
without prior written permission. For written permission, please contact
enquiries@springsource.com.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ package org.springframework.integration.hazelcast;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*
* @see org.springframework.integration.hazelcast.inbound.AbstractHazelcastMessageProducer
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ package org.springframework.integration.hazelcast;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*
* @see org.springframework.integration.hazelcast.inbound.AbstractHazelcastMessageProducer
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ package org.springframework.integration.hazelcast;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*
* @see org.springframework.integration.hazelcast.inbound.HazelcastClusterMonitorMessageProducer
* @see com.hazelcast.core.DistributedObjectListener

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ package org.springframework.integration.hazelcast;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*
* @see org.springframework.integration.hazelcast.inbound.HazelcastDistributedSQLMessageSource
* @see com.hazelcast.map.IMap

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ package org.springframework.integration.hazelcast;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public abstract class HazelcastHeaders {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
@@ -32,18 +29,21 @@ import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* Common Validator for Hazelcast Integration. It validates cache types and events.
*
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public final class HazelcastIntegrationDefinitionValidator {
public static <E extends Enum<E>> Set<String> validateEnumType(final Class<E> enumType, final String types) {
Set<String> typeSet = StringUtils.commaDelimitedListToSet(StringUtils.trimAllWhitespace(types));
Set<String> typeSet = StringUtils.commaDelimitedListToSet(StringUtils.trimAllWhitespace(types));
for (String type : typeSet) {
Enum.valueOf(enumType, type);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,17 +19,16 @@ package org.springframework.integration.hazelcast;
import java.net.SocketAddress;
import java.util.concurrent.locks.Lock;
import com.hazelcast.cluster.MembershipListener;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.multimap.MultiMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.integration.hazelcast.listener.HazelcastMembershipListener;
import com.hazelcast.cluster.MembershipListener;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.multimap.MultiMap;
/**
* This class creates an internal configuration {@link MultiMap} to cache Hazelcast instances' socket
* address information which used Hazelcast event-driven inbound channel adapter(s). It
@@ -39,7 +38,7 @@ import com.hazelcast.multimap.MultiMap;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class HazelcastLocalInstanceRegistrar implements SmartInitializingSingleton {
@@ -82,9 +81,9 @@ public class HazelcastLocalInstanceRegistrar implements SmartInitializingSinglet
public void afterSingletonsInstantiated() {
if (this.hazelcastInstance == null) {
if (!Hazelcast.getAllHazelcastInstances().isEmpty()) {
HazelcastInstance hazelcastInstance = Hazelcast.getAllHazelcastInstances().iterator().next();
hazelcastInstance.getCluster().addMembershipListener(new HazelcastMembershipListener());
syncConfigurationMultiMap(hazelcastInstance);
HazelcastInstance anyHazelcastInstance = Hazelcast.getAllHazelcastInstances().iterator().next();
anyHazelcastInstance.getCluster().addMembershipListener(new HazelcastMembershipListener());
syncConfigurationMultiMap(anyHazelcastInstance);
}
else {
logger.warn("No HazelcastInstances for MembershipListener registration");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class HazelcastIntegrationConfigurationInitializer implements IntegrationConfigurationInitializer {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ import org.springframework.util.StringUtils;
* Parser for the {@code <int-hazelcast:cm-inbound-channel-adapter />} component.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
public class HazelcastClusterMonitorInboundChannelAdapterParser extends
AbstractSingleBeanDefinitionParser {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,9 @@ import org.springframework.util.StringUtils;
* {@code <int-hazelcast:cq-inbound-channel-adapter/>} configuration.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @author Artem Bilan
*
* @since 6.0
*/
public class HazelcastContinuousQueryInboundChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
@@ -82,22 +84,21 @@ public class HazelcastContinuousQueryInboundChannelAdapterParser extends Abstrac
}
if (!StringUtils.hasText(element.getAttribute(CACHE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_ATTRIBUTE + "' attribute is required.", element);
errorAttributeRequired(element, parserContext, CACHE_ATTRIBUTE);
}
else if (!StringUtils.hasText(element.getAttribute(CACHE_EVENTS_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_EVENTS_ATTRIBUTE + "' attribute is required.", element);
errorAttributeRequired(element, parserContext, CACHE_EVENTS_ATTRIBUTE);
}
else if (!StringUtils.hasText(element.getAttribute(PREDICATE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + PREDICATE_ATTRIBUTE + "' attribute is required.", element);
errorAttributeRequired(element, parserContext, PREDICATE_ATTRIBUTE);
}
else if (!StringUtils.hasText(element.getAttribute(CACHE_LISTENING_POLICY_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_LISTENING_POLICY_ATTRIBUTE + "' attribute is required.",
element);
errorAttributeRequired(element, parserContext, CACHE_LISTENING_POLICY_ATTRIBUTE);
}
builder.addPropertyReference(OUTPUT_CHANNEL, channelName);
builder.addConstructorArgReference(element.getAttribute(CACHE_ATTRIBUTE));
builder.addConstructorArgValue(element.getAttribute(PREDICATE_ATTRIBUTE));
builder.addPropertyReference(OUTPUT_CHANNEL, channelName)
.addConstructorArgReference(element.getAttribute(CACHE_ATTRIBUTE))
.addConstructorArgValue(element.getAttribute(PREDICATE_ATTRIBUTE));
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, CACHE_EVENTS_ATTRIBUTE, CACHE_EVENT_TYPES);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, INCLUDE_VALUE_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, CACHE_LISTENING_POLICY_ATTRIBUTE);
@@ -105,4 +106,8 @@ public class HazelcastContinuousQueryInboundChannelAdapterParser extends Abstrac
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.PHASE);
}
private static void errorAttributeRequired(Element element, ParserContext parserContext, String attribute) {
parserContext.getReaderContext().error("'" + attribute + "' attribute is required.", element);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 the original author or authors.
* Copyright 2015-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ import org.springframework.util.StringUtils;
* {@code <int-hazelcast:ds-inbound-channel-adapter/>} configuration.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
public class HazelcastDistributedSQLInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
@@ -65,4 +65,5 @@ public class HazelcastDistributedSQLInboundChannelAdapterParser extends Abstract
return builder.getBeanDefinition();
}
}

View File

@@ -33,7 +33,7 @@ import org.springframework.util.StringUtils;
* {@code <int-hazelcast:inbound-channel-adapter />} configuration.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
public class HazelcastEventDrivenInboundChannelAdapterParser extends AbstractSingleBeanDefinitionParser {

View File

@@ -22,7 +22,7 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
* Namespace handler for the Hazelcast schema.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
public class HazelcastIntegrationNamespaceHandler extends AbstractIntegrationNamespaceHandler {

View File

@@ -31,7 +31,7 @@ import org.springframework.integration.hazelcast.outbound.HazelcastCacheWritingM
* {@code <int-hazelcast:inbound-channel-adapter />}.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
public class HazelcastOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2024 the original author 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,16 +25,6 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.hazelcast.CacheEventType;
import org.springframework.integration.hazelcast.CacheListeningPolicyType;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationDefinitionValidator;
import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
@@ -45,13 +35,24 @@ import com.hazelcast.map.AbstractIMapEvent;
import com.hazelcast.map.MapEvent;
import com.hazelcast.multimap.MultiMap;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.hazelcast.CacheEventType;
import org.springframework.integration.hazelcast.CacheListeningPolicyType;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationDefinitionValidator;
import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
/**
* Hazelcast Base Event-Driven Message Producer.
*
* @author Eren Avsarogullari
* @author Artem Bilan
* @author Ngoc Nhan
*
* @since 1.0.0
* @since 6.0
*/
public abstract class AbstractHazelcastMessageProducer extends MessageProducerSupport {
@@ -73,12 +74,12 @@ public abstract class AbstractHazelcastMessageProducer extends MessageProducerSu
}
public void setCacheEventTypes(String cacheEventTypes) {
Set<String> cacheEvents =
Set<String> events =
HazelcastIntegrationDefinitionValidator.validateEnumType(CacheEventType.class, cacheEventTypes);
Assert.notEmpty(cacheEvents, "'cacheEvents' must have elements");
Assert.notEmpty(events, "'events' must have elements");
HazelcastIntegrationDefinitionValidator.validateCacheEventsByDistributedObject(this.distributedObject,
cacheEvents);
this.cacheEvents = cacheEvents;
events);
this.cacheEvents = events;
}
protected CacheListeningPolicyType getCacheListeningPolicy() {
@@ -218,9 +219,9 @@ public abstract class AbstractHazelcastMessageProducer extends MessageProducerSu
entryEvent.getValue(), entryEvent.getOldValue());
return getMessageBuilderFactory().withPayload(messagePayload).copyHeaders(headers).build();
}
else if (event instanceof MapEvent) {
else if (event instanceof MapEvent mapEvent) {
return getMessageBuilderFactory()
.withPayload(((MapEvent) event).getNumberOfEntriesAffected()).copyHeaders(headers).build();
.withPayload(mapEvent.getNumberOfEntriesAffected()).copyHeaders(headers).build();
}
else {
throw new IllegalStateException("Invalid event is received. Event : " + event);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2022 the original author 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,11 +22,6 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.hazelcast.ClusterMonitorType;
import org.springframework.integration.hazelcast.HazelcastIntegrationDefinitionValidator;
import org.springframework.util.Assert;
import com.hazelcast.client.Client;
import com.hazelcast.client.ClientListener;
import com.hazelcast.cluster.MembershipEvent;
@@ -40,6 +35,11 @@ import com.hazelcast.partition.MigrationListener;
import com.hazelcast.partition.MigrationState;
import com.hazelcast.partition.ReplicaMigrationEvent;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.hazelcast.ClusterMonitorType;
import org.springframework.integration.hazelcast.HazelcastIntegrationDefinitionValidator;
import org.springframework.util.Assert;
/**
* Hazelcast Cluster Monitor Event Driven Message Producer is a message producer which
* enables {@link HazelcastClusterMonitorMessageProducer.HazelcastClusterMonitorListener}
@@ -48,7 +48,7 @@ import com.hazelcast.partition.ReplicaMigrationEvent;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class HazelcastClusterMonitorMessageProducer extends MessageProducerSupport {
@@ -64,10 +64,10 @@ public class HazelcastClusterMonitorMessageProducer extends MessageProducerSuppo
}
public void setMonitorEventTypes(String monitorEventTypes) {
final Set<String> monitorTypes =
Set<String> types =
HazelcastIntegrationDefinitionValidator.validateEnumType(ClusterMonitorType.class, monitorEventTypes);
Assert.notEmpty(monitorTypes, "'monitorTypes' must have elements");
this.monitorTypes = monitorTypes;
Assert.notEmpty(types, "'monitorTypes' must have elements");
this.monitorTypes = types;
}
@Override
@@ -89,13 +89,13 @@ public class HazelcastClusterMonitorMessageProducer extends MessageProducerSuppo
if (this.monitorTypes.contains(ClusterMonitorType.MIGRATION.name())) {
final UUID registrationId = this.hazelcastInstance.getPartitionService()
.addMigrationListener(clusterMonitorListener);
this.hazelcastRegisteredListenerIdMap.put(ClusterMonitorType.MIGRATION, registrationId);
this.hazelcastRegisteredListenerIdMap.put(ClusterMonitorType.MIGRATION, registrationId);
}
if (this.monitorTypes.contains(ClusterMonitorType.LIFECYCLE.name())) {
final UUID registrationId = this.hazelcastInstance.getLifecycleService()
.addLifecycleListener(clusterMonitorListener);
this.hazelcastRegisteredListenerIdMap.put(ClusterMonitorType.LIFECYCLE, registrationId);
this.hazelcastRegisteredListenerIdMap.put(ClusterMonitorType.LIFECYCLE, registrationId);
}
if (this.monitorTypes.contains(ClusterMonitorType.CLIENT.name())) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,11 @@
package org.springframework.integration.hazelcast.inbound;
import org.springframework.util.Assert;
import com.hazelcast.map.IMap;
import com.hazelcast.query.impl.predicates.SqlPredicate;
import org.springframework.util.Assert;
/**
* Hazelcast Continuous Query Message Producer is a message producer which enables
* {@link AbstractHazelcastMessageProducer.HazelcastEntryListener} with a
@@ -28,7 +28,7 @@ import com.hazelcast.query.impl.predicates.SqlPredicate;
* defined predicate and sends events to related channel.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
public class HazelcastContinuousQueryMessageProducer extends AbstractHazelcastMessageProducer {
@@ -47,7 +47,7 @@ public class HazelcastContinuousQueryMessageProducer extends AbstractHazelcastMe
this.includeValue = includeValue;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
protected void doStart() {
setHazelcastRegisteredEventListenerId(((IMap<?, ?>) this.distributedObject)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,20 +19,22 @@ package org.springframework.integration.hazelcast.inbound;
import java.util.Collection;
import java.util.Collections;
import com.hazelcast.map.IMap;
import com.hazelcast.query.impl.predicates.SqlPredicate;
import org.springframework.integration.endpoint.AbstractMessageSource;
import org.springframework.integration.hazelcast.DistributedSQLIterationType;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import com.hazelcast.map.IMap;
import com.hazelcast.query.impl.predicates.SqlPredicate;
/**
* Hazelcast Distributed SQL Message Source is a message source which runs defined
* distributed query in the cluster and returns results in the light of iteration type.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @author Artem Bilan
*
* @since 6.0
*/
@SuppressWarnings("rawtypes")
public class HazelcastDistributedSQLMessageSource extends AbstractMessageSource {
@@ -63,30 +65,20 @@ public class HazelcastDistributedSQLMessageSource extends AbstractMessageSource
@Override
@SuppressWarnings("unchecked")
protected Collection<?> doReceive() {
switch (this.iterationType) {
case ENTRY:
return getDistributedSQLResultSet(Collections
.unmodifiableCollection(this.distributedMap.entrySet(new SqlPredicate(this.distributedSql))));
final SqlPredicate predicate = new SqlPredicate(this.distributedSql);
Collection<?> collection =
switch (this.iterationType) {
case ENTRY -> this.distributedMap.entrySet(predicate);
case KEY -> this.distributedMap.keySet(predicate);
case LOCAL_KEY -> this.distributedMap.localKeySet(predicate);
default -> this.distributedMap.values(predicate);
};
case KEY:
return getDistributedSQLResultSet(Collections
.unmodifiableCollection(this.distributedMap.keySet(new SqlPredicate(this.distributedSql))));
case LOCAL_KEY:
return getDistributedSQLResultSet(Collections
.unmodifiableCollection(this.distributedMap.localKeySet(new SqlPredicate(this.distributedSql))));
default:
return getDistributedSQLResultSet(this.distributedMap.values(new SqlPredicate(this.distributedSql)));
}
}
private Collection<?> getDistributedSQLResultSet(Collection<?> collection) {
if (CollectionUtils.isEmpty(collection)) {
return null;
}
return collection;
return Collections.unmodifiableCollection(collection);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,10 +19,6 @@ package org.springframework.integration.hazelcast.inbound;
import java.util.HashMap;
import java.util.Map;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationDefinitionValidator;
import org.springframework.util.Assert;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
@@ -31,13 +27,16 @@ import com.hazelcast.collection.ItemListener;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.instance.EndpointQualifier;
import com.hazelcast.map.IMap;
import com.hazelcast.map.listener.MapListener;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import com.hazelcast.topic.Message;
import com.hazelcast.topic.MessageListener;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationDefinitionValidator;
import org.springframework.util.Assert;
/**
* Hazelcast Event Driven Message Producer is a message producer which enables
* {@link AbstractHazelcastMessageProducer.HazelcastEntryListener},
@@ -48,7 +47,7 @@ import com.hazelcast.topic.MessageListener;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessageProducer {
@@ -63,11 +62,11 @@ public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessag
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
protected void doStart() {
if (this.distributedObject instanceof IMap) {
setHazelcastRegisteredEventListenerId(((IMap<?, ?>) this.distributedObject)
.addEntryListener((MapListener) new HazelcastEntryListener(), true));
.addEntryListener(new HazelcastEntryListener(), true));
}
else if (this.distributedObject instanceof MultiMap) {
setHazelcastRegisteredEventListenerId(((MultiMap<?, ?>) this.distributedObject)
@@ -125,7 +124,7 @@ public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessag
return "hazelcast:inbound-channel-adapter";
}
private class HazelcastItemListener<E> extends AbstractHazelcastEventListener<ItemEvent<E>>
private final class HazelcastItemListener<E> extends AbstractHazelcastEventListener<ItemEvent<E>>
implements ItemListener<E> {
@Override
@@ -145,9 +144,7 @@ public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessag
event.getMember().getSocketAddress(EndpointQualifier.MEMBER), getCacheListeningPolicy());
}
if (logger.isDebugEnabled()) {
logger.debug("Received ItemEvent : " + event);
}
logger.debug(() -> "Received ItemEvent : " + event);
}
@Override
@@ -161,7 +158,7 @@ public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessag
}
private class HazelcastMessageListener<E> extends AbstractHazelcastEventListener<Message<E>>
private final class HazelcastMessageListener<E> extends AbstractHazelcastEventListener<Message<E>>
implements MessageListener<E> {
@Override
@@ -174,9 +171,7 @@ public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessag
sendMessage(event,
event.getPublishingMember().getSocketAddress(EndpointQualifier.MEMBER), getCacheListeningPolicy());
if (logger.isDebugEnabled()) {
logger.debug("Received Message : " + event);
}
logger.debug(() -> "Received Message : " + event);
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2022 the original author or authors.
* Copyright 2015-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,21 +16,25 @@
package org.springframework.integration.hazelcast.leader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.cp.CPSubsystem;
import com.hazelcast.cp.lock.FencedLock;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.log.LogAccessor;
import org.springframework.core.log.LogMessage;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.integration.leader.Candidate;
import org.springframework.integration.leader.Context;
import org.springframework.integration.leader.DefaultCandidate;
@@ -39,10 +43,6 @@ import org.springframework.integration.leader.event.LeaderEventPublisher;
import org.springframework.integration.support.leader.LockRegistryLeaderInitiator;
import org.springframework.util.Assert;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.cp.CPSubsystem;
import com.hazelcast.cp.lock.FencedLock;
/**
* Bootstrap leadership {@link org.springframework.integration.leader.Candidate candidates}
* with Hazelcast. Upon construction, {@link #start} must be invoked to
@@ -55,15 +55,17 @@ import com.hazelcast.cp.lock.FencedLock;
* @author Mael Le Guével
* @author Alexey Tsoy
* @author Robert Höglund
* @author Christian Tzolov
* @author Emil Palm
*/
public class LeaderInitiator implements SmartLifecycle, DisposableBean, ApplicationEventPublisherAware {
private static final Log logger = LogFactory.getLog(LeaderInitiator.class);
private static int threadNameCount = 0;
private static final LogAccessor logger = new LogAccessor(LeaderInitiator.class);
private static final Context NULL_CONTEXT = new NullContext();
private final Lock lock = new ReentrantLock();
/*** Hazelcast client.
*/
private final HazelcastInstance client;
@@ -76,12 +78,7 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
/**
* Executor service for running leadership daemon.
*/
private final ExecutorService executorService =
Executors.newSingleThreadExecutor(r -> {
Thread thread = new Thread(r, "Hazelcast-leadership-" + (threadNameCount++));
thread.setDaemon(true);
return thread;
});
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("Hazelcast-leadership-");
private long heartBeatMillis = LockRegistryLeaderInitiator.DEFAULT_HEART_BEAT_TIME;
@@ -99,7 +96,7 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
private int phase;
/**
* Future returned by submitting an {@link LeaderSelector} to {@link #executorService}.
* Future returned by submitting an {@link LeaderSelector} to {@link #taskExecutor}.
* This is used to cancel leadership.
*/
private volatile Future<Void> future;
@@ -131,7 +128,17 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
}
/**
* Sets the {@link LeaderEventPublisher}.
* Set a {@link AsyncTaskExecutor} for running leadership daemon.
* @param taskExecutor the {@link AsyncTaskExecutor} to use.
* @since 6.2
*/
public void setTaskExecutor(AsyncTaskExecutor taskExecutor) {
Assert.notNull(taskExecutor, "A 'taskExecutor' must not be null.");
this.taskExecutor = taskExecutor;
}
/**
* Set the {@link LeaderEventPublisher}.
* @param leaderEventPublisher the event publisher
*/
public void setLeaderEventPublisher(LeaderEventPublisher leaderEventPublisher) {
@@ -206,11 +213,17 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
* Start the registration of the {@link #candidate} for leader election.
*/
@Override
public synchronized void start() {
if (!this.running) {
this.leaderSelector = new LeaderSelector();
this.running = true;
this.future = this.executorService.submit(this.leaderSelector);
public void start() {
this.lock.lock();
try {
if (!this.running) {
this.leaderSelector = new LeaderSelector();
this.running = true;
this.future = this.taskExecutor.submit(this.leaderSelector);
}
}
finally {
this.lock.unlock();
}
}
@@ -225,13 +238,19 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
* If the candidate is currently leader, its leadership will be revoked.
*/
@Override
public synchronized void stop() {
if (this.running) {
this.running = false;
if (this.future != null) {
this.future.cancel(true);
public void stop() {
this.lock.lock();
try {
if (this.running) {
this.running = false;
if (this.future != null) {
this.future.cancel(true);
}
this.future = null;
}
this.future = null;
}
finally {
this.lock.unlock();
}
}
@@ -247,21 +266,16 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
@Override
public void destroy() {
stop();
this.executorService.shutdown();
}
FencedLock getLock() {
CPSubsystem cpSubSystem = this.client.getCPSubsystem();
FencedLock lock = cpSubSystem.getLock(this.candidate.getRole());
if (logger.isDebugEnabled()) {
logger.debug(
String.format("Use lock groupId '%s', lock count '%s'", lock.getGroupId(), lock.getLockCount()));
}
logger.debug(
LogMessage.format("Use lock groupId '%s', lock count '%s'", lock.getGroupId(), lock.getLockCount()));
return lock;
}
/**
* Callable that manages the acquisition of Hazelcast locks
* for leadership election.
@@ -279,17 +293,17 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
try {
while (isRunning()) {
try {
if (logger.isTraceEnabled()) {
logger.trace("Am I the leader (" + LeaderInitiator.this.candidate.getRole() + ") ? "
+ this.leader);
}
logger.trace(() ->
"Am I the leader (" + LeaderInitiator.this.candidate.getRole() + ")? " + this.leader);
if (getLock().isLockedByCurrentThread()) {
if (!this.leader) {
// Since we have the lock we need to ensure that the leader flag is set
this.leader = true;
}
// Give it a chance to expire.
if (yieldSign.tryAcquire(LeaderInitiator.this.heartBeatMillis, TimeUnit.MILLISECONDS)) {
if (LeaderInitiator.this.yieldSign
.tryAcquire(LeaderInitiator.this.heartBeatMillis, TimeUnit.MILLISECONDS)) {
revokeLeadership();
// Give it a chance to elect some other leader.
Thread.sleep(LeaderInitiator.this.busyWaitMillis);
@@ -304,27 +318,28 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
this.leader = true;
handleGranted();
}
if (!acquired && this.leader) {
//If we no longer can acquire the lock but still have the leader status
revokeLeadership();
}
}
}
catch (Exception e) {
catch (Exception ex) {
// The lock was broken and we are no longer leader
revokeLeadership();
if (isRunning()) {
// Give it a chance to elect some other leader.
try {
Thread.sleep(LeaderInitiator.this.busyWaitMillis);
}
catch (InterruptedException e1) {
// Ignore interruption and let it to be caught on the next cycle.
// Ignore interruption and let it be caught on the next cycle.
Thread.currentThread().interrupt();
}
}
if (logger.isDebugEnabled()) {
logger.debug("Error acquiring the lock for " + this.context +
". " + (isRunning() ? "Retrying..." : ""), e);
}
logger.debug(ex, () -> "Error acquiring the lock for " + this.context +
". " + (isRunning() ? "Retrying..." : ""));
}
}
}
@@ -343,8 +358,8 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
getLock().unlock();
}
catch (Exception e1) {
logger.warn("Could not unlock - treat as broken " + this.context + ". Revoking "
+ (isRunning() ? " and retrying..." : "..."), e1);
logger.warn(e1, () -> "Could not unlock - treat as broken " + this.context + ". Revoking "
+ (isRunning() ? " and retrying..." : "..."));
}
@@ -352,7 +367,6 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
}
}
private void handleGranted() throws InterruptedException {
LeaderInitiator.this.candidate.onGranted(this.context);
if (LeaderInitiator.this.leaderEventPublisher != null) {
@@ -360,8 +374,8 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
LeaderInitiator.this.leaderEventPublisher.publishOnGranted(
LeaderInitiator.this, this.context, this.role);
}
catch (Exception e) {
logger.warn("Error publishing OnGranted event.", e);
catch (Exception ex) {
logger.warn(ex, "Error publishing OnGranted event.");
}
}
}
@@ -371,10 +385,10 @@ public class LeaderInitiator implements SmartLifecycle, DisposableBean, Applicat
if (LeaderInitiator.this.leaderEventPublisher != null) {
try {
LeaderInitiator.this.leaderEventPublisher.publishOnRevoked(
LeaderInitiator.this, this.context, role);
LeaderInitiator.this, this.context, this.role);
}
catch (Exception e) {
logger.warn("Error publishing OnRevoked event.", e);
catch (Exception ex) {
logger.warn(ex, "Error publishing OnRevoked event.");
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2022 the original author 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,6 @@ import java.net.SocketAddress;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar;
import com.hazelcast.cluster.MembershipAdapter;
import com.hazelcast.cluster.MembershipEvent;
import com.hazelcast.core.Hazelcast;
@@ -29,13 +27,15 @@ import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.instance.EndpointQualifier;
import com.hazelcast.multimap.MultiMap;
import org.springframework.integration.hazelcast.HazelcastLocalInstanceRegistrar;
/**
* Hazelcast {@link MembershipAdapter} in order to listen for membership updates in the cluster.
*
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class HazelcastMembershipListener extends MembershipAdapter {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,11 +18,11 @@ package org.springframework.integration.hazelcast.lock;
import java.util.concurrent.locks.Lock;
import com.hazelcast.core.HazelcastInstance;
import org.springframework.integration.support.locks.LockRegistry;
import org.springframework.util.Assert;
import com.hazelcast.core.HazelcastInstance;
/**
* A {@link LockRegistry} implementation Hazelcast distributed locks.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class EntryEventMessagePayload<K, V> {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2017-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,6 @@ package org.springframework.integration.hazelcast.metadata;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.metadata.ListenableMetadataStore;
import org.springframework.integration.metadata.MetadataStoreListener;
import org.springframework.util.Assert;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
@@ -31,6 +26,11 @@ import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.metadata.ListenableMetadataStore;
import org.springframework.integration.metadata.MetadataStoreListener;
import org.springframework.util.Assert;
/**
* The Hazelcast {@link IMap}-based {@link ListenableMetadataStore} implementation.
*
@@ -43,7 +43,7 @@ public class HazelcastMetadataStore implements ListenableMetadataStore, Initiali
private final IMap<String, String> map;
private final List<MetadataStoreListener> listeners = new CopyOnWriteArrayList<MetadataStoreListener>();
private final List<MetadataStoreListener> listeners = new CopyOnWriteArrayList<>();
public HazelcastMetadataStore(HazelcastInstance hazelcastInstance) {
Assert.notNull(hazelcastInstance, "Hazelcast instance can't be null");
@@ -57,14 +57,14 @@ public class HazelcastMetadataStore implements ListenableMetadataStore, Initiali
@Override
public String putIfAbsent(String key, String value) {
Assert.notNull(key, "'key' must not be null.");
assertKey(key);
Assert.notNull(value, "'value' must not be null.");
return this.map.putIfAbsent(key, value);
}
@Override
public boolean replace(String key, String oldValue, String newValue) {
Assert.notNull(key, "'key' must not be null.");
assertKey(key);
Assert.notNull(oldValue, "'oldValue' must not be null.");
Assert.notNull(newValue, "'newValue' must not be null.");
return this.map.replace(key, oldValue, newValue);
@@ -72,23 +72,27 @@ public class HazelcastMetadataStore implements ListenableMetadataStore, Initiali
@Override
public void put(String key, String value) {
Assert.notNull(key, "'key' must not be null.");
assertKey(key);
Assert.notNull(value, "'value' must not be null.");
this.map.put(key, value);
}
@Override
public String get(String key) {
Assert.notNull(key, "'key' must not be null.");
assertKey(key);
return this.map.get(key);
}
@Override
public String remove(String key) {
Assert.notNull(key, "'key' must not be null.");
assertKey(key);
return this.map.remove(key);
}
private static void assertKey(String key) {
Assert.notNull(key, "'key' must not be null.");
}
@Override
public void addListener(MetadataStoreListener callback) {
Assert.notNull(callback, "callback object can not be null");
@@ -101,18 +105,14 @@ public class HazelcastMetadataStore implements ListenableMetadataStore, Initiali
}
@Override
public void afterPropertiesSet() throws Exception {
public void afterPropertiesSet() {
this.map.addEntryListener(new MapListener(this.listeners), true);
}
private static class MapListener implements EntryAddedListener<String, String>,
EntryRemovedListener<String, String>, EntryUpdatedListener<String, String> {
private final List<MetadataStoreListener> listeners;
MapListener(List<MetadataStoreListener> listeners) {
this.listeners = listeners;
}
private record MapListener(List<MetadataStoreListener> listeners)
implements EntryAddedListener<String, String>,
EntryRemovedListener<String, String>,
EntryUpdatedListener<String, String> {
@Override
public void entryAdded(EntryEvent<String, String> event) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,10 @@ package org.springframework.integration.hazelcast.outbound;
import java.util.Collection;
import java.util.Map;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.topic.ITopic;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.integration.expression.ExpressionUtils;
@@ -27,10 +31,6 @@ import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.topic.ITopic;
/**
* MessageHandler implementation that writes {@link Message} or payload to defined
* Hazelcast distributed cache object.
@@ -38,7 +38,7 @@ import com.hazelcast.topic.ITopic;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class HazelcastCacheWritingMessageHandler extends AbstractMessageHandler {
@@ -85,56 +85,51 @@ public class HazelcastCacheWritingMessageHandler extends AbstractMessageHandler
objectToStore = message.getPayload();
}
DistributedObject distributedObject = getDistributedObject(message);
DistributedObject object = getDistributedObject(message);
if (distributedObject instanceof Map) {
Map map = (Map) distributedObject;
if (object instanceof Map map) {
if (objectToStore instanceof Map) {
map.putAll((Map) objectToStore);
}
else if (objectToStore instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) objectToStore;
else if (objectToStore instanceof Map.Entry entry) {
map.put(entry.getKey(), entry.getValue());
}
else {
map.put(getKey(message), objectToStore);
}
}
else if (distributedObject instanceof MultiMap) {
MultiMap map = (MultiMap) distributedObject;
else if (object instanceof MultiMap map) {
if (objectToStore instanceof Map) {
Map<?, ?> mapToStore = (Map) objectToStore;
for (Map.Entry entry : mapToStore.entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
}
else if (objectToStore instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) objectToStore;
else if (objectToStore instanceof Map.Entry entry) {
map.put(entry.getKey(), entry.getValue());
}
else {
map.put(getKey(message), objectToStore);
}
}
else if (distributedObject instanceof ITopic) {
((ITopic) distributedObject).publish(objectToStore);
else if (object instanceof ITopic) {
((ITopic) object).publish(objectToStore);
}
else if (distributedObject instanceof Collection) {
else if (object instanceof Collection) {
if (objectToStore instanceof Collection) {
((Collection) distributedObject).addAll((Collection) objectToStore);
((Collection) object).addAll((Collection) objectToStore);
}
else {
((Collection) distributedObject).add(objectToStore);
((Collection) object).add(objectToStore);
}
}
else {
throw new IllegalStateException("The 'distributedObject' for 'HazelcastCacheWritingMessageHandler' " +
throw new IllegalStateException("The 'object' for 'HazelcastCacheWritingMessageHandler' " +
"must be of 'IMap', 'MultiMap', 'ITopic', 'ISet' or 'IList' type, " +
"but gotten: [" + distributedObject + "].");
"but gotten: [" + object + "].");
}
}
private DistributedObject getDistributedObject(final Message<?> message) {
if (this.distributedObject != null) {
return this.distributedObject;
@@ -144,7 +139,7 @@ public class HazelcastCacheWritingMessageHandler extends AbstractMessageHandler
}
else if (message.getHeaders().containsKey(HazelcastHeaders.CACHE_NAME)) {
return getBeanFactory()
.getBean(message.getHeaders().get(HazelcastHeaders.CACHE_NAME, String.class),
.getBean(message.getHeaders().get(HazelcastHeaders.CACHE_NAME, String.class), // NOSONAR
DistributedObject.class);
}
else {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,14 @@ package org.springframework.integration.hazelcast.store;
import java.util.Collection;
import org.springframework.integration.store.AbstractKeyValueMessageStore;
import org.springframework.util.Assert;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.query.Predicates;
import com.hazelcast.query.QueryConstants;
import org.springframework.integration.store.AbstractKeyValueMessageStore;
import org.springframework.util.Assert;
/**
* The Hazelcast {@link IMap}-based {@link AbstractKeyValueMessageStore} implementation.
*
@@ -76,8 +76,8 @@ public class HazelcastMessageStore extends AbstractKeyValueMessageStore {
@Override
protected Collection<?> doListKeys(String keyPattern) {
Assert.hasText(keyPattern, "'keyPattern' must not be empty");
keyPattern = keyPattern.replaceAll("\\*", "%");
return this.map.keySet(Predicates.like(QueryConstants.KEY_ATTRIBUTE_NAME.value(), keyPattern));
return this.map.keySet(Predicates.like(QueryConstants.KEY_ATTRIBUTE_NAME.value(),
keyPattern.replaceAll("\\*", "%")));
}
}

View File

@@ -1,4 +1,4 @@
http\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast-1.0.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast-1.0.xsd
http\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast-1.0.xsd
https\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast-1.0.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast-1.0.xsd
https\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast-1.0.xsd
http\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast-1.0.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast.xsd
http\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast.xsd
https\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast-1.0.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast.xsd
https\://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd=org/springframework/integration/hazelcast/config/xml/spring-integration-hazelcast.xsd

View File

@@ -0,0 +1,303 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.org/schema/integration/hazelcast"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:integration="http://www.springframework.org/schema/integration"
targetNamespace="http://www.springframework.org/schema/integration/hazelcast"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"
schemaLocation="https://www.springframework.org/schema/beans/spring-beans.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:import namespace="http://www.springframework.org/schema/integration"
schemaLocation="https://www.springframework.org/schema/integration/spring-integration.xsd"/>
<xsd:element name="inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures Hazelcast Event-Driven Inbound Channel Adapter
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="cache" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="com.hazelcast.core.DistributedObject" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies cache reference to listen ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-events" type="xsd:string" use="optional" default="ADDED">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="value">
<tool:expected-type
type="org.springframework.integration.hazelcast.common.CacheEventType" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies cache entry event types ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-listening-policy" default="SINGLE" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[ Specifies cache listening policy. ]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="SINGLE" />
<xsd:enumeration value="ALL" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="outbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures Hazelcast Outbound Channel Adapter
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:choice minOccurs="0" maxOccurs="2">
<xsd:element name="request-handler-advice-chain" type="integration:handlerAdviceChainType"
minOccurs="0" maxOccurs="1" />
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:choice>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="cache" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="com.hazelcast.core.DistributedObject" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies cache reference to listen ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-expression" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Specifies cache name to listen ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="key-expression" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Specifies entry key ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="extract-payload" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Specifies whole message or just payload to send ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the order for invocation when this endpoint is connected as a
subscriber to a SubscribableChannel.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="cq-inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures Hazelcast Continuous Query Inbound Channel Adapter
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="cache" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="com.hazelcast.core.IMap" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies cache reference to listen ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-events" type="xsd:string" use="optional" default="ADDED">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="value">
<tool:expected-type
type="org.springframework.integration.hazelcast.common.CacheEventType" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies cache entry event types ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="predicate" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Specifies predicate for continuous query ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="include-value" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Specifies including of value and oldValue in continuous query result ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-listening-policy" default="SINGLE" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[ Specifies cache listening policy. ]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="SINGLE" />
<xsd:enumeration value="ALL" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="ds-inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures Hazelcast Distributed SQL Inbound Channel Adapter
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="cache" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="com.hazelcast.core.IMap" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies cache reference to listen ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="iteration-type" default="VALUE" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[ Specifies Distributed-SQL Iteration Types. ]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ENTRY" />
<xsd:enumeration value="KEY" />
<xsd:enumeration value="LOCAL_KEY" />
<xsd:enumeration value="VALUE" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="distributed-sql" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Specifies Distributed-SQL ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="cm-inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation>
Configures Hazelcast Cluster Monitor Inbound Channel Adapter
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
<xsd:attribute name="hazelcast-instance" use="required" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="com.hazelcast.core.HazelcastInstance" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies hazelcast instance reference to listen ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="monitor-types" type="xsd:string" use="optional" default="MEMBERSHIP">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="value">
<tool:expected-type
type="org.springframework.integration.hazelcast.ClusterMonitorType" />
</tool:annotation>
</xsd:appinfo>
<xsd:documentation>
<![CDATA[ Specifies cluster monitor types ]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -8,7 +8,7 @@
<constructor-arg value="distList"/>
</bean>
<bean id="hzInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
<bean id="hzInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance" destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="instanceName" value="Test_Hazelcast_Instance"/>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author 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,24 +16,22 @@
package org.springframework.integration.hazelcast;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Resource;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hazelcast.collection.IList;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Integration Definition Validator Test Class
@@ -41,15 +39,16 @@ import com.hazelcast.instance.impl.HazelcastInstanceFactory;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"rawtypes"})
public class HazelcastIntegrationDefinitionValidatorTests {
@Resource
private IList<HazelcastIntegrationTestUser> distList;
@Autowired
private IList distList;
@AfterClass
public static void shutdown() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import java.util.Objects;
* User Bean for Hazelcast Integration Unit Tests
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
public class HazelcastIntegrationTestUser implements Comparable<HazelcastIntegrationTestUser>, Serializable {

View File

@@ -27,7 +27,7 @@ import org.springframework.messaging.Message;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
public class HazelcastTestRequestHandlerAdvice extends AbstractRequestHandlerAdvice {

View File

@@ -0,0 +1,372 @@
/*
* Copyright 2014-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.aopalliance.aop.Advice;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.IntegrationMessageHeaderAccessor;
import org.springframework.integration.MessageRejectedException;
import org.springframework.integration.annotation.BridgeFrom;
import org.springframework.integration.annotation.BridgeTo;
import org.springframework.integration.annotation.IdempotentReceiver;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.config.GlobalChannelInterceptor;
import org.springframework.integration.handler.MessageProcessor;
import org.springframework.integration.handler.ServiceActivatingHandler;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.handler.advice.IdempotentReceiverInterceptor;
import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport;
import org.springframework.integration.metadata.ConcurrentMetadataStore;
import org.springframework.integration.metadata.MetadataStore;
import org.springframework.integration.metadata.SimpleMetadataStore;
import org.springframework.integration.selector.MetadataStoreSelector;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.transaction.PseudoTransactionManager;
import org.springframework.integration.transaction.TransactionInterceptorBuilder;
import org.springframework.integration.transformer.Transformer;
import org.springframework.jmx.support.MBeanServerFactoryBean;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.spy;
/**
* @author Artem Bilan
* @author Gary Russell
*
* @since 4.1
*/
@SpringJUnitConfig
@DirtiesContext
public class IdempotentReceiverIntegrationTests {
@Autowired
private MessageChannel input;
@Autowired
private PollableChannel output;
@Autowired
private MetadataStore store;
@Autowired
private IdempotentReceiverInterceptor idempotentReceiverInterceptor;
@Autowired
private AtomicInteger adviceCalled;
@Autowired
private MessageChannel annotatedMethodChannel;
@Autowired
private FooService fooService;
@Autowired
private MessageChannel annotatedBeanMessageHandlerChannel;
@Autowired
private MessageChannel annotatedBeanMessageHandlerChannel2;
@Autowired
private MessageChannel bridgeChannel;
@Autowired
private MessageChannel toBridgeChannel;
@Autowired
private PollableChannel bridgePollableChannel;
@Autowired
private AtomicBoolean txSupplied;
@Test
@SuppressWarnings("unchecked")
public void testIdempotentReceiver() {
this.idempotentReceiverInterceptor.setThrowExceptionOnRejection(true);
TestUtils.getPropertyValue(this.store, "metadata", Map.class).clear();
Message<String> message = new GenericMessage<>("foo");
this.input.send(message);
Message<?> receive = this.output.receive(10000);
assertThat(receive).isNotNull();
assertThat(this.adviceCalled.get()).isEqualTo(1);
assertThat(TestUtils.getPropertyValue(this.store, "metadata", Map.class)).hasSize(1);
String foo = this.store.get("foo");
assertThat(foo).isEqualTo("FOO");
assertThatExceptionOfType(MessageRejectedException.class)
.isThrownBy(() -> this.input.send(message));
this.idempotentReceiverInterceptor.setThrowExceptionOnRejection(false);
this.input.send(message);
receive = this.output.receive(10000);
assertThat(receive).isNotNull();
assertThat(this.adviceCalled.get()).isEqualTo(2);
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
assertThat(TestUtils.getPropertyValue(store, "metadata", Map.class)).hasSize(1);
assertThat(this.txSupplied.get()).isTrue();
}
@Test
public void testIdempotentReceiverOnMethod() {
TestUtils.getPropertyValue(this.store, "metadata", Map.class).clear();
Message<String> message = new GenericMessage<>("foo");
this.annotatedMethodChannel.send(message);
this.annotatedMethodChannel.send(message);
assertThat(this.fooService.messages.size()).isEqualTo(2);
assertThat(this.fooService.messages.get(1)
.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}
@Test
public void testIdempotentReceiverOnBeanMessageHandler() {
PollableChannel replyChannel = new QueueChannel();
Message<String> message = MessageBuilder.withPayload("bar").setReplyChannel(replyChannel).build();
this.annotatedBeanMessageHandlerChannel.send(message);
Message<?> receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);
this.annotatedBeanMessageHandlerChannel.send(message);
receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
this.annotatedBeanMessageHandlerChannel2.send(new GenericMessage<>("baz"));
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> this.annotatedBeanMessageHandlerChannel2.send(new GenericMessage<>("baz")))
.withMessageContaining("duplicate message has been received");
}
@Test
public void testIdempotentReceiverOnBridgeTo() {
PollableChannel replyChannel = new QueueChannel();
Message<String> message = MessageBuilder.withPayload("bridgeTo").setReplyChannel(replyChannel).build();
this.bridgeChannel.send(message);
Message<?> receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);
this.bridgeChannel.send(message);
receive = replyChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}
@Test
public void testIdempotentReceiverOnBridgeFrom() {
Message<String> message = MessageBuilder.withPayload("bridgeFrom").build();
this.toBridgeChannel.send(message);
Message<?> receive = this.bridgePollableChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).doesNotContainKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE);
this.toBridgeChannel.send(message);
receive = this.bridgePollableChannel.receive(10000);
assertThat(receive).isNotNull();
assertThat(receive.getHeaders()).containsEntry(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE, true);
}
@Configuration
@EnableIntegration
@EnableIntegrationMBeanExport(server = "mBeanServer")
public static class ContextConfiguration {
@Bean
public static MBeanServerFactoryBean mBeanServer() {
return new MBeanServerFactoryBean();
}
@Bean(destroyMethod = "shutdown")
public HazelcastInstance hazelcastInstance() {
return Hazelcast.newHazelcastInstance();
}
@Bean
public ConcurrentMetadataStore store() {
return new SimpleMetadataStore(
hazelcastInstance()
.getMap("idempotentReceiverMetadataStore"));
}
@Bean
public IdempotentReceiverInterceptor idempotentReceiverInterceptor() {
return new IdempotentReceiverInterceptor(
new MetadataStoreSelector(
message -> message.getPayload().toString(),
message -> message.getPayload().toString().toUpperCase(), store()));
}
@Bean
public PlatformTransactionManager transactionManager() {
return spy(new PseudoTransactionManager());
}
@Bean
public TransactionInterceptor transactionInterceptor() {
return new TransactionInterceptorBuilder(true)
.build();
}
@Bean
public MessageChannel input() {
return new DirectChannel();
}
@Bean
public PollableChannel output() {
return new QueueChannel();
}
@Bean
public AtomicBoolean txSupplied() {
return new AtomicBoolean();
}
@Bean
@GlobalChannelInterceptor(patterns = "output")
public ChannelInterceptor txSuppliedChannelInterceptor(final AtomicBoolean txSupplied) {
return new ChannelInterceptor() {
@Override
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
txSupplied.set(TransactionSynchronizationManager.isActualTransactionActive());
}
};
}
@Bean
@org.springframework.integration.annotation.Transformer(inputChannel = "input",
outputChannel = "output",
adviceChain = {"fooAdvice",
"idempotentReceiverInterceptor",
"transactionInterceptor"})
public Transformer transformer() {
return message -> message;
}
@Bean
public AtomicInteger adviceCalled() {
return new AtomicInteger();
}
@Bean
public Advice fooAdvice(@SuppressWarnings("unused") final AtomicInteger adviceCalled) {
return new AbstractRequestHandlerAdvice() {
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
adviceCalled.incrementAndGet();
return callback.execute();
}
};
}
@Bean
public MessageChannel annotatedMethodChannel() {
return new DirectChannel();
}
@Bean
public FooService fooService() {
return new FooService();
}
@Bean
@BridgeTo
@IdempotentReceiver("idempotentReceiverInterceptor")
public MessageChannel bridgeChannel() {
return new DirectChannel();
}
@Bean
@BridgeFrom("toBridgeChannel")
@IdempotentReceiver("idempotentReceiverInterceptor")
public PollableChannel bridgePollableChannel() {
return new QueueChannel();
}
@Bean
@ServiceActivator(inputChannel = "annotatedBeanMessageHandlerChannel")
@IdempotentReceiver("idempotentReceiverInterceptor")
public MessageHandler messageHandler() {
return new ServiceActivatingHandler((MessageProcessor<Object>) message -> message);
}
@Bean
@ServiceActivator(inputChannel = "annotatedBeanMessageHandlerChannel2")
@IdempotentReceiver("idempotentReceiverInterceptor")
public MessageHandler messageHandler2() {
return message -> {
if (message.getHeaders().containsKey(IntegrationMessageHeaderAccessor.DUPLICATE_MESSAGE)) {
throw new MessageHandlingException(message, "duplicate message has been received");
}
};
}
}
@Component
private static class FooService {
private final List<Message<?>> messages = new ArrayList<Message<?>>();
@ServiceActivator(inputChannel = "annotatedMethodChannel")
@IdempotentReceiver("idempotentReceiverInterceptor")
public void handle(Message<?> message) {
this.messages.add(message);
}
}
}

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="instance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
<bean id="instance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance" destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="CPSubsystemConfig">

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,8 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -33,22 +30,20 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Continuous Query Inbound Channel Adapter Unit Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastCQDistributedMapInboundChannelAdapterTests {
@Autowired
@@ -66,25 +61,20 @@ public class HazelcastCQDistributedMapInboundChannelAdapterTests {
@Autowired
private PollableChannel cqMapChannel5;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap1;
@Autowired
private IMap cqDistributedMap1;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap2;
@Autowired
private IMap cqDistributedMap2;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap3;
@Autowired
private IMap cqDistributedMap3;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap4;
@Autowired
private IMap cqDistributedMap4;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap5;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private IMap cqDistributedMap5;
@Test
public void testContinuousQueryForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,10 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.LifecycleEvent;
import com.hazelcast.core.LifecycleEvent.LifecycleState;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
@@ -28,15 +30,10 @@ import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundCh
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.client.Client;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.LifecycleEvent;
import com.hazelcast.core.LifecycleEvent.LifecycleState;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.internal.nio.ConnectionType;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Cluster Monitor Inbound Channel Adapter Unit Test Class
@@ -44,8 +41,8 @@ import com.hazelcast.internal.nio.ConnectionType;
* @author Eren Avsarogullari
* @author Artem Bilan
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@RunWith(SpringRunner.class)
@SpringJUnitConfig
@DirtiesContext
@Ignore("Hard to reach CP consensus with limited number of members in two clusters")
public class HazelcastClusterMonitorInboundChannelAdapterTests {
@@ -111,12 +108,4 @@ public class HazelcastClusterMonitorInboundChannelAdapterTests {
assertThat(((LifecycleEvent) msg.getPayload()).getState()).isEqualTo(lifecycleState);
}
private void verifyClientEvent(final Message<?> msg) {
assertThat(msg).isNotNull();
assertThat(msg.getPayload()).isNotNull();
assertThat(msg.getPayload() instanceof Client).isTrue();
assertThat(((Client) msg.getPayload()).getClientType()).isEqualTo(ConnectionType.JAVA_CLIENT);
assertThat(((Client) msg.getPayload()).getSocketAddress()).isNotNull();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,8 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.collection.IList;
import com.hazelcast.core.EntryEventType;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,21 +29,20 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.collection.IList;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed List Event Driven Inbound Channel Adapter Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedListEventDrivenInboundChannelAdapterTests {
@Autowired
@@ -58,19 +54,14 @@ public class HazelcastDistributedListEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edListChannel3;
@Resource
private IList<HazelcastIntegrationTestUser> edDistributedList1;
@Autowired
private IList edDistributedList1;
@Resource
private IList<HazelcastIntegrationTestUser> edDistributedList2;
@Autowired
private IList edDistributedList2;
@Resource
private IList<HazelcastIntegrationTestUser> edDistributedList3;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private IList edDistributedList3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,8 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -33,22 +30,20 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed Map Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedMapEventDrivenInboundChannelAdapterTests {
@Autowired
@@ -63,22 +58,17 @@ public class HazelcastDistributedMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edMapChannel4;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap1;
@Autowired
private IMap edDistributedMap1;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap2;
@Autowired
private IMap edDistributedMap2;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap3;
@Autowired
private IMap edDistributedMap3;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap4;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private IMap edDistributedMap4;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,8 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.collection.IQueue;
import com.hazelcast.core.EntryEventType;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,21 +29,20 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.collection.IQueue;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed Queue Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedQueueEventDrivenInboundChannelAdapterTests {
@Autowired
@@ -58,19 +54,14 @@ public class HazelcastDistributedQueueEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edQueueChannel3;
@Resource
private IQueue<HazelcastIntegrationTestUser> edDistributedQueue1;
@Autowired
private IQueue edDistributedQueue1;
@Resource
private IQueue<HazelcastIntegrationTestUser> edDistributedQueue2;
@Autowired
private IQueue edDistributedQueue2;
@Resource
private IQueue<HazelcastIntegrationTestUser> edDistributedQueue3;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private IQueue edDistributedQueue3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author 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,32 +16,27 @@
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Hazelcast Distributed SQL Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedSQLInboundChannelAdapterTests {
@Autowired
@@ -56,22 +51,17 @@ public class HazelcastDistributedSQLInboundChannelAdapterTests {
@Autowired
private PollableChannel dsMapChannel4;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap1;
@Autowired
private IMap dsDistributedMap1;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap2;
@Autowired
private IMap dsDistributedMap2;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap3;
@Autowired
private IMap dsDistributedMap3;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap4;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private IMap dsDistributedMap4;
@Test
public void testDistributedSQLForOnlyENTRYIterationType() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,8 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.collection.ISet;
import com.hazelcast.core.EntryEventType;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,21 +29,20 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.collection.ISet;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Distributed Set Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedSetEventDrivenInboundChannelAdapterTests {
@Autowired
@@ -58,19 +54,14 @@ public class HazelcastDistributedSetEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edSetChannel3;
@Resource
private ISet<HazelcastIntegrationTestUser> edDistributedSet1;
@Autowired
private ISet edDistributedSet1;
@Resource
private ISet<HazelcastIntegrationTestUser> edDistributedSet2;
@Autowired
private ISet edDistributedSet2;
@Resource
private ISet<HazelcastIntegrationTestUser> edDistributedSet3;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private ISet edDistributedSet3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author 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,44 +16,34 @@
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.topic.ITopic;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundChannelAdapterTestUtils;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.topic.ITopic;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Hazelcast Distributed Topic Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastDistributedTopicEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edTopicChannel1;
@Resource
private ITopic<HazelcastIntegrationTestUser> edDistributedTopic1;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private ITopic edDistributedTopic1;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,8 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.multimap.MultiMap;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -33,23 +30,21 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.multimap.MultiMap;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast MultiMap Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @author Artem Bilan
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastMultiMapEventDrivenInboundChannelAdapterTests {
@Autowired
@@ -61,19 +56,14 @@ public class HazelcastMultiMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edMultiMapChannel3;
@Resource
private MultiMap<Integer, HazelcastIntegrationTestUser> edMultiMap1;
@Autowired
private MultiMap edMultiMap1;
@Resource
private MultiMap<Integer, HazelcastIntegrationTestUser> edMultiMap2;
@Autowired
private MultiMap edMultiMap2;
@Resource
private MultiMap<Integer, HazelcastIntegrationTestUser> edMultiMap3;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private MultiMap edMultiMap3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,8 @@
package org.springframework.integration.hazelcast.inbound;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.junit.AfterClass;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.replicatedmap.ReplicatedMap;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -33,22 +30,20 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.replicatedmap.ReplicatedMap;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Hazelcast Replicated Map Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
@DirtiesContext
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests {
@Autowired
@@ -63,22 +58,17 @@ public class HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edReplicatedMapChannel4;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap1;
@Autowired
private ReplicatedMap edReplicatedMap1;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap2;
@Autowired
private ReplicatedMap edReplicatedMap2;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap3;
@Autowired
private ReplicatedMap edReplicatedMap3;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap4;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Autowired
private ReplicatedMap edReplicatedMap4;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
package org.springframework.integration.hazelcast.inbound.config;
import javax.annotation.Resource;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -27,18 +26,16 @@ import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundCh
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import com.hazelcast.map.IMap;
/**
* Hazelcast Continuous Query Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class,
loader = AnnotationConfigContextLoader.class)
@DirtiesContext
@@ -53,13 +50,13 @@ public class HazelcastCQDistributedMapInboundChannelAdapterConfigTests {
@Autowired
private PollableChannel cqDistributedMapChannel3;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap1;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap2;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testCQDistributedMap3;
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.integration.hazelcast.inbound.config;
import com.hazelcast.core.HazelcastInstance;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -26,14 +27,13 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hazelcast.core.HazelcastInstance;
/**
* Hazelcast Cluster Monitor Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class)
@DirtiesContext

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
package org.springframework.integration.hazelcast.inbound.config;
import javax.annotation.Resource;
import com.hazelcast.map.IMap;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -27,18 +26,16 @@ import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundCh
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import com.hazelcast.map.IMap;
/**
* Hazelcast Distributed SQL Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class,
loader = AnnotationConfigContextLoader.class)
@DirtiesContext
@@ -56,16 +53,16 @@ public class HazelcastDistributedSQLInboundChannelAdapterConfigTests {
@Autowired
private PollableChannel dsDistributedMapChannel4;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap2;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap3;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDSDistributedMap4;
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,13 @@
package org.springframework.integration.hazelcast.inbound.config;
import javax.annotation.Resource;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -27,24 +32,16 @@ import org.springframework.integration.hazelcast.inbound.util.HazelcastInboundCh
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
/**
* Hazelcast Event Driven Inbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationInboundTestConfiguration.class,
loader = AnnotationConfigContextLoader.class)
@DirtiesContext
@@ -74,28 +71,28 @@ public class HazelcastEventDrivenInboundChannelAdapterConfigTests {
@Autowired
private PollableChannel multiMapChannel;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDistributedMap;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> testDistributedMap2;
@Resource
@Autowired
private IList<HazelcastIntegrationTestUser> testDistributedList;
@Resource
@Autowired
private ISet<HazelcastIntegrationTestUser> testDistributedSet;
@Resource
@Autowired
private IQueue<HazelcastIntegrationTestUser> testDistributedQueue;
@Resource
@Autowired
private ITopic<HazelcastIntegrationTestUser> testTopic;
@Resource
@Autowired
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> testReplicatedMap;
@Resource
@Autowired
private MultiMap<Integer, HazelcastIntegrationTestUser> testMultiMap;
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author 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,16 @@
package org.springframework.integration.hazelcast.inbound.config;
import javax.annotation.PreDestroy;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -33,18 +42,6 @@ import org.springframework.integration.hazelcast.inbound.HazelcastDistributedSQL
import org.springframework.integration.hazelcast.inbound.HazelcastEventDrivenMessageProducer;
import org.springframework.messaging.PollableChannel;
import com.hazelcast.collection.IList;
import com.hazelcast.collection.IQueue;
import com.hazelcast.collection.ISet;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
/**
* Configuration Class for Hazelcast Integration Inbound Test
*
@@ -55,11 +52,6 @@ import com.hazelcast.topic.ITopic;
@EnableIntegration
public class HazelcastIntegrationInboundTestConfiguration {
@PreDestroy
public void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Bean
public PollableChannel distributedMapChannel() {
return new QueueChannel();
@@ -228,7 +220,7 @@ public class HazelcastIntegrationInboundTestConfiguration {
return config;
}
@Bean(destroyMethod = "")
@Bean(destroyMethod = "shutdown")
public HazelcastInstance testHazelcastInstance() {
return Hazelcast.newHazelcastInstance(hazelcastConfig());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2022 the original author 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,18 +16,9 @@
package org.springframework.integration.hazelcast.inbound.util;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import java.util.Collection;
import java.util.Map;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import com.hazelcast.cluster.MembershipEvent;
import com.hazelcast.collection.ICollection;
import com.hazelcast.core.DistributedObjectEvent;
@@ -39,11 +30,20 @@ import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.spi.exception.DistributedObjectDestroyedException;
import com.hazelcast.topic.ITopic;
import org.springframework.integration.hazelcast.HazelcastHeaders;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.message.EntryEventMessagePayload;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
/**
* Util Class for Hazelcast Inbound Channel Adapters Test Support.
*
* @author Eren Avsarogullari
* @since 1.0.0
* @since 6.0
*/
@SuppressWarnings("unchecked")
public final class HazelcastInboundChannelAdapterTestUtils {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2024 the original author 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,37 +16,41 @@
package org.springframework.integration.hazelcast.leader;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Mockito.spy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.cp.CPGroupId;
import com.hazelcast.cp.CPSubsystem;
import com.hazelcast.cp.lock.FencedLock;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.leader.Candidate;
import org.springframework.integration.leader.Context;
import org.springframework.integration.leader.DefaultCandidate;
import org.springframework.integration.leader.event.AbstractLeaderEvent;
import org.springframework.integration.leader.event.DefaultLeaderEventPublisher;
import org.springframework.integration.leader.event.LeaderEventPublisher;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
/**
* Tests for hazelcast leader election.
@@ -56,9 +60,9 @@ import com.hazelcast.instance.impl.HazelcastInstanceFactory;
* @author Dave Syer
* @author Artem Bilan
* @author Mael Le Guével
* @author Emil Palm
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@SpringJUnitConfig
@DirtiesContext
public class LeaderInitiatorTests {
@@ -74,11 +78,6 @@ public class LeaderInitiatorTests {
@Autowired
private LeaderInitiator initiator;
@AfterClass
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Test
public void testLeaderElections() throws Exception {
assertThat(this.candidate.onGrantedLatch.await(5, TimeUnit.SECONDS)).isTrue();
@@ -179,7 +178,6 @@ public class LeaderInitiatorTests {
initiator1.destroy();
CountDownLatch onGranted = new CountDownLatch(1);
DefaultCandidate candidate = spy(new DefaultCandidate());
@@ -213,35 +211,82 @@ public class LeaderInitiatorTests {
initiator.destroy();
}
@Test
public void testRevokeLeadershipCalledWhenLockNotAcquiredButStillLeader() throws Exception {
// Initialize mocks and objects needed for the revoke leadership when fenced lock is no longer acquired
HazelcastInstance hazelcastInstance = mock();
Candidate candidate = mock();
FencedLock fencedLock = mock();
LeaderEventPublisher leaderEventPublisher = mock();
CPSubsystem cpSubsystem = mock(CPSubsystem.class);
given(candidate.getRole()).willReturn("role");
given(hazelcastInstance.getCPSubsystem()).willReturn(cpSubsystem);
given(cpSubsystem.getLock(anyString())).willReturn(fencedLock);
given(fencedLock.getGroupId())
.willReturn(new CPGroupId() {
@Override
public String getName() {
return "";
}
@Override
public long getId() {
return 0;
}
});
LeaderInitiator leaderInitiator = new LeaderInitiator(hazelcastInstance, candidate);
leaderInitiator.setLeaderEventPublisher(leaderEventPublisher);
// Simulate that the lock is currently held by this thread
given(fencedLock.isLockedByCurrentThread()).willReturn(true, false);
given(fencedLock.tryLock(anyLong(), any(TimeUnit.class))).willReturn(false); // Lock acquisition fails
// Start the LeaderInitiator to trigger the leader election process
leaderInitiator.start();
// Simulate the lock acquisition check process
Thread.sleep(1000); // Give time for the async task to run
// Verify that revokeLeadership was called due to lock not being acquired
// unlock is part of revokeLeadership
verify(fencedLock).unlock();
// verify revoke event is published
verify(leaderEventPublisher).publishOnRevoked(any(Object.class), any(Context.class), anyString());
leaderInitiator.destroy();
}
@Configuration
public static class TestConfig {
@Bean
public TestCandidate candidate() {
TestCandidate candidate() {
return new TestCandidate();
}
@Bean
public Config hazelcastConfig() {
Config hazelcastConfig() {
Config config = new Config();
config.getCPSubsystemConfig()
.setSessionHeartbeatIntervalSeconds(1);
return config;
}
@Bean(destroyMethod = "")
public HazelcastInstance hazelcastInstance() {
@Bean(destroyMethod = "shutdown")
HazelcastInstance hazelcastInstance() {
return Hazelcast.newHazelcastInstance(hazelcastConfig());
}
@Bean
public LeaderInitiator initiator() {
LeaderInitiator initiator() {
return new LeaderInitiator(hazelcastInstance(), candidate());
}
@Bean
public TestEventListener testEventListener() {
TestEventListener testEventListener() {
return new TestEventListener();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2020 the original author or authors.
* Copyright 2017-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,23 +16,23 @@
package org.springframework.integration.hazelcast.lock;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import org.junit.AfterClass;
import org.junit.Test;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.cp.lock.FencedLock;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Artem Bilan
@@ -47,7 +47,7 @@ public class HazelcastLockRegistryTests {
private static final HazelcastInstance instance = Hazelcast.newHazelcastInstance(CONFIG);
@AfterClass
@AfterAll
public static void destroy() {
HazelcastInstanceFactory.terminateAll();
}
@@ -145,7 +145,8 @@ public class HazelcastLockRegistryTests {
lock1.lockInterruptibly();
AtomicBoolean locked = new AtomicBoolean();
CountDownLatch latch = new CountDownLatch(1);
Future<Object> result = Executors.newSingleThreadExecutor().submit(() -> {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Object> result = executorService.submit(() -> {
Lock lock2 = registry.obtain("foo");
locked.set(lock2.tryLock(200, TimeUnit.MILLISECONDS));
latch.countDown();
@@ -163,6 +164,7 @@ public class HazelcastLockRegistryTests {
Object ise = result.get(10, TimeUnit.SECONDS);
assertThat(ise).isInstanceOf(IllegalMonitorStateException.class);
assertThat(((Exception) ise).getMessage()).contains("Current thread is not owner of the lock!");
executorService.shutdown();
}
@Test
@@ -174,7 +176,8 @@ public class HazelcastLockRegistryTests {
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
lock1.lockInterruptibly();
Executors.newSingleThreadExecutor().execute(() -> {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
Lock lock2 = registry.obtain("foo");
try {
latch1.countDown();
@@ -196,6 +199,7 @@ public class HazelcastLockRegistryTests {
latch2.countDown();
assertThat(latch3.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isTrue();
executorService.shutdown();
}
@Test
@@ -208,7 +212,8 @@ public class HazelcastLockRegistryTests {
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
lock1.lockInterruptibly();
Executors.newSingleThreadExecutor().execute(() -> {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
Lock lock2 = registry2.obtain("foo");
try {
latch1.countDown();
@@ -230,6 +235,7 @@ public class HazelcastLockRegistryTests {
latch2.countDown();
assertThat(latch3.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(locked.get()).isTrue();
executorService.shutdown();
}
@Test
@@ -239,7 +245,8 @@ public class HazelcastLockRegistryTests {
lock.lockInterruptibly();
final AtomicBoolean locked = new AtomicBoolean();
final CountDownLatch latch = new CountDownLatch(1);
Future<Object> result = Executors.newSingleThreadExecutor().submit(() -> {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Object> result = executorService.submit(() -> {
try {
lock.unlock();
}
@@ -255,6 +262,7 @@ public class HazelcastLockRegistryTests {
Object imse = result.get(10, TimeUnit.SECONDS);
assertThat(imse).isInstanceOf(IllegalMonitorStateException.class);
assertThat(((Exception) imse).getMessage()).contains("Current thread is not owner of the lock!");
executorService.shutdown();
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2020 the original author or authors.
* Copyright 2017-2023 the original author 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,25 +16,26 @@
package org.springframework.integration.hazelcast.metadata;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.integration.metadata.MetadataStoreListener;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.integration.metadata.MetadataStoreListener;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.awaitility.Awaitility.await;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* @author Vinicius Carvalho
* @author Artem Bilan
*/
public class HazelcastMetadataStoreTests {
@@ -44,24 +45,24 @@ public class HazelcastMetadataStoreTests {
HazelcastMetadataStore metadataStore;
@BeforeClass
@BeforeAll
public static void init() {
instance = Hazelcast.newHazelcastInstance();
map = instance.getMap("customTestsMetadataStore");
}
@AfterClass
@AfterAll
public static void destroy() {
instance.getLifecycleService().terminate();
instance.shutdown();
}
@Before
public void setup() throws Exception {
@BeforeEach
public void setup() {
this.metadataStore = new HazelcastMetadataStore(map);
this.metadataStore.afterPropertiesSet();
}
@After
@AfterEach
public void clean() {
map.clear();
}
@@ -81,62 +82,43 @@ public class HazelcastMetadataStoreTests {
@Test
public void testGetValueFromMetadataStore() {
this.metadataStore.put("HazelcastMetadataStoreTests-GetValue", "Hello Hazelcast");
String retrievedValue = this.metadataStore
.get("HazelcastMetadataStoreTests-GetValue");
String retrievedValue = this.metadataStore.get("HazelcastMetadataStoreTests-GetValue");
assertThat(retrievedValue).isEqualTo("Hello Hazelcast");
}
@Test
public void testPersistEmptyStringToMetadataStore() {
this.metadataStore.put("HazelcastMetadataStoreTests-PersistEmpty", "");
String retrievedValue = this.metadataStore
.get("HazelcastMetadataStoreTests-PersistEmpty");
String retrievedValue = this.metadataStore.get("HazelcastMetadataStoreTests-PersistEmpty");
assertThat(retrievedValue).isEqualTo("");
}
@Test
public void testPersistNullStringToMetadataStore() {
try {
this.metadataStore.put("HazelcastMetadataStoreTests-PersistEmpty", null);
fail("Expected an IllegalArgumentException to be thrown.");
}
catch (IllegalArgumentException e) {
assertThat(e.getMessage()).isEqualTo("'value' must not be null.");
}
assertThatIllegalArgumentException()
.isThrownBy(() -> this.metadataStore.put("HazelcastMetadataStoreTests-PersistEmpty", null))
.withMessage("'value' must not be null.");
}
@Test
public void testPersistWithEmptyKeyToMetadataStore() {
this.metadataStore.put("", "PersistWithEmptyKey");
String retrievedValue = this.metadataStore.get("");
assertThat(retrievedValue).isEqualTo("PersistWithEmptyKey");
}
@Test
public void testPersistWithNullKeyToMetadataStore() {
try {
this.metadataStore.put(null, "something");
fail("Expected an IllegalArgumentException to be thrown.");
}
catch (IllegalArgumentException e) {
assertThat(e.getMessage()).isEqualTo("'key' must not be null.");
}
assertThatIllegalArgumentException()
.isThrownBy(() -> this.metadataStore.put(null, "something"))
.withMessage("'key' must not be null.");
}
@Test
public void testGetValueWithNullKeyFromMetadataStore() {
try {
this.metadataStore.get(null);
}
catch (IllegalArgumentException e) {
assertThat(e.getMessage()).isEqualTo("'key' must not be null.");
return;
}
fail("Expected an IllegalArgumentException to be thrown.");
assertThatIllegalArgumentException()
.isThrownBy(() -> this.metadataStore.get(null))
.withMessage("'key' must not be null.");
}
@Test
@@ -152,8 +134,7 @@ public class HazelcastMetadataStoreTests {
@Test
public void testPersistKeyValueIfAbsent() {
this.metadataStore.putIfAbsent("HazelcastMetadataStoreTests-Spring",
"Integration");
this.metadataStore.putIfAbsent("HazelcastMetadataStoreTests-Spring", "Integration");
assertThat(map.get("HazelcastMetadataStoreTests-Spring")).isEqualTo("Integration");
}
@@ -173,7 +154,8 @@ public class HazelcastMetadataStoreTests {
this.metadataStore.put("foo", "bar");
this.metadataStore.replace("foo", "bar", "baz");
this.metadataStore.remove("foo");
verify(listener).onAdd("foo", "bar");
await().untilAsserted(() -> verify(listener).onAdd("foo", "bar"));
verify(listener).onUpdate("foo", "baz");
verify(listener).onRemove("foo", "baz");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
package org.springframework.integration.hazelcast.outbound;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -31,12 +29,13 @@ import java.util.TreeMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -51,13 +50,10 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Hazelcast Outbound Channel Adapter Test Class.
@@ -65,12 +61,11 @@ import com.hazelcast.topic.ITopic;
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@SpringJUnitConfig
@DirtiesContext
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"unchecked", "rawtypes"})
public class HazelcastOutboundChannelAdapterTests {
private static final String DISTRIBUTED_MAP = "distributedMap";
@@ -152,41 +147,41 @@ public class HazelcastOutboundChannelAdapterTests {
@Qualifier("lockChannel")
private MessageChannel lockChannel;
@Resource
@Autowired
private Map<?, ?> distributedMap;
@Resource
@Autowired
private Map<?, ?> distributedBulkMap;
@Resource
private MultiMap<Integer, HazelcastIntegrationTestUser> multiMap;
@Autowired
private MultiMap multiMap;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> replicatedMap;
@Autowired
private ReplicatedMap replicatedMap;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> bulkReplicatedMap;
@Autowired
private ReplicatedMap bulkReplicatedMap;
@Resource
private List<HazelcastIntegrationTestUser> distributedList;
@Autowired
private List distributedList;
@Resource
private List<HazelcastIntegrationTestUser> distributedBulkList;
@Autowired
private List distributedBulkList;
@Resource
private Set<HazelcastIntegrationTestUser> distributedSet;
@Autowired
private Set distributedSet;
@Resource
private Set<HazelcastIntegrationTestUser> distributedBulkSet;
@Autowired
private Set distributedBulkSet;
@Resource
private Queue<HazelcastIntegrationTestUser> distributedQueue;
@Autowired
private Queue distributedQueue;
@Resource
private Queue<HazelcastIntegrationTestUser> distributedBulkQueue;
@Autowired
private Queue distributedBulkQueue;
@Resource
private ITopic<HazelcastIntegrationTestUser> topic;
@Autowired
private ITopic topic;
@Autowired
@Qualifier("testFirstMapRequestHandlerAdvice")
@@ -248,12 +243,12 @@ public class HazelcastOutboundChannelAdapterTests {
@Qualifier("testTopicRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice testTopicRequestHandlerAdvice;
@AfterClass
@AfterAll
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}
@Before
@BeforeEach
public void setUp() {
this.distributedMap.clear();
this.distributedBulkMap.clear();
@@ -332,10 +327,8 @@ public class HazelcastOutboundChannelAdapterTests {
public void testBulkWriteToReplicatedMap() throws InterruptedException {
Map<Integer, HazelcastIntegrationTestUser> userMap =
new HashMap<>(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1;
index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userMap
.put(index, HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userMap.put(index, HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
this.bulkReplicatedMapChannel.send(new GenericMessage<>(userMap));
@@ -346,7 +339,6 @@ public class HazelcastOutboundChannelAdapterTests {
.verifyMapForPayload(new TreeMap(this.bulkReplicatedMap));
}
@Test
public void testWriteToDistributedList() {
HazelcastOutboundChannelAdapterTestUtils
@@ -358,8 +350,7 @@ public class HazelcastOutboundChannelAdapterTests {
public void testBulkWriteToDistributedList() throws InterruptedException {
List<HazelcastIntegrationTestUser> userList =
new ArrayList<>(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1;
index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userList.add(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
@@ -383,8 +374,7 @@ public class HazelcastOutboundChannelAdapterTests {
public void testBulkWriteToDistributedSet() throws InterruptedException {
Set<HazelcastIntegrationTestUser> userSet =
new HashSet<>(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1;
index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userSet.add(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
@@ -410,8 +400,7 @@ public class HazelcastOutboundChannelAdapterTests {
public void testBulkWriteToDistributedQueue() throws InterruptedException {
Queue<HazelcastIntegrationTestUser> userQueue =
new ArrayBlockingQueue(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);
for (int index = 1;
index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
userQueue.add(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index));
}
@@ -431,29 +420,33 @@ public class HazelcastOutboundChannelAdapterTests {
this.testTopicRequestHandlerAdvice);
}
@Test(expected = MessageHandlingException.class)
@Test
public void testWriteToDistributedMapWhenCacheIsNotSet() {
this.fifthMapChannel.send(new GenericMessage<>(
HazelcastOutboundChannelAdapterTestUtils.getTestUser(1)));
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() ->
this.fifthMapChannel.send(
new GenericMessage<>(HazelcastOutboundChannelAdapterTestUtils.getTestUser(1))));
}
@Test(expected = MessageHandlingException.class)
@Test
public void testWriteToDistributedMapWhenKeyExpressionIsNotSet() {
Message<HazelcastIntegrationTestUser> message = this.messageBuilderFactory
.withPayload(HazelcastOutboundChannelAdapterTestUtils.getTestUser(1))
.setHeader(HazelcastHeaders.CACHE_NAME, DISTRIBUTED_MAP).build();
this.sixthMapChannel.send(message);
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> this.sixthMapChannel.send(message));
}
@Test(expected = MessageHandlingException.class)
@Test
public void testWriteToLock() {
this.lockChannel.send(new GenericMessage<>("foo"));
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> this.lockChannel.send(new GenericMessage<>("foo")));
}
private void sendMessageWithCacheHeaderToChannel(final MessageChannel channel,
final String headerName, final String distributedObjectName) {
for (int index = 1;
index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
for (int index = 1; index <= HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT; index++) {
Message<HazelcastIntegrationTestUser> message = this.messageBuilderFactory
.withPayload(HazelcastOutboundChannelAdapterTestUtils.getTestUser(index))
.setHeader(headerName, distributedObjectName).build();
@@ -461,8 +454,7 @@ public class HazelcastOutboundChannelAdapterTests {
}
}
private void verifyMapForMessage(
final Map<Integer, Message<HazelcastIntegrationTestUser>> map) {
private static void verifyMapForMessage(final Map<Integer, Message<HazelcastIntegrationTestUser>> map) {
int index = 1;
assertThat(map).isNotNull();
assertThat(map.size()).isEqualTo(HazelcastOutboundChannelAdapterTestUtils.DATA_COUNT);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2022 the original author 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,13 +20,17 @@ import java.util.List;
import java.util.Queue;
import java.util.Set;
import javax.annotation.PreDestroy;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.config.EnableIntegration;
@@ -36,34 +40,18 @@ import org.springframework.integration.hazelcast.outbound.HazelcastCacheWritingM
import org.springframework.integration.hazelcast.outbound.util.HazelcastOutboundChannelAdapterTestUtils;
import org.springframework.messaging.MessageChannel;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
/**
* Configuration Class for Hazelcast Integration Outbound Test
*
* @author Eren Avsarogullari
* @author Artem Bilan
*
* @since 1.0.0
* @since 6.0
*/
@Configuration
@ComponentScan(basePackages = { "org.springframework.integration.hazelcast.*" })
@EnableIntegration
@IntegrationComponentScan("org.springframework.integration.hazelcast.outbound")
public class HazelcastIntegrationOutboundTestConfiguration {
@PreDestroy
public void terminate() {
HazelcastInstanceFactory.terminateAll();
}
@Bean
public MessageChannel distMapChannel() {
return new DirectChannel();
@@ -144,7 +132,7 @@ public class HazelcastIntegrationOutboundTestConfiguration {
return testHzInstance().getReplicatedMap("Replicated_Map1");
}
@Bean(destroyMethod = "")
@Bean(destroyMethod = "shutdown")
public HazelcastInstance testHzInstance() {
return Hazelcast.newHazelcastInstance();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,11 +20,13 @@ import java.util.List;
import java.util.Queue;
import java.util.Set;
import javax.annotation.Resource;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -33,25 +35,17 @@ import org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvi
import org.springframework.integration.hazelcast.outbound.util.HazelcastOutboundChannelAdapterTestUtils;
import org.springframework.messaging.MessageChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import com.hazelcast.instance.impl.HazelcastInstanceFactory;
import com.hazelcast.map.IMap;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* Hazelcast Outbound Channel Adapter JavaConfig driven Unit Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
* @author Atem Bilan
*
* @since 6.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = HazelcastIntegrationOutboundTestConfiguration.class,
loader = AnnotationConfigContextLoader.class)
@SpringJUnitConfig(classes = HazelcastIntegrationOutboundTestConfiguration.class)
@DirtiesContext
public class HazelcastOutboundChannelAdapterConfigTests {
@@ -87,28 +81,28 @@ public class HazelcastOutboundChannelAdapterConfigTests {
@Qualifier("replicatedMapChannel2")
private MessageChannel replicatedMapChannel2;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> distMap;
@Resource
@Autowired
private IMap<Integer, HazelcastIntegrationTestUser> distBulkMap;
@Resource
@Autowired
private List<HazelcastIntegrationTestUser> distList;
@Resource
@Autowired
private Set<HazelcastIntegrationTestUser> distSet;
@Resource
@Autowired
private Queue<HazelcastIntegrationTestUser> distQueue;
@Resource
@Autowired
private ITopic<HazelcastIntegrationTestUser> topic;
@Resource
@Autowired
private MultiMap<Integer, HazelcastIntegrationTestUser> multiMap;
@Resource
@Autowired
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> replicatedMap;
@Autowired
@@ -143,7 +137,7 @@ public class HazelcastOutboundChannelAdapterConfigTests {
@Qualifier("replicatedMapRequestHandlerAdvice")
private HazelcastTestRequestHandlerAdvice replicatedMapRequestHandlerAdvice;
@AfterClass
@AfterAll
public static void shutdown() {
HazelcastInstanceFactory.terminateAll();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 the original author or authors.
* Copyright 2016-2022 the original author 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,9 +16,6 @@
package org.springframework.integration.hazelcast.outbound.util;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -32,24 +29,27 @@ import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import com.hazelcast.topic.MessageListener;
import org.springframework.integration.hazelcast.HazelcastIntegrationTestUser;
import org.springframework.integration.hazelcast.HazelcastTestRequestHandlerAdvice;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.GenericMessage;
import com.hazelcast.multimap.MultiMap;
import com.hazelcast.replicatedmap.ReplicatedMap;
import com.hazelcast.topic.ITopic;
import com.hazelcast.topic.MessageListener;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
/**
* Util Class for Hazelcast Outbound Channel Adapter Test Support
*
* @author Eren Avsarogullari
*
* @since 1.0.0
* @since 6.0
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({"unchecked", "rawtypes"})
public final class HazelcastOutboundChannelAdapterTestUtils {
public static final int DATA_COUNT = 100;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,17 @@
package org.springframework.integration.hazelcast.store;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.history.MessageHistory;
@@ -35,9 +36,7 @@ import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Vinicius Carvalho
@@ -51,26 +50,25 @@ public class HazelcastMessageStoreTests {
private static IMap<Object, Object> map;
@BeforeClass
@BeforeAll
public static void init() {
instance = Hazelcast.newHazelcastInstance();
map = instance.getMap("customTestsMessageStore");
store = new HazelcastMessageStore(map);
}
@AfterClass
@AfterAll
public static void destroy() {
instance.getLifecycleService().terminate();
instance.shutdown();
}
@Before
@BeforeEach
public void clean() {
map.clear();
}
@Test
public void testWithMessageHistory() {
Message<?> message = new GenericMessage<>("Hello");
DirectChannel fooChannel = new DirectChannel();
fooChannel.setBeanName("fooChannel");
@@ -108,7 +106,6 @@ public class HazelcastMessageStoreTests {
@Test
public void addAndGetMessage() {
Message<?> message = MessageBuilder.withPayload("test").build();
store.addMessage(message);
Message<?> retrieved = store.getMessage(message.getHeaders().getId());
@@ -146,4 +143,34 @@ public class HazelcastMessageStoreTests {
assertThat(groupCount).isEqualTo(1);
}
@Test
public void sameMessageInTwoGroupsNotRemovedByFirstGroup() {
GenericMessage<String> testMessage = new GenericMessage<>("test data");
store.addMessageToGroup("1", testMessage);
store.addMessageToGroup("2", testMessage);
store.removeMessageGroup("1");
assertThat(store.getMessageCount()).isEqualTo(1);
store.removeMessageGroup("2");
assertThat(store.getMessageCount()).isEqualTo(0);
}
@Test
public void removeMessagesFromGroupDontRemoveSameMessageInOtherGroup() {
GenericMessage<String> testMessage = new GenericMessage<>("test data");
store.addMessageToGroup("1", testMessage);
store.addMessageToGroup("2", testMessage);
store.removeMessagesFromGroup("1", testMessage);
assertThat(store.getMessageCount()).isEqualTo(1);
assertThat(store.messageGroupSize("1")).isEqualTo(0);
assertThat(store.messageGroupSize("2")).isEqualTo(1);
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p [%t] [%c] - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.springframework" level="warn"/>
<Logger name="org.springframework.integration" level="warn"/>
<Logger name="org.springframework.integration.hazelcast" level="info"/>
<Root level="warn">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>