INTEXT-142: Add Spring Integration Hazelcast

JIRA: https://jira.spring.io/browse/INTEXT-142
This commit is contained in:
erenavsarogullari
2015-03-05 01:30:54 +00:00
committed by Artem Bilan
parent fddd7e47b4
commit bfec7640ca
62 changed files with 5485 additions and 0 deletions

View File

@@ -0,0 +1,301 @@
SPRING INTEGRATION HAZELCAST SUPPORT
====================================
## HAZELCAST EVENT-DRIVEN INBOUND CHANNEL ADAPTER
Hazelcast provides distributed data structures such as
* com.hazelcast.core.IMap,
* com.hazelcast.core.MultiMap,
* com.hazelcast.core.IList,
* com.hazelcast.core.ISet,
* com.hazelcast.core.IQueue,
* com.hazelcast.core.ITopic,
* com.hazelcast.core.ReplicatedMap.
It also provides event listeners in order to listen to the modifications performed on these data structures.
* com.hazelcast.core.EntryListener<K, V>
* com.hazelcast.core.ItemListener<E>
* com.hazelcast.core.MessageListener<E>
Hazelcast Event-Driven Inbound Channel Adapter listens related cache events and sends event messages to defined channel. Its basic definition is as follows :
```
<int-hazelcast:inbound-channel-adapter channel="mapChannel"
cache="map"
cache-events="UPDATED, REMOVED"
cache-listening-policy="SINGLE" />
```
Basically, Hazelcast Event-Driven Inbound Channel Adapter requires following attributes :
* **channel :** Specifies channel which message is sent. It is mandatory attribute.
* **cache :** Specifies the distributed Object reference which is listened. It is mandatory attribute.
* **cache-events :** Specifies cache events which are listened. It is optional attribute and its default value is ADDED. Its supported values are as follows :
1. Supported cache event types for IMap and MultiMap : ADDED, REMOVED, UPDATED, EVICTED, EVICT_ALL and CLEAR_ALL.
2. Supported cache event types for ReplicatedMap : ADDED, REMOVED, UPDATED, EVICTED.
3. Supported cache event types for IList, ISet and IQueue : ADDED, REMOVED.
4. There is no need to cache event type definition for ITopic.
* **cache-listening-policy :** Specifies cache listening policy as SINGLE or ALL. It is optional attribute and its default value is SINGLE. Each Hazelcast inbound channel adapter which listens same cache object with same cache-events attribute, can receive a single event message or all event messages. If this is ALL, all Hazelcast inbound channel adapters which listens same cache object with same cache-events attribute, will receive same event messages. If this is SINGLE, they will receive unique event messages.
Sample namespace and schemaLocation definitions are as follows :
```
xmlns:int-hazelcast= “http://www.springframework.org/schema/integration/hazelcast”
xsi:schemaLocation="http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd”
```
Sample definitions are as follows :
**Distributed Map :**
```
<int:channel id="mapChannel"/>
<int-hazelcast:inbound-channel-adapter channel="mapChannel"
cache="map"
cache-events="UPDATED, REMOVED" />
<bean id="map" factory-bean="instance" factory-method="getMap">
<constructor-arg value="map"/>
</bean>
<bean id="instance" class="com.hazelcast.core.Hazelcast"
factory-method="newHazelcastInstance">
<constructor-arg>
<bean class="com.hazelcast.config.Config" />
</constructor-arg>
</bean>
```
**Distributed MultiMap :**
```
<int:channel id="multiMapChannel"/>
<int-hazelcast:inbound-channel-adapter channel="multiMapChannel"
cache="multiMap"
cache-events="ADDED,
REMOVED,
CLEAR_ALL" />
<bean id="multiMap" factory-bean="instance" factory-method="getMultiMap">
<constructor-arg value="multiMap"/>
</bean>
```
**Distributed List :**
```
<int:channel id="listChannel"/>
<int-hazelcast:inbound-channel-adapter channel="listChannel"
cache="list"
cache-events="ADDED, REMOVED"
cache-listening-policy="ALL" />
<bean id="list" factory-bean="instance" factory-method="getList">
<constructor-arg value="list"/>
</bean>
```
**Distributed Set :**
```
<int:channel id="setChannel"/>
<int-hazelcast:inbound-channel-adapter channel="setChannel" cache="set" />
<bean id="set" factory-bean="instance" factory-method="getSet">
<constructor-arg value="set"/>
</bean>
```
**Distributed Queue :**
```
<int:channel id="queueChannel"/>
<int-hazelcast:inbound-channel-adapter channel="queueChannel"
cache="queue"
cache-events="REMOVED"
cache-listening-policy="ALL" />
<bean id="queue" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="queue"/>
</bean>
```
**Distributed Topic :**
```
<int:channel id="topicChannel"/>
<int-hazelcast:inbound-channel-adapter channel="topicChannel" cache="topic" />
<bean id="topic" factory-bean="instance" factory-method="getTopic">
<constructor-arg value="topic"/>
</bean>
```
**Replicated Map :**
```
<int:channel id="replicatedMapChannel"/>
<int-hazelcast:inbound-channel-adapter channel="replicatedMapChannel"
cache="replicatedMap"
cache-events="ADDED,UPDATED, REMOVED"
cache-listening-policy="SINGLE" />
<bean id="replicatedMap" factory-bean="instance" factory-method="getReplicatedMap">
<constructor-arg value="replicatedMap"/>
</bean>
<bean id="instance" class="com.hazelcast.core.Hazelcast"
factory-method="newHazelcastInstance">
<constructor-arg>
<bean class="com.hazelcast.config.Config" />
</constructor-arg>
</bean>
```
**Reference :** http://docs.hazelcast.org/docs/3.4/manual/html-single/hazelcast-documentation.html#distributed-data-structures
## HAZELCAST CONTINUOUS QUERY INBOUND CHANNEL ADAPTER
Hazelcast Continuous Query enables to listen to the modifications performed on specific map entries. Hazelcast Continuous Query Inbound Channel Adapter is an event-driven inbound channel adapter and listens related distributed map events in the light of defined predicate. Its basic definition is as follows :
```
<int-hazelcast:cq-inbound-channel-adapter
channel="cqMapChannel"
cache="cqMap"
cache-events="UPDATED, REMOVED"
predicate="name=TestName AND surname=TestSurname" />
```
Basically, it requires four attributes as follows :
* **channel :** Specifies channel which message is sent. It is mandatory attribute.
* **cache :** Specifies distributed Map reference which is listened. It is mandatory attribute.
* **cache-events :** Specifies cache events which are listened. It is optional attribute with ADDED default value. Supported values are ADDED, REMOVED, UPDATED, EVICTED, EVICT_ALL and CLEAR_ALL.
* **predicate :** Specifies predicate to listen to the modifications performed on specific map entries. It is mandatory attribute.
Sample definition is as follows :
```
<int:channel id="cqMapChannel"/>
<int-hazelcast:cq-inbound-channel-adapter
channel="cqMapChannel"
cache="cqMap"
cache-events="UPDATED, REMOVED"
predicate="name=TestName AND surname=TestSurname"/>
<bean id="cqMap" factory-bean="instance" factory-method="getMap">
<constructor-arg value="cqMap"/>
</bean>
<bean id="instance" class="com.hazelcast.core.Hazelcast"
factory-method="newHazelcastInstance">
<constructor-arg>
<bean class="com.hazelcast.config.Config" />
</constructor-arg>
</bean>
```
**Reference :** http://docs.hazelcast.org/docs/3.4/manual/html-single/hazelcast-documentation.html#continuous-query
## HAZELCAST DISTRIBUTED-SQL INBOUND CHANNEL ADAPTER
Hazelcast allows to run distributed queries on the distributed map. Hazelcast Distributed SQL Inbound Channel Adapter is a poller-driven inbound channel adapter. It runs defined distributed-sql and returns results in the light of iteration type. Its basic definition is as follows :
```
<int-hazelcast:ds-inbound-channel-adapter
channel="dsMapChannel"
cache="dsMap"
iteration-type="ENTRY"
distributed-sql="active=false OR age >= 25 OR name = 'TestName'">
<int:poller cron="*/10 * * * * *"/>
</int-hazelcast:ds-inbound-channel-adapter>
```
Basically, it requires a poller and four attributes such as
* **channel :** Specifies channel which message is sent. It is mandatory attribute.
* **cache :** Specifies distributed Map reference which is queried. It is mandatory attribute.
* **iteration-type :** Specifies result type. Distributed SQL can be run on EntrySet, KeySet, LocalKeySet or Values. It is optional attribute with VALUE default value. Supported values are ENTRY, KEY, LOCAL_KEY and VALUE.
* **distributed-sql :** Specifies where clause of sql statement. It is mandatory attribute.
Sample definition is as follows :
```
<int:channel id="dsMapChannel"/>
<int-hazelcast:ds-inbound-channel-adapter
channel="dsMapChannel"
cache="dsMap"
iteration-type="ENTRY"
distributed-sql="active=false OR age >= 25 OR name = 'TestName'">
<int:poller cron="*/10 * * * * *"/>
</int-hazelcast:ds-inbound-channel-adapter>
<bean id="dsMap" factory-bean="instance" factory-method="getMap">
<constructor-arg value="dsMap"/>
</bean>
<bean id="instance" class="com.hazelcast.core.Hazelcast"
factory-method="newHazelcastInstance">
<constructor-arg>
<bean class="com.hazelcast.config.Config" />
</constructor-arg>
</bean>
```
**Reference :** http://docs.hazelcast.org/docs/3.4/manual/html-single/hazelcast-documentation.html#query-overview
## HAZELCAST OUTBOUND CHANNEL ADAPTER
Hazelcast Outbound Channel Adapter listens its defined channel and writes incoming messages to related distributed cache. It expects one of java.util.Map, List, Set and Queue data structures in incoming message's payload. Its definition is as follows :
```
<int-hazelcast:outbound-channel-adapter channel="mapChannel" cache="distributedMap" />
```
Basically, it requires two attributes as follows :
* **channel :** Specifies channel which message is sent. It is mandatory attribute.
* **cache :** Specifies distributed Map reference which is queried. It is mandatory attribute.
**Case 1-** If incoming messages need to be written to distributed map(com.hazelcast.core.IMap), Message should have java.util.Map payload. Sample definition should be as follows :
```
<int:channel id="mapChannel"/>
<int-hazelcast:outbound-channel-adapter channel="mapChannel" cache="distributedMap" />
<bean id="distributedMap" factory-bean="instance" factory-method="getMap">
<constructor-arg value="distributedMap"/>
</bean>
<bean id="instance" class="com.hazelcast.core.Hazelcast"
factory-method="newHazelcastInstance">
<constructor-arg>
<bean class="com.hazelcast.config.Config" />
</constructor-arg>
</bean>
```
**Case 2-** If incoming messages need to be written to distributed list(com.hazelcast.core.IList), Message should have java.util.List payload. Sample definition should be as follows :
```
<int:channel id="listChannel"/>
<int-hazelcast:outbound-channel-adapter channel="listChannel" cache="distributedList" />
<bean id="distributedList" factory-bean="instance" factory-method="getList">
<constructor-arg value="distributedList"/>
</bean>
```
**Case 3-** If incoming messages need to be written to distributed set(com.hazelcast.core.ISet), Message should have java.util.Set payload. Sample definition should be as follows :
```
<int:channel id="setChannel"/>
<int-hazelcast:outbound-channel-adapter channel="setChannel" cache="distributedSet" />
<bean id="distributedSet" factory-bean="instance" factory-method="getSet">
<constructor-arg value="distributedSet"/>
</bean>
```
**Case 4-** If incoming messages need to be written to distributed queue(com.hazelcast.core.IQueue), Message should have java.util.Queue payload. Sample definition should be as follows :
```
<int:channel id="queueChannel"/>
<int-hazelcast:outbound-channel-adapter channel="queueChannel" cache="distributedQueue" />
<bean id="distributedQueue" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="distributedQueue"/>
</bean>
```

View File

@@ -0,0 +1,226 @@
description = 'Spring Integration Hazelcast Support'
apply plugin: 'java'
apply from: "${rootProject.projectDir}/publish-maven.gradle"
apply plugin: 'eclipse'
apply plugin: 'idea'
group = 'org.springframework.integration'
repositories {
maven { url 'http://repo.spring.io/libs-milestone' }
}
sourceCompatibility = targetCompatibility = 1.7
ext {
hazelcastVersion = '3.4.2'
jacocoVersion = '0.7.2.201409121644'
slf4jVersion = '1.7.10'
springIntegrationVersion = '4.1.2.RELEASE'
idPrefix = 'hazelcast'
linkHomepage = 'https://github.com/spring-projects/spring-integration-extensions'
linkCi = 'https://build.spring.io/browse/INTEXT'
linkIssue = 'https://jira.spring.io/browse/INTEXT'
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']
}
}
}
configurations {
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
}
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"
jacoco "org.jacoco:org.jacoco.agent:$jacocoVersion:runtime"
}
// enable all compiler warnings; individual projects may customize further
[compileJava, compileTestJava]*.options*.compilerArgs = ['-Xlint:all,-options']
test {
// suppress all console output during testing unless running `gradle -i`
logging.captureStandardOutput(LogLevel.INFO)
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=*",
"-Dhazelcast.logging.type=slf4j"
}
task sourcesJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.allJava
}
task javadocJar(type: Jar) {
classifier = 'javadoc'
from javadoc
}
artifacts {
archives sourcesJar
archives javadocJar
}
apply plugin: 'sonar-runner'
sonarRunner {
sonarProperties {
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'
classifier = 'schema'
description = "Builds -${classifier} 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'
classifier = 'docs'
description = "Builds -${classifier} 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'
classifier = 'dist'
description = "Builds -${classifier} 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.archivePath)) {
into "${baseDir}/docs"
}
from(zipTree(schemaZip.archivePath)) {
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'
classifier = 'dist-with-deps'
description = "Builds -${classifier} archive, containing everything " +
"in the -${distZip.classifier} archive plus all dependencies."
from zipTree(distZip.archivePath)
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.'
}
task wrapper(type: Wrapper) {
description = 'Generates gradlew[.bat] scripts'
gradleVersion = '2.3'
distributionUrl = "http://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"
}

View File

@@ -0,0 +1 @@
version=1.0.0-BUILD-SNAPSHOT

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Thu Mar 19 00:10:16 GMT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-2.3-all.zip

164
spring-integration-hazelcast/gradlew vendored Executable file
View File

@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# 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
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# 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\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
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" ] ; 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, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# 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=$((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
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

View File

@@ -0,0 +1,90 @@
@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
@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=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@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 init
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 init
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
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
: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 %CMD_LINE_ARGS%
: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

@@ -0,0 +1,62 @@
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 ->
// 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 = linkHomepage
organization {
name = 'SpringIO'
url = 'http://spring.io'
}
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution 'repo'
}
}
scm {
url = linkScmUrl
connection = 'scm:git:' + linkScmConnection
developerConnection = 'scm:git:' + linkScmDevConnection
}
developers {
developer {
id = 'erenavsarogullari'
name = 'Eren Avsarogullari'
email = 'erenavsarogullari@gmail.com'
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,22 @@
<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="http://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="http://spring.io/" target="_top">
http://spring.io</a>
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,598 @@
/* 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

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,21 @@
========================================================================
== 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 (http://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 (http://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

@@ -0,0 +1,30 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.common;
/**
* Enumeration of Cache Event Types
*
* @author Eren Avsarogullari
* @since 1.0.0
* @see org.springframework.integration.hazelcast.inbound.AbstractHazelcastMessageProducer
*/
public enum CacheEventType {
ADDED, REMOVED, UPDATED, EVICTED, EVICT_ALL, CLEAR_ALL;
}

View File

@@ -0,0 +1,30 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.common;
/**
* Enumeration of Cache Listening Policy Type
*
* @author Eren Avsarogullari
* @since 1.0.0
* @see org.springframework.integration.hazelcast.inbound.AbstractHazelcastMessageProducer
*/
public enum CacheListeningPolicyType {
SINGLE, ALL;
}

View File

@@ -0,0 +1,30 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.common;
/**
* Enumeration of Distributed SQL Iteration Type
*
* @author Eren Avsarogullari
* @since 1.0.0
* @see org.springframework.integration.hazelcast.inbound.HazelcastDistributedSQLMessageSource
*/
public enum DistributedSQLIterationType {
ENTRY, KEY, LOCAL_KEY, VALUE
}

View File

@@ -0,0 +1,112 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.common;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.IList;
import com.hazelcast.core.IMap;
import com.hazelcast.core.IQueue;
import com.hazelcast.core.ISet;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.MultiMap;
import com.hazelcast.core.ReplicatedMap;
import reactor.util.CollectionUtils;
import reactor.util.StringUtils;
/**
* Common Validator for Hazelcast Integration. It validates cache types and events.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastIntegrationDefinitionValidator {
public static <E extends Enum<E>> void validateEnumType(final Class<E> enumType, final String cacheEventTypes) {
Set<String> eventTypeSet = StringUtils.commaDelimitedListToSet(cacheEventTypes);
for (String eventType : eventTypeSet) {
Enum.valueOf(enumType, eventType);
}
}
public static void validateCacheTypeForEventDrivenMessageProducer(final DistributedObject distributedObject) {
if (!(distributedObject instanceof IMap
|| distributedObject instanceof MultiMap
|| distributedObject instanceof ReplicatedMap
|| distributedObject instanceof IList
|| distributedObject instanceof ISet
|| distributedObject instanceof IQueue
|| distributedObject instanceof ITopic)) {
throw new IllegalArgumentException(
"Invalid 'cache' type is set. IMap, MultiMap, ReplicatedMap, IList, ISet, IQueue and ITopic" +
" cache object types are acceptable for Hazelcast Inbound Channel Adapter.");
}
}
public static void validateCacheTypeForCacheWritingMessageHandler(final DistributedObject distributedObject) {
if (!(distributedObject instanceof IMap
|| distributedObject instanceof IList
|| distributedObject instanceof ISet
|| distributedObject instanceof IQueue)) {
throw new IllegalArgumentException(
"Invalid 'cache' type is set. IMap, IList, ISet and IQueue cache object types are acceptable "
+ "for Hazelcast Outbound Channel Adapter.");
}
}
public static void validateCacheEventsByDistributedObject(
final DistributedObject distributedObject, final Set<String> cacheEventTypeSet) {
List<String> supportedCacheEventTypes = getSupportedCacheEventTypes(distributedObject);
if (!CollectionUtils.isEmpty(supportedCacheEventTypes)) {
validateCacheEventsByDistributedObject(distributedObject, cacheEventTypeSet, supportedCacheEventTypes);
}
}
private static List<String> getSupportedCacheEventTypes(final DistributedObject distributedObject) {
if ((distributedObject instanceof IList)
|| (distributedObject instanceof ISet)
|| (distributedObject instanceof IQueue)) {
return Arrays.asList(CacheEventType.ADDED.toString(), CacheEventType.REMOVED.toString());
}
else if (distributedObject instanceof MultiMap) {
return Arrays.asList(CacheEventType.ADDED.toString(),
CacheEventType.REMOVED.toString(),
CacheEventType.CLEAR_ALL.toString());
}
else if (distributedObject instanceof ReplicatedMap) {
return Arrays.asList(CacheEventType.ADDED.toString(),
CacheEventType.REMOVED.toString(),
CacheEventType.UPDATED.toString(),
CacheEventType.EVICTED.toString());
}
return null;
}
private static void validateCacheEventsByDistributedObject(DistributedObject distributedObject,
Set<String> cacheEventTypeSet, List<String> supportedCacheEventTypes) {
if (!supportedCacheEventTypes.containsAll(cacheEventTypeSet)) {
throw new IllegalArgumentException("'cache-events' attribute of "
+ distributedObject.getName() + " can be set as " + supportedCacheEventTypes);
}
}
}

View File

@@ -0,0 +1,78 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.common;
import java.net.SocketAddress;
import java.util.concurrent.locks.Lock;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.integration.hazelcast.listener.HazelcastMembershipListener;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.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
* also enables a Hazelcast {@link com.hazelcast.core.MembershipListener} to listen for
* membership updates.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastLocalInstanceRegistrar implements SmartInitializingSingleton {
public static final String SPRING_INTEGRATION_INTERNAL_CLUSTER_MULTIMAP =
"SPRING_INTEGRATION_INTERNAL_CLUSTER_MULTIMAP";
public static final String SPRING_INTEGRATION_INTERNAL_CLUSTER_LOCK = "SPRING_INTEGRATION_INTERNAL_CLUSTER_LOCK";
@Override
public void afterSingletonsInstantiated() {
if (!Hazelcast.getAllHazelcastInstances().isEmpty()) {
HazelcastInstance hazelcastInstance = Hazelcast.getAllHazelcastInstances().iterator().next();
hazelcastInstance.getCluster().addMembershipListener(new HazelcastMembershipListener());
syncConfigurationMultiMap(hazelcastInstance);
}
else {
throw new IllegalStateException("No Active Local Hazelcast Instance found.");
}
}
private void syncConfigurationMultiMap(HazelcastInstance hazelcastInstance) {
Lock lock = hazelcastInstance.getLock(SPRING_INTEGRATION_INTERNAL_CLUSTER_LOCK);
lock.lock();
try {
MultiMap<SocketAddress, SocketAddress> multiMap = hazelcastInstance
.getMultiMap(SPRING_INTEGRATION_INTERNAL_CLUSTER_MULTIMAP);
for (HazelcastInstance localInstance : Hazelcast.getAllHazelcastInstances()) {
SocketAddress localInstanceSocketAddress = localInstance.getLocalEndpoint().getSocketAddress();
if (multiMap.size() == 0) {
multiMap.put(localInstanceSocketAddress, localInstanceSocketAddress);
}
else {
multiMap.put(multiMap.keySet().iterator().next(), localInstanceSocketAddress);
}
}
}
finally {
lock.unlock();
}
}
}

View File

@@ -0,0 +1,4 @@
/**
* Provides common used types and classes.
*/
package org.springframework.integration.hazelcast.common;

View File

@@ -0,0 +1,46 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.integration.config.IntegrationConfigurationInitializer;
import org.springframework.integration.hazelcast.common.HazelcastLocalInstanceRegistrar;
/**
* The Hazelcast Integration infrastructure {@code beanFactory} initializer.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastIntegrationConfigurationInitializer implements IntegrationConfigurationInitializer {
private static final String HAZELCAST_LOCAL_INSTANCE_REGISTRAR_BEAN_NAME =
HazelcastLocalInstanceRegistrar.class.getName();
@Override
public void initialize(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
if (!beanDefinitionRegistry.containsBeanDefinition(HAZELCAST_LOCAL_INSTANCE_REGISTRAR_BEAN_NAME)) {
beanDefinitionRegistry.registerBeanDefinition(HAZELCAST_LOCAL_INSTANCE_REGISTRAR_BEAN_NAME,
new RootBeanDefinition(HazelcastLocalInstanceRegistrar.class));
}
}
}

View File

@@ -0,0 +1,4 @@
/**
* Provides classes for configuration.
*/
package org.springframework.integration.hazelcast.config;

View File

@@ -0,0 +1,109 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.hazelcast.inbound.HazelcastContinuousQueryMessageProducer;
import reactor.util.StringUtils;
/**
* Hazelcast Continuous Query Inbound Channel Adapter Parser parses
* {@code <int-hazelcast:cq-inbound-channel-adapter/>} configuration.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastContinuousQueryInboundChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
private static final String CHANNEL_ATTRIBUTE = "channel";
private static final String CACHE_ATTRIBUTE = "cache";
private static final String CACHE_EVENTS_ATTRIBUTE = "cache-events";
private static final String PREDICATE_ATTRIBUTE = "predicate";
private static final String INCLUDE_VALUE_ATTRIBUTE = "include-value";
private static final String CACHE_LISTENING_POLICY_ATTRIBUTE = "cache-listening-policy";
private static final String OUTPUT_CHANNEL = "outputChannel";
private static final String CACHE_EVENT_TYPES = "cacheEventTypes";
@Override
protected Class<?> getBeanClass(Element element) {
return HazelcastContinuousQueryMessageProducer.class;
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
String id = super.resolveId(element, definition, parserContext);
if (!element.hasAttribute(CHANNEL_ATTRIBUTE)) {
id = id + ".adapter";
}
if (!StringUtils.hasText(id)) {
id = BeanDefinitionReaderUtils.generateBeanName(definition, parserContext.getRegistry());
}
return id;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String channelName = element.getAttribute(CHANNEL_ATTRIBUTE);
if (!StringUtils.hasText(channelName)) {
channelName = IntegrationNamespaceUtils.createDirectChannel(element, parserContext);
}
if (!StringUtils.hasText(element.getAttribute(CACHE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_ATTRIBUTE + "' attribute is required.", element);
}
else if (!StringUtils.hasText(element.getAttribute(CACHE_EVENTS_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_EVENTS_ATTRIBUTE + "' attribute is required.", element);
}
else if (!StringUtils.hasText(element.getAttribute(PREDICATE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + PREDICATE_ATTRIBUTE + "' attribute is required.", element);
}
else if (!StringUtils.hasText(element.getAttribute(CACHE_LISTENING_POLICY_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_LISTENING_POLICY_ATTRIBUTE + "' attribute is required.",
element);
}
builder.addPropertyReference(OUTPUT_CHANNEL, channelName);
builder.addConstructorArgReference(element.getAttribute(CACHE_ATTRIBUTE));
builder.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);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.AUTO_STARTUP);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.PHASE);
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.hazelcast.inbound.HazelcastDistributedSQLMessageSource;
import reactor.util.StringUtils;
/**
* Hazelcast Distributed SQL Inbound Channel Adapter Parser parses
* {@code <int-hazelcast:cq-inbound-channel-adapter/>} configuration.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastDistributedSQLInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
private static final String CACHE_ATTRIBUTE = "cache";
private static final String DISTRIBUTED_SQL_ATTRIBUTE = "distributed-sql";
private static final String ITERATION_TYPE_ATTRIBUTE = "iteration-type";
@Override
protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
if (!StringUtils.hasText(element.getAttribute(CACHE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_ATTRIBUTE + "' attribute is required.", element);
}
else if (!StringUtils.hasText(element.getAttribute(DISTRIBUTED_SQL_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + DISTRIBUTED_SQL_ATTRIBUTE + "' attribute is required.",
element);
}
else if (!StringUtils.hasText(element.getAttribute(ITERATION_TYPE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + ITERATION_TYPE_ATTRIBUTE + "' attribute is required.",
element);
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(HazelcastDistributedSQLMessageSource.class.getName());
builder.addConstructorArgReference(element.getAttribute(CACHE_ATTRIBUTE));
builder.addConstructorArgValue(element.getAttribute(DISTRIBUTED_SQL_ATTRIBUTE));
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, ITERATION_TYPE_ATTRIBUTE);
return builder.getBeanDefinition();
}
}

View File

@@ -0,0 +1,100 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.hazelcast.inbound.HazelcastEventDrivenMessageProducer;
import reactor.util.StringUtils;
/**
* Hazelcast Event Driven Inbound Channel Adapter Parser parses
* {@code <int-hazelcast:inbound-channel-adapter />} configuration.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastEventDrivenInboundChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
private static final String CHANNEL_ATTRIBUTE = "channel";
private static final String CACHE_ATTRIBUTE = "cache";
private static final String CACHE_EVENTS_ATTRIBUTE = "cache-events";
private static final String CACHE_LISTENING_POLICY_ATTRIBUTE = "cache-listening-policy";
private static final String OUTPUT_CHANNEL = "outputChannel";
private static final String CACHE_EVENT_TYPES = "cacheEventTypes";
@Override
protected Class<?> getBeanClass(Element element) {
return HazelcastEventDrivenMessageProducer.class;
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
String id = super.resolveId(element, definition, parserContext);
if (!element.hasAttribute(CHANNEL_ATTRIBUTE)) {
id = id + ".adapter";
}
if (!StringUtils.hasText(id)) {
id = BeanDefinitionReaderUtils.generateBeanName(definition, parserContext.getRegistry());
}
return id;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String channelName = element.getAttribute(CHANNEL_ATTRIBUTE);
if (!StringUtils.hasText(channelName)) {
channelName = IntegrationNamespaceUtils.createDirectChannel(element, parserContext);
}
if (!StringUtils.hasText(element.getAttribute(CACHE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_ATTRIBUTE + "' attribute is required.", element);
}
else if (!StringUtils.hasText(element.getAttribute(CACHE_EVENTS_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_EVENTS_ATTRIBUTE + "' attribute is required.", element);
}
else if (!StringUtils.hasText(element.getAttribute(CACHE_LISTENING_POLICY_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_LISTENING_POLICY_ATTRIBUTE + "' attribute is required.",
element);
}
builder.addPropertyReference(OUTPUT_CHANNEL, channelName);
builder.addConstructorArgReference(element.getAttribute(CACHE_ATTRIBUTE));
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, CACHE_EVENTS_ATTRIBUTE, CACHE_EVENT_TYPES);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, CACHE_LISTENING_POLICY_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.AUTO_STARTUP);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.PHASE);
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.config.xml;
import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
/**
* Namespace handler for the Hazelcast schema.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastIntegrationNamespaceHandler extends AbstractIntegrationNamespaceHandler {
@Override
public void init() {
registerBeanDefinitionParser("inbound-channel-adapter", new HazelcastEventDrivenInboundChannelAdapterParser());
registerBeanDefinitionParser("outbound-channel-adapter", new HazelcastOutboundChannelAdapterParser());
registerBeanDefinitionParser("cq-inbound-channel-adapter", new HazelcastContinuousQueryInboundChannelAdapterParser());
registerBeanDefinitionParser("ds-inbound-channel-adapter", new HazelcastDistributedSQLInboundChannelAdapterParser());
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.hazelcast.outbound.HazelcastCacheWritingMessageHandler;
import reactor.util.StringUtils;
/**
* Hazelcast Outbound Channel Adapter Parser for {@code <int-hazelcast:inbound-channel-adapter />}.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
private static final String CACHE_ATTRIBUTE = "cache";
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(HazelcastCacheWritingMessageHandler.class);
if (!StringUtils.hasText(element.getAttribute(CACHE_ATTRIBUTE))) {
parserContext.getReaderContext().error("'" + CACHE_ATTRIBUTE + "' attribute is required.", element);
}
builder.addConstructorArgReference(element.getAttribute(CACHE_ATTRIBUTE));
return builder.getBeanDefinition();
}
}

View File

@@ -0,0 +1,4 @@
/**
* Provides classes for parsers and namespace handlers.
*/
package org.springframework.integration.hazelcast.config.xml;

View File

@@ -0,0 +1,191 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashSet;
import java.util.Set;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.hazelcast.common.CacheEventType;
import org.springframework.integration.hazelcast.common.CacheListeningPolicyType;
import org.springframework.integration.hazelcast.common.HazelcastIntegrationDefinitionValidator;
import org.springframework.integration.hazelcast.common.HazelcastLocalInstanceRegistrar;
import org.springframework.util.Assert;
import com.hazelcast.core.AbstractIMapEvent;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.MapEvent;
import com.hazelcast.core.MultiMap;
import reactor.util.StringUtils;
/**
* Hazelcast Base Event-Driven Message Producer.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public abstract class AbstractHazelcastMessageProducer extends MessageProducerSupport {
protected final DistributedObject distributedObject;
private CacheListeningPolicyType cacheListeningPolicy = CacheListeningPolicyType.SINGLE;
private String hazelcastRegisteredEventListenerId;
private Set<String> cacheEvents = Collections.singleton(CacheEventType.ADDED.name());
protected AbstractHazelcastMessageProducer(DistributedObject distributedObject) {
Assert.notNull(distributedObject, "cache must not be null");
this.distributedObject = distributedObject;
}
protected Set<String> getCacheEvents() {
return cacheEvents;
}
public void setCacheEventTypes(String cacheEventTypes) {
HazelcastIntegrationDefinitionValidator.validateEnumType(CacheEventType.class, cacheEventTypes);
final Set<String> cacheEvents = StringUtils.commaDelimitedListToSet(cacheEventTypes);
Assert.notEmpty(cacheEvents, "cacheEvents must have elements");
HazelcastIntegrationDefinitionValidator.validateCacheEventsByDistributedObject(
this.distributedObject, cacheEvents);
this.cacheEvents = cacheEvents;
}
protected CacheListeningPolicyType getCacheListeningPolicy() {
return cacheListeningPolicy;
}
public void setCacheListeningPolicy(CacheListeningPolicyType cacheListeningPolicy) {
Assert.notNull(cacheListeningPolicy, "cacheListeningPolicy must not be null");
this.cacheListeningPolicy = cacheListeningPolicy;
}
protected String getHazelcastRegisteredEventListenerId() {
return hazelcastRegisteredEventListenerId;
}
protected void setHazelcastRegisteredEventListenerId(String hazelcastRegisteredEventListenerId) {
this.hazelcastRegisteredEventListenerId = hazelcastRegisteredEventListenerId;
}
protected abstract class AbstractHazelcastEventListener {
protected abstract void processEvent(EventObject event);
protected void sendMessage(final EventObject event, final InetSocketAddress socketAddress,
final CacheListeningPolicyType cacheListeningPolicyType) {
if (CacheListeningPolicyType.ALL == cacheListeningPolicyType || isEventAcceptable(socketAddress)) {
AbstractHazelcastMessageProducer.this.sendMessage(getMessageBuilderFactory().withPayload(event).build());
}
}
private boolean isEventAcceptable(final InetSocketAddress socketAddress) {
final Set<HazelcastInstance> hazelcastInstanceSet = Hazelcast.getAllHazelcastInstances();
final Set<SocketAddress> localSocketAddressesSet = getLocalSocketAddresses(hazelcastInstanceSet);
if ((!localSocketAddressesSet.isEmpty())
&& (localSocketAddressesSet.contains(socketAddress) ||
isEventComingFromNonRegisteredHazelcastInstance(hazelcastInstanceSet.iterator().next(),
localSocketAddressesSet, socketAddress))) {
return true;
}
return false;
}
private Set<SocketAddress> getLocalSocketAddresses(final Set<HazelcastInstance> hazelcastInstanceSet) {
final Set<SocketAddress> localSocketAddressesSet = new HashSet<>();
for (HazelcastInstance hazelcastInstance : hazelcastInstanceSet) {
localSocketAddressesSet.add(hazelcastInstance.getLocalEndpoint().getSocketAddress());
}
return localSocketAddressesSet;
}
private boolean isEventComingFromNonRegisteredHazelcastInstance(
final HazelcastInstance hazelcastInstance,
final Set<SocketAddress> localSocketAddressesSet,
final InetSocketAddress socketAddressOfEvent) {
final MultiMap<SocketAddress, SocketAddress> configMultiMap = hazelcastInstance
.getMultiMap(HazelcastLocalInstanceRegistrar.SPRING_INTEGRATION_INTERNAL_CLUSTER_MULTIMAP);
return configMultiMap.size() > 0
&& !configMultiMap.values().contains(socketAddressOfEvent)
&& localSocketAddressesSet.contains(configMultiMap.keySet().iterator().next());
}
}
protected final class HazelcastEntryListener<K, V> extends
AbstractHazelcastEventListener implements EntryListener<K, V> {
@Override
public void entryAdded(EntryEvent<K, V> event) {
processEvent(event);
}
@Override
public void entryRemoved(EntryEvent<K, V> event) {
processEvent(event);
}
@Override
public void entryUpdated(EntryEvent<K, V> event) {
processEvent(event);
}
@Override
public void entryEvicted(EntryEvent<K, V> event) {
processEvent(event);
}
@Override
public void mapEvicted(MapEvent event) {
processEvent(event);
}
@Override
public void mapCleared(MapEvent event) {
processEvent(event);
}
@Override
protected void processEvent(EventObject event) {
Assert.notNull(event, "event must not be null");
if (getCacheEvents().contains(((AbstractIMapEvent) event).getEventType().toString())) {
sendMessage(event, ((AbstractIMapEvent) event).getMember().getSocketAddress(),
getCacheListeningPolicy());
}
if (logger.isDebugEnabled()) {
logger.debug("Received Event : " + event);
}
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import org.springframework.util.Assert;
import com.hazelcast.core.IMap;
import com.hazelcast.query.SqlPredicate;
/**
* Hazelcast Continuous Query Message Producer is a message producer which enables
* {@link AbstractHazelcastMessageProducer.HazelcastEntryListener} with a
* {@link SqlPredicate} in order to listen related distributed map events in the light of
* defined predicate and sends events to related channel.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastContinuousQueryMessageProducer extends AbstractHazelcastMessageProducer {
private final String predicate;
private boolean includeValue = true;
@SuppressWarnings("rawtypes")
public HazelcastContinuousQueryMessageProducer(IMap distributedMap, String predicate) {
super(distributedMap);
Assert.hasText(predicate, "predicate must not be null");
this.predicate = predicate;
}
public void setIncludeValue(boolean includeValue) {
this.includeValue = includeValue;
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
protected void doStart() {
setHazelcastRegisteredEventListenerId(((IMap<?, ?>) this.distributedObject)
.addEntryListener(new HazelcastEntryListener(), new SqlPredicate(this.predicate), this.includeValue));
}
@Override
protected void doStop() {
((IMap<?, ?>) this.distributedObject).removeEntryListener(getHazelcastRegisteredEventListenerId());
}
@Override
public String getComponentType() {
return "hazelcast:cq-inbound-channel-adapter";
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import java.util.Collection;
import java.util.Collections;
import org.springframework.integration.endpoint.AbstractMessageSource;
import org.springframework.integration.hazelcast.common.DistributedSQLIterationType;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import com.hazelcast.core.IMap;
import com.hazelcast.query.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
*/
@SuppressWarnings("rawtypes")
public class HazelcastDistributedSQLMessageSource extends AbstractMessageSource {
private final IMap<?, ?> distributedMap;
private final String distributedSQL;
private DistributedSQLIterationType iterationType = DistributedSQLIterationType.VALUE;
public HazelcastDistributedSQLMessageSource(IMap distributedMap, String distributedSQL) {
Assert.notNull(distributedMap, "cache must not be null");
Assert.hasText(distributedSQL, "distributed-sql must not be null");
this.distributedMap = distributedMap;
this.distributedSQL = distributedSQL;
}
public void setIterationType(DistributedSQLIterationType iterationType) {
Assert.notNull(this.iterationType, "iterationType must not be null");
this.iterationType = iterationType;
}
@Override
public String getComponentType() {
return "hazelcast:ds-inbound-channel-adapter";
}
@Override
protected Collection<?> doReceive() {
switch (this.iterationType) {
case ENTRY:
return getDistributedSQLResultSet(Collections
.unmodifiableCollection(this.distributedMap.entrySet(new SqlPredicate(this.distributedSQL))));
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;
}
}

View File

@@ -0,0 +1,168 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import java.util.EventObject;
import org.springframework.integration.hazelcast.common.HazelcastIntegrationDefinitionValidator;
import org.springframework.util.Assert;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.IList;
import com.hazelcast.core.IMap;
import com.hazelcast.core.IQueue;
import com.hazelcast.core.ISet;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.ItemEvent;
import com.hazelcast.core.ItemListener;
import com.hazelcast.core.Message;
import com.hazelcast.core.MessageListener;
import com.hazelcast.core.MultiMap;
import com.hazelcast.core.ReplicatedMap;
/**
* Hazelcast Event Driven Message Producer is a message producer which enables
* {@link AbstractHazelcastMessageProducer.HazelcastEntryListener},
* {@link HazelcastEventDrivenMessageProducer.HazelcastItemListener} and
* {@link HazelcastEventDrivenMessageProducer.HazelcastMessageListener} listeners in order
* to listen related cache events and sends events to related channel.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public class HazelcastEventDrivenMessageProducer extends AbstractHazelcastMessageProducer {
public HazelcastEventDrivenMessageProducer(DistributedObject distributedObject) {
super(distributedObject);
}
@Override
protected void onInit() {
super.onInit();
HazelcastIntegrationDefinitionValidator.validateCacheTypeForEventDrivenMessageProducer(this.distributedObject);
}
@Override
protected void doStart() {
if(this.distributedObject instanceof IMap) {
setHazelcastRegisteredEventListenerId(((IMap<?, ?>) this.distributedObject)
.addEntryListener(new HazelcastEntryListener(), true));
}
else if(this.distributedObject instanceof MultiMap) {
setHazelcastRegisteredEventListenerId(((MultiMap<?, ?>) this.distributedObject)
.addEntryListener(new HazelcastEntryListener(), true));
}
else if(this.distributedObject instanceof ReplicatedMap) {
setHazelcastRegisteredEventListenerId(((ReplicatedMap<?, ?>) this.distributedObject)
.addEntryListener(new HazelcastEntryListener()));
}
else if(this.distributedObject instanceof IList) {
setHazelcastRegisteredEventListenerId(((IList<?>) this.distributedObject)
.addItemListener(new HazelcastItemListener(), true));
}
else if(this.distributedObject instanceof ISet) {
setHazelcastRegisteredEventListenerId(((ISet<?>) this.distributedObject)
.addItemListener(new HazelcastItemListener(), true));
}
else if(this.distributedObject instanceof IQueue) {
setHazelcastRegisteredEventListenerId(((IQueue<?>) this.distributedObject)
.addItemListener(new HazelcastItemListener(), true));
}
else if(this.distributedObject instanceof ITopic) {
setHazelcastRegisteredEventListenerId(((ITopic<?>) this.distributedObject)
.addMessageListener(new HazelcastMessageListener()));
}
}
@Override
protected void doStop() {
if(this.distributedObject instanceof IMap) {
((IMap<?, ?>) this.distributedObject).removeEntryListener(getHazelcastRegisteredEventListenerId());
}
else if(this.distributedObject instanceof MultiMap) {
((MultiMap<?, ?>) this.distributedObject).removeEntryListener(getHazelcastRegisteredEventListenerId());
}
else if(this.distributedObject instanceof ReplicatedMap) {
((ReplicatedMap<?, ?>) this.distributedObject).removeEntryListener(getHazelcastRegisteredEventListenerId());
}
else if(this.distributedObject instanceof IList) {
((IList<?>) this.distributedObject).removeItemListener(getHazelcastRegisteredEventListenerId());
}
else if(this.distributedObject instanceof ISet) {
((ISet<?>) this.distributedObject).removeItemListener(getHazelcastRegisteredEventListenerId());
}
else if(this.distributedObject instanceof IQueue) {
((IQueue<?>) this.distributedObject).removeItemListener(getHazelcastRegisteredEventListenerId());
}
else if(this.distributedObject instanceof ITopic) {
((ITopic<?>) this.distributedObject).removeMessageListener(getHazelcastRegisteredEventListenerId());
}
}
@Override
public String getComponentType() {
return "hazelcast:inbound-channel-adapter";
}
private class HazelcastItemListener<E> extends AbstractHazelcastEventListener implements ItemListener<E> {
@Override
public void itemAdded(ItemEvent<E> item) {
processEvent(item);
}
@Override
public void itemRemoved(ItemEvent<E> item) {
processEvent(item);
}
@Override
protected void processEvent(EventObject event) {
Assert.notNull(event, "event must not be null");
if (getCacheEvents().contains(((ItemEvent<E>) event).getEventType().toString())) {
sendMessage(event, ((ItemEvent<E>) event).getMember().getSocketAddress(), getCacheListeningPolicy());
}
if (logger.isDebugEnabled()){
logger.debug("Received ItemEvent : " + event);
}
}
}
private class HazelcastMessageListener<E> extends AbstractHazelcastEventListener implements MessageListener<E> {
@Override
public void onMessage(Message<E> message) {
processEvent(message);
}
@Override
protected void processEvent(EventObject event) {
Assert.notNull(event, "event must not be null");
sendMessage(event, ((Message<E>) event).getPublishingMember().getSocketAddress(), null);
if (logger.isDebugEnabled()){
logger.debug("Received Message : " + event);
}
}
}
}

View File

@@ -0,0 +1,4 @@
/**
* Provides classes supporting inbound endpoints.
*/
package org.springframework.integration.hazelcast.inbound;

View File

@@ -0,0 +1,83 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.listener;
import java.net.SocketAddress;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import org.springframework.integration.hazelcast.common.HazelcastLocalInstanceRegistrar;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.MembershipAdapter;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MultiMap;
/**
* Hazelcast {@link MembershipAdapter} in order to listen for membership updates in the cluster.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastMembershipListener extends MembershipAdapter {
@Override
public void memberRemoved(MembershipEvent membershipEvent) {
SocketAddress removedMemberSocketAddress = membershipEvent.getMember().getSocketAddress();
Set<HazelcastInstance> hazelcastLocalInstanceSet = Hazelcast.getAllHazelcastInstances();
if (!hazelcastLocalInstanceSet.isEmpty()) {
HazelcastInstance hazelcastInstance = hazelcastLocalInstanceSet.iterator().next();
Lock lock = hazelcastInstance
.getLock(HazelcastLocalInstanceRegistrar.SPRING_INTEGRATION_INTERNAL_CLUSTER_LOCK);
lock.lock();
try {
MultiMap<SocketAddress, SocketAddress> configMultiMap = hazelcastInstance
.getMultiMap(HazelcastLocalInstanceRegistrar.SPRING_INTEGRATION_INTERNAL_CLUSTER_MULTIMAP);
if (configMultiMap.containsKey(removedMemberSocketAddress)) {
SocketAddress newAdminSocketAddress = getNewAdminInstanceSocketAddress(
configMultiMap, removedMemberSocketAddress);
for (SocketAddress socketAddress : configMultiMap.values()) {
if (!socketAddress.equals(removedMemberSocketAddress)) {
configMultiMap.put(newAdminSocketAddress, socketAddress);
}
}
configMultiMap.remove(removedMemberSocketAddress);
}
else {
configMultiMap.remove(configMultiMap.keySet().iterator().next(), removedMemberSocketAddress);
}
}
finally {
lock.unlock();
}
}
}
private SocketAddress getNewAdminInstanceSocketAddress(
MultiMap<SocketAddress, SocketAddress> configMultiMap, SocketAddress removedMemberSocketAddress) {
for (SocketAddress socketAddress : configMultiMap.values()) {
if (!socketAddress.equals(removedMemberSocketAddress)) {
return socketAddress;
}
}
throw new IllegalStateException("No Active Hazelcast Instance Found.");
}
}

View File

@@ -0,0 +1,4 @@
/**
* Provides classes for listeners.
*/
package org.springframework.integration.hazelcast.listener;

View File

@@ -0,0 +1,80 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.outbound;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.hazelcast.common.HazelcastIntegrationDefinitionValidator;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.IList;
import com.hazelcast.core.IMap;
import com.hazelcast.core.IQueue;
import com.hazelcast.core.ISet;
/**
* MessageHandler implementation that writes {@link Message} payload to defined Hazelcast
* distributed cache object. Currently, it supports {@link java.util.Map},
* {@link java.util.List}, {@link java.util.Set} and {@link java.util.Queue} data
* structures.
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastCacheWritingMessageHandler extends AbstractMessageHandler {
private final DistributedObject distributedObject;
public HazelcastCacheWritingMessageHandler(DistributedObject distributedObject) {
Assert.notNull(distributedObject, "cache must not be null");
this.distributedObject = distributedObject;
}
@Override
protected void onInit() throws Exception {
super.onInit();
HazelcastIntegrationDefinitionValidator.validateCacheTypeForCacheWritingMessageHandler(this.distributedObject);
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
writeToCache(message);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void writeToCache(Message<?> message) {
if (this.distributedObject instanceof IMap) {
((IMap<?, ?>) this.distributedObject).putAll((Map) message.getPayload());
}
else if (this.distributedObject instanceof IList) {
((IList<?>) this.distributedObject).addAll((List) message.getPayload());
}
else if (this.distributedObject instanceof ISet) {
((ISet<?>) this.distributedObject).addAll((Set) message.getPayload());
}
else if (this.distributedObject instanceof IQueue) {
((IQueue<?>) this.distributedObject).addAll((Queue) message.getPayload());
}
}
}

View File

@@ -0,0 +1,4 @@
/**
* Provides classes supporting outbound endpoints.
*/
package org.springframework.integration.hazelcast.outbound;

View File

@@ -0,0 +1,2 @@
org.springframework.integration.config.IntegrationConfigurationInitializer=\
org.springframework.integration.hazelcast.config.HazelcastIntegrationConfigurationInitializer

View File

@@ -0,0 +1 @@
http\://www.springframework.org/schema/integration/hazelcast=org.springframework.integration.hazelcast.config.xml.HazelcastIntegrationNamespaceHandler

View File

@@ -0,0 +1,2 @@
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

View File

@@ -0,0 +1,235 @@
<?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="http://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="http://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:all>
<xsd:element name="request-handler-advice-chain" type="integration:handlerAdviceChainType"
minOccurs="0" maxOccurs="1" />
</xsd:all>
<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="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:schema>

View File

@@ -0,0 +1,129 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast;
import java.io.Serializable;
/**
* User Bean for Hazelcast Integration Unit Tests
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
public class HazelcastIntegrationTestUser implements Serializable {
private static final long serialVersionUID = -5357485957528362705L;
private int id;
private String name;
private String surname;
private int age;
public HazelcastIntegrationTestUser(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public HazelcastIntegrationTestUser(int id, String name, String surname, int age) {
this.id = id;
this.name = name;
this.surname = surname;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", surname=" + surname + ", age="
+ age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((surname == null) ? 0 : surname.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
HazelcastIntegrationTestUser other = (HazelcastIntegrationTestUser) obj;
if (age != other.age)
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
}
else if (!name.equals(other.name))
return false;
if (surname == null) {
if (other.surname != null)
return false;
}
else if (!surname.equals(other.surname))
return false;
return true;
}
}

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="cqMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel4">
<int:queue/>
</int:channel>
<int:channel id="cqMapChannel5">
<int:queue/>
</int:channel>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel1" cache="cqDistributedMap1"
predicate="name=TestName1"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel2" cache="cqDistributedMap2" cache-events="REMOVED"
predicate="name=TestName2" include-value="true"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel3" cache="cqDistributedMap3"
cache-events="ADDED,REMOVED,UPDATED,CLEAR_ALL"
predicate="name=TestName1 OR name=TestName2"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel4" cache="cqDistributedMap4" cache-events="UPDATED"
predicate="surname=TestSurname2" include-value="true"/>
<int-hazelcast:cq-inbound-channel-adapter channel="cqMapChannel5" cache="cqDistributedMap5" cache-events="UPDATED"
predicate="surname=TestSurname2" include-value="false"/>
<bean id="cqDistributedMap1" factory-bean="cqInstance" factory-method="getMap">
<constructor-arg value="cqDistributedMap1"/>
</bean>
<bean id="cqDistributedMap2" factory-bean="cqInstance" factory-method="getMap">
<constructor-arg value="cqDistributedMap2"/>
</bean>
<bean id="cqDistributedMap3" factory-bean="cqInstance" factory-method="getMap">
<constructor-arg value="cqDistributedMap3"/>
</bean>
<bean id="cqDistributedMap4" factory-bean="cqInstance" factory-method="getMap">
<constructor-arg value="cqDistributedMap4"/>
</bean>
<bean id="cqDistributedMap5" factory-bean="cqInstance" factory-method="getMap">
<constructor-arg value="cqDistributedMap5"/>
</bean>
<bean id="cqInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,196 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.AbstractIMapEvent;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.core.IMap;
/**
* Hazelcast Continuous Query Inbound Channel Adapter Unit Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastCQDistributedMapInboundChannelAdapterTests {
@Autowired
private PollableChannel cqMapChannel1;
@Autowired
private PollableChannel cqMapChannel2;
@Autowired
private PollableChannel cqMapChannel3;
@Autowired
private PollableChannel cqMapChannel4;
@Autowired
private PollableChannel cqMapChannel5;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap1;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap2;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap3;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap4;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> cqDistributedMap5;
@Test
public void testContinuousQueryForOnlyADDEDEntryEvent() {
cqDistributedMap1.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
cqDistributedMap1.remove(1);
cqDistributedMap1.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg = cqMapChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.ADDED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("cqDistributedMap1",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(1, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testContinuousQueryForOnlyREMOVEDEntryEvent() {
cqDistributedMap2.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
cqDistributedMap2.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
cqDistributedMap2.remove(2);
Message<?> msg = cqMapChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.REMOVED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("cqDistributedMap2",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(2, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getSurname());
}
@Test
public void testContinuousQueryForALLEntryEvent() {
cqDistributedMap3.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = cqMapChannel3.receive(2_000);
verify(msg, "cqDistributedMap3", EntryEventType.ADDED);
cqDistributedMap3.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurnameUpdated"));
msg = cqMapChannel3.receive(2_000);
verify(msg, "cqDistributedMap3", EntryEventType.UPDATED);
cqDistributedMap3.remove(1);
msg = cqMapChannel3.receive(2_000);
verify(msg, "cqDistributedMap3", EntryEventType.REMOVED);
cqDistributedMap3.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
msg = cqMapChannel3.receive(2_000);
verify(msg, "cqDistributedMap3", EntryEventType.ADDED);
cqDistributedMap3.clear();
msg = cqMapChannel3.receive(2_000);
verify(msg, "cqDistributedMap3", EntryEventType.CLEAR_ALL);
}
@Test
public void testContinuousQueryForOnlyUPDATEDEntryEvent() {
cqDistributedMap4.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
cqDistributedMap4.put(1, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg = cqMapChannel4.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.UPDATED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("cqDistributedMap4",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(1, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getSurname());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testContinuousQueryForOnlyUPDATEDEntryEventWhenIncludeValueIsFalse() {
cqDistributedMap5.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
cqDistributedMap5.put(1, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg = cqMapChannel5.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.UPDATED, ((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("cqDistributedMap5", ((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(1, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertNull(((EntryEvent<?, ?>) msg.getPayload()).getOldValue());
Assert.assertNull(((EntryEvent<?, ?>) msg.getPayload()).getValue());
}
private void verify(Message<?> msg, String cacheName, EntryEventType type) {
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof AbstractIMapEvent);
Assert.assertEquals(cacheName, ((AbstractIMapEvent) msg.getPayload()).getName());
Assert.assertEquals(type, ((AbstractIMapEvent) msg.getPayload()).getEventType());
}
}

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="edListChannel1">
<int:queue/>
</int:channel>
<int:channel id="edListChannel2">
<int:queue/>
</int:channel>
<int:channel id="edListChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edListChannel1" cache="edDistributedList1"/>
<int-hazelcast:inbound-channel-adapter channel="edListChannel2" cache="edDistributedList2" cache-events="REMOVED"
cache-listening-policy="SINGLE"/>
<int-hazelcast:inbound-channel-adapter channel="edListChannel3" cache="edDistributedList3"
cache-events="ADDED,REMOVED"/>
<bean id="edDistributedList1" factory-bean="edListInstance" factory-method="getList">
<constructor-arg value="edDistributedList1"/>
</bean>
<bean id="edDistributedList2" factory-bean="edListInstance" factory-method="getList">
<constructor-arg value="edDistributedList2"/>
</bean>
<bean id="edDistributedList3" factory-bean="edListInstance" factory-method="getList">
<constructor-arg value="edDistributedList3"/>
</bean>
<bean id="edListInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,127 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.EntryEventType;
import com.hazelcast.core.IList;
import com.hazelcast.core.ItemEvent;
/**
* Hazelcast Distributed List Event Driven Inbound Channel Adapter Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastDistributedListEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edListChannel1;
@Autowired
private PollableChannel edListChannel2;
@Autowired
private PollableChannel edListChannel3;
@Resource
private IList<HazelcastIntegrationTestUser> edDistributedList1;
@Resource
private IList<HazelcastIntegrationTestUser> edDistributedList2;
@Resource
private IList<HazelcastIntegrationTestUser> edDistributedList3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedList1.add(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edListChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(EntryEventType.ADDED.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getSurname());
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
HazelcastIntegrationTestUser user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedList2.add(user);
edDistributedList2.remove(user);
Message<?> msg = edListChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(EntryEventType.REMOVED.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getSurname());
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastIntegrationTestUser user = new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1");
edDistributedList3.add(user);
Message<?> msg = edListChannel3.receive(2_000);
verify(msg, EntryEventType.ADDED);
edDistributedList3.remove(user);
msg = edListChannel3.receive(2_000);
verify(msg, EntryEventType.REMOVED);
user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedList3.add(user);
msg = edListChannel3.receive(2_000);
verify(msg, EntryEventType.ADDED);
}
private void verify(Message<?> msg, EntryEventType type) {
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(type.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
}
}

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="edMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="edMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="edMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="edMapChannel4">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel1" cache="edDistributedMap1"/>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel2" cache="edDistributedMap2" cache-events="UPDATED"/>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel3" cache="edDistributedMap3" cache-events="REMOVED"
cache-listening-policy="SINGLE"/>
<int-hazelcast:inbound-channel-adapter channel="edMapChannel4" cache="edDistributedMap4"
cache-events="ADDED,REMOVED,UPDATED,CLEAR_ALL"/>
<bean id="edDistributedMap1" factory-bean="edMapInstance" factory-method="getMap">
<constructor-arg value="edDistributedMap1"/>
</bean>
<bean id="edDistributedMap2" factory-bean="edMapInstance" factory-method="getMap">
<constructor-arg value="edDistributedMap2"/>
</bean>
<bean id="edDistributedMap3" factory-bean="edMapInstance" factory-method="getMap">
<constructor-arg value="edDistributedMap3"/>
</bean>
<bean id="edDistributedMap4" factory-bean="edMapInstance" factory-method="getMap">
<constructor-arg value="edDistributedMap4"/>
</bean>
<bean id="edMapInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,173 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.AbstractIMapEvent;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.core.IMap;
/**
* Hazelcast Distributed Map Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastDistributedMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edMapChannel1;
@Autowired
private PollableChannel edMapChannel2;
@Autowired
private PollableChannel edMapChannel3;
@Autowired
private PollableChannel edMapChannel4;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap1;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap2;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap3;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> edDistributedMap4;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedMap1.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edMapChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.ADDED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edDistributedMap1",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(1, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testEventDrivenForOnlyUPDATEDEntryEvent() {
edDistributedMap2.put(2, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edDistributedMap2.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg = edMapChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.UPDATED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edDistributedMap2",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(2, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getSurname());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
edDistributedMap3.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edDistributedMap3.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
edDistributedMap3.remove(2);
Message<?> msg = edMapChannel3.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.REMOVED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edDistributedMap3",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(2, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getSurname());
}
@Test
public void testEventDrivenForALLEntryEvent() {
edDistributedMap4.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edMapChannel4.receive(2_000);
verify(msg, "edDistributedMap4", EntryEventType.ADDED);
edDistributedMap4.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurnameUpdated"));
msg = edMapChannel4.receive(2_000);
verify(msg, "edDistributedMap4", EntryEventType.UPDATED);
edDistributedMap4.remove(1);
msg = edMapChannel4.receive(2_000);
verify(msg, "edDistributedMap4", EntryEventType.REMOVED);
edDistributedMap4.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
msg = edMapChannel4.receive(2_000);
verify(msg, "edDistributedMap4", EntryEventType.ADDED);
edDistributedMap4.clear();
msg = edMapChannel4.receive(2_000);
verify(msg, "edDistributedMap4", EntryEventType.CLEAR_ALL);
}
private void verify(Message<?> msg, String cacheName, EntryEventType type) {
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof AbstractIMapEvent);
Assert.assertEquals(cacheName, ((AbstractIMapEvent) msg.getPayload()).getName());
Assert.assertEquals(type, ((AbstractIMapEvent) msg.getPayload()).getEventType());
}
}

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="edQueueChannel1">
<int:queue/>
</int:channel>
<int:channel id="edQueueChannel2">
<int:queue/>
</int:channel>
<int:channel id="edQueueChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edQueueChannel1" cache="edDistributedQueue1"
cache-listening-policy="SINGLE"/>
<int-hazelcast:inbound-channel-adapter channel="edQueueChannel2" cache="edDistributedQueue2"
cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edQueueChannel3" cache="edDistributedQueue3"
cache-events="ADDED,REMOVED"/>
<bean id="edDistributedQueue1" factory-bean="edQueueInstance" factory-method="getQueue">
<constructor-arg value="edDistributedQueue1"/>
</bean>
<bean id="edDistributedQueue2" factory-bean="edQueueInstance" factory-method="getQueue">
<constructor-arg value="edDistributedQueue2"/>
</bean>
<bean id="edDistributedQueue3" factory-bean="edQueueInstance" factory-method="getQueue">
<constructor-arg value="edDistributedQueue3"/>
</bean>
<bean id="edQueueInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,127 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.EntryEventType;
import com.hazelcast.core.IQueue;
import com.hazelcast.core.ItemEvent;
/**
* Hazelcast Distributed Queue Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastDistributedQueueEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edQueueChannel1;
@Autowired
private PollableChannel edQueueChannel2;
@Autowired
private PollableChannel edQueueChannel3;
@Resource
private IQueue<HazelcastIntegrationTestUser> edDistributedQueue1;
@Resource
private IQueue<HazelcastIntegrationTestUser> edDistributedQueue2;
@Resource
private IQueue<HazelcastIntegrationTestUser> edDistributedQueue3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedQueue1.add(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edQueueChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(EntryEventType.ADDED.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getSurname());
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
HazelcastIntegrationTestUser user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedQueue2.add(user);
edDistributedQueue2.remove(user);
Message<?> msg = edQueueChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(EntryEventType.REMOVED.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getSurname());
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastIntegrationTestUser user = new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1");
edDistributedQueue3.add(user);
Message<?> msg = edQueueChannel3.receive(2_000);
verify(msg, EntryEventType.ADDED);
edDistributedQueue3.remove(user);
msg = edQueueChannel3.receive(2_000);
verify(msg, EntryEventType.REMOVED);
user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedQueue3.add(user);
msg = edQueueChannel3.receive(2_000);
verify(msg, EntryEventType.ADDED);
}
private void verify(Message<?> msg, EntryEventType type) {
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(type.toString(), ((ItemEvent<?>) msg.getPayload())
.getEventType().toString());
}
}

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="dsMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="dsMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="dsMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="dsMapChannel4">
<int:queue/>
</int:channel>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel1" cache="dsDistributedMap1" iteration-type="ENTRY"
distributed-sql="age = 40">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel2" cache="dsDistributedMap2" iteration-type="KEY"
distributed-sql="age > 0 AND age &lt;= 10">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel3" cache="dsDistributedMap3"
iteration-type="LOCAL_KEY" distributed-sql="age > 10 AND age &lt;= 20">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<int-hazelcast:ds-inbound-channel-adapter channel="dsMapChannel4" cache="dsDistributedMap4" iteration-type="VALUE"
distributed-sql="age > 20 AND age &lt;= 30">
<int:poller fixed-delay="100"/>
</int-hazelcast:ds-inbound-channel-adapter>
<bean id="dsDistributedMap1" factory-bean="dsInstance" factory-method="getMap">
<constructor-arg value="dsDistributedMap1"/>
</bean>
<bean id="dsDistributedMap2" factory-bean="dsInstance" factory-method="getMap">
<constructor-arg value="dsDistributedMap2"/>
</bean>
<bean id="dsDistributedMap3" factory-bean="dsInstance" factory-method="getMap">
<constructor-arg value="dsDistributedMap3"/>
</bean>
<bean id="dsDistributedMap4" factory-bean="dsInstance" factory-method="getMap">
<constructor-arg value="dsDistributedMap4"/>
</bean>
<bean id="dsInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,146 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import java.util.Collection;
import java.util.Map;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.IMap;
/**
* Hazelcast Distributed SQL Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastDistributedSQLInboundChannelAdapterTests {
@Autowired
private PollableChannel dsMapChannel1;
@Autowired
private PollableChannel dsMapChannel2;
@Autowired
private PollableChannel dsMapChannel3;
@Autowired
private PollableChannel dsMapChannel4;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap1;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap2;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap3;
@Resource
private IMap<Integer, HazelcastIntegrationTestUser> dsDistributedMap4;
@Test
public void testDistributedSQLForOnlyENTRYIterationType() throws InterruptedException {
dsDistributedMap1.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap1.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap1.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
dsDistributedMap1.put(4, new HazelcastIntegrationTestUser(4, "TestName4", "TestSurname4", 40));
dsDistributedMap1.put(5, new HazelcastIntegrationTestUser(5, "TestName5", "TestSurname5", 50));
Message<?> msg = dsMapChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof Collection);
Assert.assertEquals(4, (((Map.Entry<?, ?>) ((Collection<?>) msg.getPayload()).iterator()
.next()).getKey()));
Assert.assertEquals(4, ((HazelcastIntegrationTestUser) ((Map.Entry<?, ?>) ((Collection<?>) msg.getPayload())
.iterator().next()).getValue()).getId());
Assert.assertEquals("TestName4", ((HazelcastIntegrationTestUser) ((Map.Entry<?, ?>) ((Collection<?>) msg
.getPayload()).iterator().next()).getValue()).getName());
Assert.assertEquals("TestSurname4", ((HazelcastIntegrationTestUser) ((Map.Entry<?, ?>) ((Collection<?>) msg
.getPayload()).iterator().next()).getValue()).getSurname());
}
@Test
public void testDistributedSQLForOnlyKEYIterationType() throws InterruptedException {
dsDistributedMap2.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap2.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap2.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
Message<?> msg = dsMapChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof Collection);
Assert.assertEquals(1, ((Collection<?>) msg.getPayload()).iterator().next());
}
@Test
public void testDistributedSQLForOnlyLOCAL_KEYIterationType()
throws InterruptedException {
dsDistributedMap3.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap3.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap3.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
Message<?> msg = dsMapChannel3.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof Collection);
Assert.assertEquals(2, ((Collection<?>) msg.getPayload()).iterator().next());
}
@Test
public void testDistributedSQLForOnlyVALUEIterationType() throws InterruptedException {
dsDistributedMap4.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1", 10));
dsDistributedMap4.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2", 20));
dsDistributedMap4.put(3, new HazelcastIntegrationTestUser(3, "TestName3", "TestSurname3", 30));
dsDistributedMap4.put(4, new HazelcastIntegrationTestUser(4, "TestName4", "TestSurname4", 40));
dsDistributedMap4.put(5, new HazelcastIntegrationTestUser(5, "TestName5", "TestSurname5", 50));
Message<?> msg = dsMapChannel4.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof Collection);
Assert.assertEquals(3,
((HazelcastIntegrationTestUser) (((Collection<?>) msg.getPayload()).iterator().next())).getId());
Assert.assertEquals("TestName3",
((HazelcastIntegrationTestUser) (((Collection<?>) msg.getPayload()).iterator().next())).getName());
Assert.assertEquals("TestSurname3",
((HazelcastIntegrationTestUser) (((Collection<?>) msg.getPayload()).iterator().next())).getSurname());
}
}

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="edSetChannel1">
<int:queue/>
</int:channel>
<int:channel id="edSetChannel2">
<int:queue/>
</int:channel>
<int:channel id="edSetChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edSetChannel1" cache="edDistributedSet1"/>
<int-hazelcast:inbound-channel-adapter channel="edSetChannel2" cache="edDistributedSet2" cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edSetChannel3" cache="edDistributedSet3"
cache-events="ADDED,REMOVED" cache-listening-policy="SINGLE"/>
<bean id="edDistributedSet1" factory-bean="edSetInstance" factory-method="getSet">
<constructor-arg value="edDistributedSet1"/>
</bean>
<bean id="edDistributedSet2" factory-bean="edSetInstance" factory-method="getSet">
<constructor-arg value="edDistributedSet2"/>
</bean>
<bean id="edDistributedSet3" factory-bean="edSetInstance" factory-method="getSet">
<constructor-arg value="edDistributedSet3"/>
</bean>
<bean id="edSetInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,127 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.EntryEventType;
import com.hazelcast.core.ISet;
import com.hazelcast.core.ItemEvent;
/**
* Hazelcast Distributed Set Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastDistributedSetEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edSetChannel1;
@Autowired
private PollableChannel edSetChannel2;
@Autowired
private PollableChannel edSetChannel3;
@Resource
private ISet<HazelcastIntegrationTestUser> edDistributedSet1;
@Resource
private ISet<HazelcastIntegrationTestUser> edDistributedSet2;
@Resource
private ISet<HazelcastIntegrationTestUser> edDistributedSet3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedSet1.add(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edSetChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(EntryEventType.ADDED.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getSurname());
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
HazelcastIntegrationTestUser user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedSet2.add(user);
edDistributedSet2.remove(user);
Message<?> msg = edSetChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(EntryEventType.REMOVED.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((ItemEvent<?>) msg.getPayload()).getItem()).getSurname());
}
@Test
public void testEventDrivenForALLEntryEvent() {
HazelcastIntegrationTestUser user = new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1");
edDistributedSet3.add(user);
Message<?> msg = edSetChannel3.receive(2_000);
verify(msg, EntryEventType.ADDED);
edDistributedSet3.remove(user);
msg = edSetChannel3.receive(2_000);
verify(msg, EntryEventType.REMOVED);
user = new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2");
edDistributedSet3.add(user);
msg = edSetChannel3.receive(2_000);
verify(msg, EntryEventType.ADDED);
}
private void verify(Message<?> msg, EntryEventType type) {
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof ItemEvent);
Assert.assertEquals(type.toString(),
((ItemEvent<?>) msg.getPayload()).getEventType().toString());
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="edTopicChannel1">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edTopicChannel1" cache="edDistributedTopic1"/>
<bean id="edDistributedTopic1" factory-bean="edTopicInstance" factory-method="getTopic">
<constructor-arg value="edDistributedTopic1"/>
</bean>
<bean id="edTopicInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,67 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.ITopic;
/**
* Hazelcast Distributed Topic Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastDistributedTopicEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edTopicChannel1;
@Resource
private ITopic<HazelcastIntegrationTestUser> edDistributedTopic1;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edDistributedTopic1.publish(new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edTopicChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof com.hazelcast.core.Message);
Assert.assertEquals(1, ((HazelcastIntegrationTestUser) ((com.hazelcast.core.Message<?>) msg.getPayload())
.getMessageObject()).getId());
Assert.assertEquals("TestName1", ((HazelcastIntegrationTestUser) ((com.hazelcast.core.Message<?>) msg
.getPayload()).getMessageObject()).getName());
Assert.assertEquals("TestSurname1", ((HazelcastIntegrationTestUser) ((com.hazelcast.core.Message<?>) msg
.getPayload()).getMessageObject()).getSurname());
}
}

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="edMultiMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="edMultiMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="edMultiMapChannel3">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edMultiMapChannel1" cache="edMultiMap1"/>
<int-hazelcast:inbound-channel-adapter channel="edMultiMapChannel2" cache="edMultiMap2" cache-events="REMOVED"
cache-listening-policy="SINGLE"/>
<int-hazelcast:inbound-channel-adapter channel="edMultiMapChannel3" cache="edMultiMap3"
cache-events="ADDED,REMOVED,CLEAR_ALL"/>
<bean id="edMultiMap1" factory-bean="edMultiMapInstance" factory-method="getMultiMap">
<constructor-arg value="edMultiMap1"/>
</bean>
<bean id="edMultiMap2" factory-bean="edMultiMapInstance" factory-method="getMultiMap">
<constructor-arg value="edMultiMap2"/>
</bean>
<bean id="edMultiMap3" factory-bean="edMultiMapInstance" factory-method="getMultiMap">
<constructor-arg value="edMultiMap3"/>
</bean>
<bean id="edMultiMapInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,142 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.AbstractIMapEvent;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.core.MultiMap;
/**
* Hazelcast MultiMap Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastMultiMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edMultiMapChannel1;
@Autowired
private PollableChannel edMultiMapChannel2;
@Autowired
private PollableChannel edMultiMapChannel3;
@Resource
private MultiMap<Integer, HazelcastIntegrationTestUser> edMultiMap1;
@Resource
private MultiMap<Integer, HazelcastIntegrationTestUser> edMultiMap2;
@Resource
private MultiMap<Integer, HazelcastIntegrationTestUser> edMultiMap3;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edMultiMap1.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edMultiMapChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.ADDED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edMultiMap1",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(1, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
edMultiMap2.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edMultiMap2.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
edMultiMap2.remove(2);
Message<?> msg = edMultiMapChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.REMOVED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edMultiMap2",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(2, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testEventDrivenForALLEntryEvent() {
edMultiMap3.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edMultiMapChannel3.receive(2_000);
verify(msg, "edMultiMap3", EntryEventType.ADDED);
edMultiMap3.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurnameUpdated"));
msg = edMultiMapChannel3.receive(2_000);
verify(msg, "edMultiMap3", EntryEventType.ADDED);
edMultiMap3.remove(1);
msg = edMultiMapChannel3.receive(2_000);
verify(msg, "edMultiMap3", EntryEventType.REMOVED);
msg = edMultiMapChannel3.receive(2_000);
verify(msg, "edMultiMap3", EntryEventType.REMOVED);
edMultiMap3.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
msg = edMultiMapChannel3.receive(2_000);
verify(msg, "edMultiMap3", EntryEventType.ADDED);
edMultiMap3.clear();
msg = edMultiMapChannel3.receive(2_000);
verify(msg, "edMultiMap3", EntryEventType.CLEAR_ALL);
}
private void verify(Message<?> msg, String cacheName, EntryEventType type) {
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof AbstractIMapEvent);
Assert.assertEquals(cacheName, ((AbstractIMapEvent) msg.getPayload()).getName());
Assert.assertEquals(type, ((AbstractIMapEvent) msg.getPayload()).getEventType());
}
}

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="edReplicatedMapChannel1">
<int:queue/>
</int:channel>
<int:channel id="edReplicatedMapChannel2">
<int:queue/>
</int:channel>
<int:channel id="edReplicatedMapChannel3">
<int:queue/>
</int:channel>
<int:channel id="edReplicatedMapChannel4">
<int:queue/>
</int:channel>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel1" cache="edReplicatedMap1"/>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel2" cache="edReplicatedMap2"
cache-events="UPDATED"/>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel3" cache="edReplicatedMap3"
cache-events="REMOVED"/>
<int-hazelcast:inbound-channel-adapter channel="edReplicatedMapChannel4" cache="edReplicatedMap4"
cache-events="ADDED,REMOVED,UPDATED"/>
<bean id="edReplicatedMap1" factory-bean="edReplicatedMapInstance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap1"/>
</bean>
<bean id="edReplicatedMap2" factory-bean="edReplicatedMapInstance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap2"/>
</bean>
<bean id="edReplicatedMap3" factory-bean="edReplicatedMapInstance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap3"/>
</bean>
<bean id="edReplicatedMap4" factory-bean="edReplicatedMapInstance" factory-method="getReplicatedMap">
<constructor-arg value="edReplicatedMap4"/>
</bean>
<bean id="edReplicatedMapInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,170 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.inbound;
import javax.annotation.Resource;
import org.junit.Assert;
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.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 com.hazelcast.core.AbstractIMapEvent;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.core.ReplicatedMap;
/**
* Hazelcast Replicated Map Event Driven Inbound Channel Adapter Test
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastReplicatedMapEventDrivenInboundChannelAdapterTests {
@Autowired
private PollableChannel edReplicatedMapChannel1;
@Autowired
private PollableChannel edReplicatedMapChannel2;
@Autowired
private PollableChannel edReplicatedMapChannel3;
@Autowired
private PollableChannel edReplicatedMapChannel4;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap1;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap2;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap3;
@Resource
private ReplicatedMap<Integer, HazelcastIntegrationTestUser> edReplicatedMap4;
@Test
public void testEventDrivenForOnlyADDEDEntryEvent() {
edReplicatedMap1.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edReplicatedMapChannel1.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.ADDED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edReplicatedMap1",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(1, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testEventDrivenForOnlyUPDATEDEntryEvent() {
edReplicatedMap2.put(2, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edReplicatedMap2.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
Message<?> msg = edReplicatedMapChannel2.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.UPDATED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edReplicatedMap2",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(2, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(1,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getId());
Assert.assertEquals("TestName1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getName());
Assert.assertEquals("TestSurname1",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getSurname());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getValue()).getSurname());
}
@Test
public void testEventDrivenForOnlyREMOVEDEntryEvent() {
edReplicatedMap3.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
edReplicatedMap3.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
edReplicatedMap3.remove(2);
Message<?> msg = edReplicatedMapChannel3.receive(2_000);
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof EntryEvent);
Assert.assertEquals(EntryEventType.REMOVED,
((EntryEvent<?, ?>) msg.getPayload()).getEventType());
Assert.assertEquals("edReplicatedMap3",
((EntryEvent<?, ?>) msg.getPayload()).getName());
Assert.assertEquals(2, ((EntryEvent<?, ?>) msg.getPayload()).getKey());
Assert.assertEquals(2,
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getId());
Assert.assertEquals("TestName2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getName());
Assert.assertEquals("TestSurname2",
((HazelcastIntegrationTestUser) ((EntryEvent<?, ?>) msg.getPayload()).getOldValue()).getSurname());
}
@Test
public void testEventDrivenForALLEntryEvent() {
edReplicatedMap4.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurname1"));
Message<?> msg = edReplicatedMapChannel4.receive(2_000);
verify(msg, "edReplicatedMap4", EntryEventType.ADDED);
edReplicatedMap4.put(1, new HazelcastIntegrationTestUser(1, "TestName1", "TestSurnameUpdated"));
msg = edReplicatedMapChannel4.receive(2_000);
verify(msg, "edReplicatedMap4", EntryEventType.UPDATED);
edReplicatedMap4.remove(1);
msg = edReplicatedMapChannel4.receive(2_000);
verify(msg, "edReplicatedMap4", EntryEventType.REMOVED);
edReplicatedMap4.put(2, new HazelcastIntegrationTestUser(2, "TestName2", "TestSurname2"));
msg = edReplicatedMapChannel4.receive(2_000);
verify(msg, "edReplicatedMap4", EntryEventType.ADDED);
}
private void verify(Message<?> msg, String cacheName, EntryEventType type) {
Assert.assertNotNull(msg);
Assert.assertNotNull(msg.getPayload());
Assert.assertTrue(msg.getPayload() instanceof AbstractIMapEvent);
Assert.assertEquals(cacheName, ((AbstractIMapEvent) msg.getPayload()).getName());
Assert.assertEquals(type, ((AbstractIMapEvent) msg.getPayload()).getEventType());
}
}

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-hazelcast="http://www.springframework.org/schema/integration/hazelcast"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/hazelcast
http://www.springframework.org/schema/integration/hazelcast/spring-integration-hazelcast.xsd">
<int:channel id="mapChannel"/>
<int:channel id="listChannel"/>
<int:channel id="setChannel"/>
<int:channel id="queueChannel"/>
<int-hazelcast:outbound-channel-adapter channel="mapChannel" cache="distributedMap"/>
<int-hazelcast:outbound-channel-adapter channel="listChannel" cache="distributedList"/>
<int-hazelcast:outbound-channel-adapter channel="setChannel" cache="distributedSet"/>
<int-hazelcast:outbound-channel-adapter channel="queueChannel" cache="distributedQueue"/>
<bean id="distributedMap" factory-bean="instance" factory-method="getMap">
<constructor-arg value="distributedMap"/>
</bean>
<bean id="distributedList" factory-bean="instance" factory-method="getList">
<constructor-arg value="distributedList"/>
</bean>
<bean id="distributedSet" factory-bean="instance" factory-method="getSet">
<constructor-arg value="distributedSet"/>
</bean>
<bean id="distributedQueue" factory-bean="instance" factory-method="getQueue">
<constructor-arg value="distributedQueue"/>
</bean>
<bean id="instance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance"
destroy-method="shutdown">
<constructor-arg>
<bean class="com.hazelcast.config.Config"/>
</constructor-arg>
</bean>
</beans>

View File

@@ -0,0 +1,203 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.hazelcast.outbound;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.Resource;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
* Hazelcast Outbound Channel Adapter Test Class
*
* @author Eren Avsarogullari
* @since 1.0.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class HazelcastOutboundChannelAdapterTests {
private static final int DATA_COUNT = 100;
@Autowired
private MessageChannel mapChannel;
@Autowired
private MessageChannel listChannel;
@Autowired
private MessageChannel setChannel;
@Autowired
private MessageChannel queueChannel;
@Resource
private Map<?, ?> distributedMap;
@Resource
private List<?> distributedList;
@Resource
private Set<?> distributedSet;
@Resource
private Queue<?> distributedQueue;
@Before
public void setUp() {
distributedMap.clear();
distributedList.clear();
distributedSet.clear();
distributedQueue.clear();
}
@Test
public void testWriteDistributedMap() {
Map<Integer, String> map = createMapByEntryCount();
mapChannel.send(new GenericMessage<>(map));
verifyDistributedMap();
}
@Test
public void testWriteDistributedList() {
List<Integer> list = (List<Integer>) fillCollectionByEntryCount(new ArrayList<Integer>());
listChannel.send(new GenericMessage<>(list));
verifyDistributedList();
}
@Test
public void testWriteDistributedSet() {
Set<Integer> set = (Set<Integer>) fillCollectionByEntryCount(new HashSet<Integer>());
setChannel.send(new GenericMessage<>(set));
verifyDistributedSet();
}
@Test
public void testWriteDistributedQueue() {
Queue<Integer> queue = (Queue<Integer>) fillCollectionByEntryCount(
new LinkedBlockingQueue<Integer>(DATA_COUNT));
queueChannel.send(new GenericMessage<>(queue));
verifyDistributedQueue();
}
@Test(expected = MessageHandlingException.class)
public void testMapChannelWithIncorrectDataType() {
Set<Integer> set = new HashSet<>();
set.add(1);
mapChannel.send(new GenericMessage<>(set));
}
@Test(expected = MessageHandlingException.class)
public void testListChannelWithIncorrectDataType() {
Set<Integer> set = new HashSet<>();
set.add(1);
listChannel.send(new GenericMessage<>(set));
}
@Test(expected = MessageHandlingException.class)
public void testSetChannelWithIncorrectDataType() {
List<Integer> list = new ArrayList<>();
list.add(1);
setChannel.send(new GenericMessage<>(list));
}
@Test(expected = MessageHandlingException.class)
public void testQueueChannelWithIncorrectDataType() {
Set<Integer> set = new HashSet<>();
set.add(1);
queueChannel.send(new GenericMessage<>(set));
}
private Map<Integer, String> createMapByEntryCount() {
Map<Integer, String> map = new HashMap<>();
StringBuilder strBuilder = new StringBuilder();
for (int index = 0; index < DATA_COUNT; index++) {
String value = strBuilder.append("Value_").append(index).toString();
map.put(index, value);
strBuilder.delete(0, strBuilder.length());
}
return map;
}
private void verifyDistributedMap() {
Assert.assertEquals(true, distributedMap.size() == DATA_COUNT);
StringBuilder strBuilder = new StringBuilder();
for (int index = 0; index < DATA_COUNT; index++) {
String value = strBuilder.append("Value_").append(index).toString();
Assert.assertEquals(value, distributedMap.get(index));
strBuilder.delete(0, strBuilder.length());
}
}
private Collection<Integer> fillCollectionByEntryCount(Collection<Integer> coll) {
for (int index = 0; index < DATA_COUNT; index++) {
coll.add(index);
}
return coll;
}
private void verifyDistributedList() {
Assert.assertEquals(true, distributedList.size() == DATA_COUNT);
for (int index = 0; index < DATA_COUNT; index++) {
Assert.assertEquals(index, distributedList.get(index));
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void verifyDistributedSet() {
Assert.assertEquals(true, distributedSet.size() == DATA_COUNT);
List list = new ArrayList(distributedSet);
Collections.sort(list);
for (int index = 0; index < DATA_COUNT; index++) {
Assert.assertEquals(index, list.get(index));
}
}
private void verifyDistributedQueue() {
Assert.assertEquals(true, distributedQueue.size() == DATA_COUNT);
int index = 0;
for (Object o : distributedQueue) {
Assert.assertEquals(index++, o);
}
}
}

View File

@@ -0,0 +1,8 @@
log4j.rootCategory=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p %c{1} [%t] : %m%n
log4j.category.org.springframework.integration=WARN
log4j.category.org.springframework.integration.hazelcast=INFO