diff --git a/README.adoc b/README.adoc
index e337bc0..a449c42 100644
--- a/README.adoc
+++ b/README.adoc
@@ -27,6 +27,18 @@ Open Liberty is a lightweight and highly flexible open-source application server
|Simple CRUD REST application with *Jakarta Bean Validation* support
| MongoDB
+| link:microprofile-liberty-redis-single-node/[]
+| Simple CRUD REST application
+| Redis - Single node
+
+| link:microprofile-liberty-redis-sentinel/[]
+| Simple CRUD REST application
+| Redis - Sentinel
+
+| link:microprofile-liberty-redis-cluster/[]
+| Simple CRUD REST application
+| Redis - Cluster
+
|===
== Wildfly
@@ -85,4 +97,5 @@ Apache TomEE is a lightweight, open-source Jakarta EE application server that is
| Simple CRUD REST application
| MongoDB
-|===
\ No newline at end of file
+|===
+
diff --git a/microprofile-liberty-redis-cluster/.dockerignore b/microprofile-liberty-redis-cluster/.dockerignore
new file mode 100644
index 0000000..326c2bc
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/.dockerignore
@@ -0,0 +1,3 @@
+target/
+!target/*.war
+!target/liberty/wlp/usr/shared/resources/*
diff --git a/microprofile-liberty-redis-cluster/.gitignore b/microprofile-liberty-redis-cluster/.gitignore
new file mode 100644
index 0000000..fef207d
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/.gitignore
@@ -0,0 +1,11 @@
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+# https://github.com/takari/maven-wrapper#usage-without-binary-jar
+.mvn/wrapper/maven-wrapper.jar
\ No newline at end of file
diff --git a/microprofile-liberty-redis-cluster/.mvn/wrapper/maven-wrapper.properties b/microprofile-liberty-redis-cluster/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..207aa43
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.1/apache-maven-3.9.1-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/microprofile-liberty-redis-cluster/Dockerfile b/microprofile-liberty-redis-cluster/Dockerfile
new file mode 100644
index 0000000..5f7ac52
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/Dockerfile
@@ -0,0 +1,10 @@
+
+FROM icr.io/appcafe/open-liberty:kernel-slim-java21-openj9-ubi-minimal
+
+COPY --chown=1001:0 /src/main/liberty/config /config
+
+RUN features.sh
+
+COPY --chown=1001:0 target/*.war /config/apps
+
+RUN configure.sh
diff --git a/microprofile-liberty-redis-cluster/README.adoc b/microprofile-liberty-redis-cluster/README.adoc
new file mode 100644
index 0000000..3aa879e
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/README.adoc
@@ -0,0 +1,81 @@
+= MicroProfile Open Liberty with Redis Cluster sample
+
+This project is intent to be a sample for MicroProfile with Redis Cluster integration by using Jakarta NoSQL implementation.
+
+== Setup Redis
+
+image::https://jnosql.github.io/img/logos/redis.png[Redis Project,align="center" width=25%,height=25%]
+
+https://redis.com/[Redis] is a software project that implements data structure servers.
+It is open-source, networked, in-memory, and stores keys with optional durability.
+
+The project is configured to reach out the Redis Cluster with the following configuration defined on the file `src/main/resources/META-INF/microprofile-config.properties`. More info about it, check the following link: https://github.com/eclipse/jnosql-databases?tab=readme-ov-file#configuration-14
+
+[source,properties]
+----
+include::src/main/resources/META-INF/microprofile-config.properties[]
+----
+*PS:warning:* Pay attention to that when you try to set up your own Redis instance.
+
+== Using Docker Compose
+
+The easier way to execute this project is to use the provided docker-compose.yaml file in the root directory.
+You can run it by performing the following command:
+
+[source, bash]
+----
+docker-compose up -d
+----
+
+== Run the code
+
+The generation of the executable jar file can be performed by issuing the following command
+[source, bash]
+----
+mvn clean package
+----
+
+This will create an executable jar file **microprofile-liberty-redis.jar** within the _target_ maven folder. This can be started by executing the following command
+
+[source, bash]
+----
+java -jar target/microprofile-liberty-redis.jar
+----
+
+=== Liberty Dev Mode
+
+During development, you can use Liberty's development mode (dev mode) to code while observing and testing your changes on the fly.
+With the dev mode, you can code along and watch the change reflected in the running server right away;
+unit and integration tests are run on pressing Enter in the command terminal; you can attach a debugger to the running server at any time to step through your code.
+
+[source, bash]
+----
+mvn liberty:dev
+----
+
+
+
+
+To launch the test page, open your browser at the following URL
+
+[source, text]
+----
+http://localhost:9080/index.html
+----
+
+
+=== Specification examples
+
+By default, there is always the creation of a JAX-RS application class to define the path on which the JAX-RS endpoints are available.
+
+Also, a simple Hello world endpoint is created, have a look at the class **HelloController**.
+
+More information on MicroProfile can be found [here](https://microprofile.io/)
+
+
+=== Config
+
+Configuration of your application parameters. Specification [here](https://microprofile.io/project/eclipse/microprofile-config)
+
+The example class **ConfigTestController** shows you how to inject a configuration parameter and how you can retrieve it programmatically.
+
diff --git a/microprofile-liberty-redis-cluster/README.txt b/microprofile-liberty-redis-cluster/README.txt
new file mode 100644
index 0000000..0e4c219
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/README.txt
@@ -0,0 +1,35 @@
+After you generate a starter project, these instructions will help you with what to do next.
+
+The Open Liberty starter gives you a simple, quick way to get the necessary files to start building
+an application on Open Liberty. There is no need to search how to find out what to add to your
+Maven build files. A simple RestApplication.java file is generated for you to start
+creating a REST based application. A server.xml configuration file is provided with the necessary
+features for the MicroProfile and Jakarta EE versions that you previously selected.
+
+If you plan on developing and/or deploying your app in a containerized environment, the included
+Dockerfile will make it easier to create your application image on top of the Open Liberty Docker
+image.
+
+1) Once you download the starter project, unpackage the .zip file on your machine.
+2) Open a command line session, navigate to the installation directory, and run `./mvnw liberty:dev` (Linux/Mac) or `mvnw liberty:dev` (Windows).
+ This will install all required dependencies and start the default server. When complete, you will
+ see the necessary features installed and the message "server is ready to run a smarter planet."
+
+For information on developing your application in dev mode using Maven, see the
+dev mode documentation (https://openliberty.io/docs/latest/development-mode.html).
+
+For further help on getting started actually developing your application, see some of our
+MicroProfile guides (https://openliberty.io/guides/?search=microprofile&key=tag) and Jakarta EE
+guides (https://openliberty.io/guides/?search=jakarta%20ee&key=tag).
+
+If you have problems building the starter project, make sure the Java SE version on your
+machine matches the Java SE version you picked from the Open Liberty starter on the downloads
+page (https://openliberty.io/downloads/). You can test this with the command `java -version`.
+
+Open Liberty performs at its best when running using Open J9 which can be obtained via IBM Semeru
+(https://developer.ibm.com/languages/java/semeru-runtimes/downloads/). For a full list of supported
+Java SE versions and where to obtain them, reference the Java SE support page
+(https://openliberty.io/docs/latest/java-se.html).
+
+If you find any issues with the starter project or have recommendations to improve it, open an
+issue in the starter GitHub repo (https://github.com/OpenLiberty/start.openliberty.io).
diff --git a/microprofile-liberty-redis-cluster/docker-compose.yaml b/microprofile-liberty-redis-cluster/docker-compose.yaml
new file mode 100644
index 0000000..72b36a1
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/docker-compose.yaml
@@ -0,0 +1,95 @@
+version: '3'
+
+services:
+ redis-configurer:
+ container_name: "redis-configurer"
+ image: redis:6.0-alpine
+ command: >
+ sh -c 'echo yes | redis-cli -h 172.22.0.2 -p 6379 --cluster create \
+ 172.22.0.2:6379 172.22.0.3:6379 172.22.0.4:6379 \
+ 172.22.0.5:6379 172.22.0.6:6379 172.22.0.7:6379 \
+ --cluster-replicas 1 && tail -f /dev/null'
+ depends_on:
+ - redis-1
+ - redis-2
+ - redis-3
+ - redis-4
+ - redis-5
+ - redis-6
+ networks:
+ redis-net:
+ ipv4_address: 172.22.0.10
+
+ redis-1:
+ container_name: "redis-1"
+ image: redis:6.0-alpine
+ ports:
+ - 7001:6379
+ command: ["redis-server", "--cluster-enabled", "yes", "--cluster-config-file", "nodes.conf", "--cluster-node-timeout", "5000", "--appendonly", "yes"]
+ depends_on:
+ - redis-2
+ - redis-3
+ - redis-4
+ - redis-5
+ - redis-6
+ networks:
+ redis-net:
+ ipv4_address: 172.22.0.2
+
+ redis-2:
+ container_name: "redis-2"
+ image: redis:6.0-alpine
+ ports:
+ - 7002:6379
+ command: ["redis-server", "--cluster-enabled", "yes", "--cluster-config-file", "nodes.conf", "--cluster-node-timeout", "5000", "--appendonly", "yes"]
+ networks:
+ redis-net:
+ ipv4_address: 172.22.0.3
+
+ redis-3:
+ container_name: "redis-3"
+ image: redis:6.0-alpine
+ ports:
+ - 7003:6379
+ command: ["redis-server", "--cluster-enabled", "yes", "--cluster-config-file", "nodes.conf", "--cluster-node-timeout", "5000", "--appendonly", "yes"]
+ networks:
+ redis-net:
+ ipv4_address: 172.22.0.4
+
+ redis-4:
+ container_name: "redis-4"
+ image: redis:6.0-alpine
+ ports:
+ - 7004:6379
+ command: ["redis-server", "--cluster-enabled", "yes", "--cluster-config-file", "nodes.conf", "--cluster-node-timeout", "5000", "--appendonly", "yes"]
+ networks:
+ redis-net:
+ ipv4_address: 172.22.0.5
+
+ redis-5:
+ container_name: "redis-5"
+ image: redis:6.0-alpine
+ ports:
+ - 7005:6379
+ command: ["redis-server", "--cluster-enabled", "yes", "--cluster-config-file", "nodes.conf", "--cluster-node-timeout", "5000", "--appendonly", "yes"]
+ networks:
+ redis-net:
+ ipv4_address: 172.22.0.6
+
+ redis-6:
+ container_name: "redis-6"
+ image: redis:6.0-alpine
+ ports:
+ - 7006:6379
+ command: ["redis-server", "--cluster-enabled", "yes", "--cluster-config-file", "nodes.conf", "--cluster-node-timeout", "5000", "--appendonly", "yes"]
+
+ networks:
+ redis-net:
+ ipv4_address: 172.22.0.7
+
+networks:
+ redis-net:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.22.0.0/16
\ No newline at end of file
diff --git a/microprofile-liberty-redis-cluster/mvnw b/microprofile-liberty-redis-cluster/mvnw
new file mode 100755
index 0000000..b7f0646
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/mvnw
@@ -0,0 +1,287 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.1.1
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /usr/local/etc/mavenrc ] ; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME
+ else
+ JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ 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
+ else
+ JAVACMD="`\\unset -f command; \\command -v java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ printf '%s' "$(cd "$basedir"; pwd)"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=$(find_maven_basedir "$(dirname $0)")
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ else
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $wrapperUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ QUIET="--quiet"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ QUIET=""
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
+ else
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
+ fi
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
+ elif command -v curl > /dev/null; then
+ QUIET="--silent"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ QUIET=""
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
+ else
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
+ fi
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaSource=`cygpath --path --windows "$javaSource"`
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaSource" ]; then
+ if [ ! -e "$javaClass" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaSource")
+ fi
+ if [ -e "$javaClass" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microprofile-liberty-redis-cluster/mvnw.cmd b/microprofile-liberty-redis-cluster/mvnw.cmd
new file mode 100644
index 0000000..474c9d6
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/mvnw.cmd
@@ -0,0 +1,187 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.1.1
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %WRAPPER_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/microprofile-liberty-redis-cluster/pom.xml b/microprofile-liberty-redis-cluster/pom.xml
new file mode 100644
index 0000000..7f0fc47
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/pom.xml
@@ -0,0 +1,68 @@
+
+
+ 4.0.0
+
+ org.jnosql
+ demo-ee
+ 1.0.1
+
+ org.jnosql.demoee
+ microprofile-liberty-redis-cluster
+ MicroProfile app using OpenLiberty and Redis Cluster
+ war
+
+
+ 17
+ 17
+
+ 1.1.1
+ UTF-8
+
+
+
+
+ jakarta.platform
+ jakarta.jakartaee-api
+ 10.0.0
+ provided
+
+
+ org.eclipse.microprofile
+ microprofile
+ 6.1
+ pom
+ provided
+
+
+ org.eclipse.jnosql.databases
+ jnosql-redis
+ ${jnosql.version}
+
+
+
+
+ microprofile-liberty-redis
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.3.2
+
+
+ io.openliberty.tools
+ liberty-maven-plugin
+ 3.11.1
+
+
+
+
+
+ io.openliberty.tools
+ liberty-maven-plugin
+
+
+
+
diff --git a/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/RestApplication.java b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/RestApplication.java
new file mode 100644
index 0000000..f5305dd
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/RestApplication.java
@@ -0,0 +1,9 @@
+package org.jnosql.demoee;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class RestApplication extends Application {
+
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/Hero.java b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/Hero.java
new file mode 100644
index 0000000..32d1724
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/Hero.java
@@ -0,0 +1,60 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.nosql.Column;
+import jakarta.nosql.Entity;
+import jakarta.nosql.Id;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+
+import java.util.Objects;
+import java.util.Set;
+
+@Entity
+@Schema
+public record Hero(
+ @Id
+ @Schema(required = true)
+ Integer id,
+ @Column
+ @Schema
+ String name,
+ @Column
+ @Schema
+ String secretIdentity,
+ @Column
+ @Schema
+ String impactPhrase
+) {
+
+ public static Hero newHero(String name, String secretIdentity, String impactPhrase) {
+ return new Hero(Objects.hash(name, secretIdentity, impactPhrase), name, secretIdentity, impactPhrase);
+ }
+
+ public boolean nameMatchesWith(String name) {
+ return fuzzySearch(name, this.name());
+ }
+
+ public boolean secretIdentityMatchesWith(String pattern) {
+ return fuzzySearch(pattern, this.secretIdentity());
+ }
+
+ public boolean impactPhraseMatchesWith(String pattern) {
+ return fuzzySearch(pattern, this.impactPhrase());
+ }
+
+ private boolean isNotSearchable(String value) {
+ return value == null || value.isBlank();
+ }
+
+ public Set splitPhrase(String phrase) {
+ return Set.of(phrase.split("[.,\\s]"));
+ }
+
+ public boolean fuzzySearch(String source, String target) {
+ if (isNotSearchable(source) || isNotSearchable(target)) {
+ return false;
+ }
+ Set words = splitPhrase(source.toLowerCase());
+ return words.stream().anyMatch(target.toLowerCase()::contains);
+ }
+
+}
diff --git a/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/Heroes.java b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/Heroes.java
new file mode 100644
index 0000000..28fa45a
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/Heroes.java
@@ -0,0 +1,74 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.eclipse.jnosql.mapping.keyvalue.KeyValueDatabase;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+@ApplicationScoped
+public class Heroes {
+
+ @Inject
+ @KeyValueDatabase("heroes")
+ Map heroes;
+
+ public Iterable findHeroesBy(HeroesQuery heroesQuery) {
+
+ var nameMatches = Optional
+ .ofNullable(heroesQuery.name())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.nameMatchesWith(m))
+ .orElse(null);
+
+ var secretIdentityMatches = Optional
+ .ofNullable(heroesQuery.secretIdentity())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.secretIdentityMatchesWith(m))
+ .orElse(null);
+
+ var impactPhraseMatches = Optional
+ .ofNullable(heroesQuery.impactPhrase())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.impactPhraseMatchesWith(m))
+ .orElse(null);
+
+ var matcherFilters = Arrays.stream(new Predicate[]{
+ nameMatches,
+ secretIdentityMatches,
+ impactPhraseMatches})
+ .filter(Objects::nonNull)
+ .reduce((a, b) -> a.or(b));
+
+
+ if (matcherFilters.isPresent()) {
+
+ return heroes.values()
+ .stream()
+ .filter(matcherFilters.orElse(h -> false)).toList();
+ }
+
+ return heroes.values().stream().toList();
+ }
+
+ public Optional getById(Integer id) {
+ return Optional.ofNullable(heroes.get(id));
+ }
+
+ public Hero add(Hero hero) {
+ Objects.requireNonNull(hero, "hero is required");
+ heroes.put(hero.id(), hero);
+ return hero;
+ }
+
+ public Optional remove(Integer id) {
+ return Optional.ofNullable(id)
+ .flatMap(existentId -> Optional.ofNullable(heroes.remove(existentId)));
+ }
+
+
+}
diff --git a/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java
new file mode 100644
index 0000000..5742cdf
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java
@@ -0,0 +1,36 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.Initialized;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
+import org.eclipse.jnosql.mapping.keyvalue.KeyValueDatabase;
+
+import java.util.Map;
+
+import static java.util.Set.of;
+import static org.jnosql.demoee.heroes.Hero.newHero;
+
+@ApplicationScoped
+public class HeroesApplicationInitializer {
+
+ @Inject
+ @KeyValueDatabase("heroes")
+ Map heroes;
+
+ public void onInitialized(@Observes @Initialized(ApplicationScoped.class) Object event) {
+ of(
+ newHero("Superman", "Clark Kent", "Up, up and away!"),
+ newHero("Batman", "Bruce Wayne", "I am vengeance, I am the night!"),
+ newHero("Wonder", "Diana Prince", "I will fight for those who cannot fight for themselves!"),
+ newHero("Flash", "Barry Allen", "Life doesn't give us purpose. We give life purpose!"),
+ newHero("Green Lantern", "Hal Jordan", "In brightest day, in blackest night, no evil shall escape my sight!"),
+ newHero("Aquaman", "Arthur Curry", "I don't belong to the land or the sea!"),
+ newHero("Cyborg", "Victor Stone", "I'm not broken, and I'm not alone!"),
+ newHero("Shazam", "Billy Batson", "Shazam!")
+ )
+ .stream()
+ .filter(hero -> !heroes.containsKey(hero.id()))
+ .forEach(hero -> heroes.put(hero.id(), hero));
+ }
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java
new file mode 100644
index 0000000..b227c84
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java
@@ -0,0 +1,35 @@
+package org.jnosql.demoee.heroes;
+
+public record HeroesQuery(String name, String secretIdentity, String impactPhrase) {
+
+ static QueryBuilder queryBuilder() {
+ return new QueryBuilder();
+ }
+
+ public static class QueryBuilder {
+
+ private String name;
+ private String secretIdentity;
+ private String impactPhrase;
+
+ public QueryBuilder byName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public QueryBuilder bySecretIdentity(String secretIdentity) {
+ this.secretIdentity = secretIdentity;
+ return this;
+ }
+
+ public QueryBuilder byImpactPhrase(String impactPhrase) {
+ this.impactPhrase = impactPhrase;
+ return this;
+ }
+
+ public HeroesQuery build() {
+ return new HeroesQuery(name, secretIdentity, impactPhrase);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java
new file mode 100644
index 0000000..442d628
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java
@@ -0,0 +1,79 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.inject.Inject;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+
+import static org.jnosql.demoee.heroes.HeroesQuery.queryBuilder;
+
+@Path("/heroes")
+@Produces({MediaType.APPLICATION_JSON})
+@Consumes({MediaType.APPLICATION_JSON})
+public class HeroesResource {
+
+ @Inject
+ Heroes heroes;
+
+ @GET
+ public Iterable heroes(
+ @QueryParam("name") String name,
+ @QueryParam("secretIdentity") String secretIdentity,
+ @QueryParam("impactPhrase") String impactPhrase
+ ) {
+
+ return heroes.findHeroesBy(queryBuilder()
+ .byName(name)
+ .bySecretIdentity(secretIdentity)
+ .byImpactPhrase(impactPhrase).build());
+
+ }
+
+ @GET
+ @Path("/{id}")
+ public Hero getHeroById(
+ @PathParam("id")
+ @Schema(required = true) final Integer id) {
+ return heroes.getById(id)
+ .orElseThrow(() -> new NotFoundException("Hero not found"));
+ }
+
+ @Schema
+ public record NewHero(
+ @NotBlank
+ @Schema
+ String name,
+ @Schema
+ String secretIdentity,
+ @Schema
+ String impactPhrase) {
+ Hero toEntity() {
+ return Hero.newHero(name(), secretIdentity(), impactPhrase());
+ }
+ }
+
+ @POST
+ public Hero add(@Valid NewHero request) {
+ var newHero = request.toEntity();
+ return heroes.add(newHero);
+ }
+
+ @DELETE
+ @Path("/{id}")
+ public Hero delete(@PathParam("id")
+ @Schema(required = true) final Integer id) {
+ return this.heroes.remove(id).orElseThrow(() -> new NotFoundException("Hero not found"));
+ }
+
+
+}
diff --git a/microprofile-liberty-redis-cluster/src/main/liberty/config/server.xml b/microprofile-liberty-redis-cluster/src/main/liberty/config/server.xml
new file mode 100644
index 0000000..4153670
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/liberty/config/server.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ jakartaee-10.0
+ microProfile-6.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/microprofile-liberty-redis-cluster/src/main/resources/META-INF/microprofile-config.properties b/microprofile-liberty-redis-cluster/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..6c9e2f5
--- /dev/null
+++ b/microprofile-liberty-redis-cluster/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,15 @@
+jnosql.keyvalue.provider=org.eclipse.jnosql.databases.redis.communication.RedisConfiguration
+jnosql.keyvalue.database=heroes
+
+# Cluster Configuration
+
+jnosql.redis.cluster.hosts=localhost:7001,localhost:7002,localhost:7003,localhost:7004,localhost:7005,localhost:7006
+#jnosql.redis.cluster.user=clusterUser
+#jnosql.redis.cluster.password=clusterPassword
+#jnosql.redis.cluster.client.name=clusterClientName
+#jnosql.redis.cluster.max.attempts=5
+#jnosql.redis.cluster.max.total.retries.duration=10000
+#jnosql.redis.cluster.ssl=false
+#jnosql.redis.cluster.timeout=2000
+#jnosql.redis.cluster.connection.timeout=2000
+#jnosql.redis.cluster.socket.timeout=2000
\ No newline at end of file
diff --git a/microprofile-liberty-redis-sentinel/.dockerignore b/microprofile-liberty-redis-sentinel/.dockerignore
new file mode 100644
index 0000000..326c2bc
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/.dockerignore
@@ -0,0 +1,3 @@
+target/
+!target/*.war
+!target/liberty/wlp/usr/shared/resources/*
diff --git a/microprofile-liberty-redis-sentinel/.gitignore b/microprofile-liberty-redis-sentinel/.gitignore
new file mode 100644
index 0000000..fef207d
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/.gitignore
@@ -0,0 +1,11 @@
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+# https://github.com/takari/maven-wrapper#usage-without-binary-jar
+.mvn/wrapper/maven-wrapper.jar
\ No newline at end of file
diff --git a/microprofile-liberty-redis-sentinel/.mvn/wrapper/maven-wrapper.properties b/microprofile-liberty-redis-sentinel/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..207aa43
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.1/apache-maven-3.9.1-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/microprofile-liberty-redis-sentinel/Dockerfile b/microprofile-liberty-redis-sentinel/Dockerfile
new file mode 100644
index 0000000..5f7ac52
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/Dockerfile
@@ -0,0 +1,10 @@
+
+FROM icr.io/appcafe/open-liberty:kernel-slim-java21-openj9-ubi-minimal
+
+COPY --chown=1001:0 /src/main/liberty/config /config
+
+RUN features.sh
+
+COPY --chown=1001:0 target/*.war /config/apps
+
+RUN configure.sh
diff --git a/microprofile-liberty-redis-sentinel/README.adoc b/microprofile-liberty-redis-sentinel/README.adoc
new file mode 100644
index 0000000..a55ec46
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/README.adoc
@@ -0,0 +1,78 @@
+= MicroProfile Open Liberty with Redis Sentinel sample
+
+This project is intent to be a sample for MicroProfile with Redis Sentinel integration by using Jakarta NoSQL implementation.
+
+== Setup Redis
+
+image::https://jnosql.github.io/img/logos/redis.png[Redis Project,align="center" width=25%,height=25%]
+
+https://redis.com/[Redis] is a software project that implements data structure servers.
+It is open-source, networked, in-memory, and stores keys with optional durability.
+
+This required configuration to connect to Redis Sentinel is on the file `src/main/resources/META-INF/microprofile-config.properties`. More info about it, check the following link: https://github.com/eclipse/jnosql-databases?tab=readme-ov-file#configuration-14
+
+[source,properties]
+----
+include::src/main/resources/META-INF/microprofile-config.properties[]
+----
+*PS:warning:* Pay attention to that when you try to set up your own Redis instance.
+
+== Using Docker Compose
+
+The easier way to execute this project is to use the provided docker-compose.yaml file in the root directory.
+You can run it by performing the following command:
+
+[source, bash]
+----
+docker-compose up -d
+----
+
+== Run the code
+
+The generation of the executable jar file can be performed by issuing the following command
+[source, bash]
+----
+mvn clean package
+----
+
+This will create an executable jar file **microprofile-liberty-redis.jar** within the _target_ maven folder. This can be started by executing the following command
+
+[source, bash]
+----
+java -jar target/microprofile-liberty-redis.jar
+----
+
+=== Liberty Dev Mode
+
+During development, you can use Liberty's development mode (dev mode) to code while observing and testing your changes on the fly.
+With the dev mode, you can code along and watch the change reflected in the running server right away;
+unit and integration tests are run on pressing Enter in the command terminal; you can attach a debugger to the running server at any time to step through your code.
+
+[source, bash]
+----
+mvn liberty:dev
+----
+
+To launch the test page, open your browser at the following URL
+
+[source, text]
+----
+http://localhost:9080/index.html
+----
+
+
+=== Specification examples
+
+By default, there is always the creation of a JAX-RS application class to define the path on which the JAX-RS endpoints are available.
+
+Also, a simple Hello world endpoint is created, have a look at the class **HelloController**.
+
+More information on MicroProfile can be found [here](https://microprofile.io/)
+
+
+=== Config
+
+Configuration of your application parameters. Specification [here](https://microprofile.io/project/eclipse/microprofile-config)
+
+The example class **ConfigTestController** shows you how to inject a configuration parameter and how you can retrieve it programmatically.
+
diff --git a/microprofile-liberty-redis-sentinel/README.txt b/microprofile-liberty-redis-sentinel/README.txt
new file mode 100644
index 0000000..0e4c219
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/README.txt
@@ -0,0 +1,35 @@
+After you generate a starter project, these instructions will help you with what to do next.
+
+The Open Liberty starter gives you a simple, quick way to get the necessary files to start building
+an application on Open Liberty. There is no need to search how to find out what to add to your
+Maven build files. A simple RestApplication.java file is generated for you to start
+creating a REST based application. A server.xml configuration file is provided with the necessary
+features for the MicroProfile and Jakarta EE versions that you previously selected.
+
+If you plan on developing and/or deploying your app in a containerized environment, the included
+Dockerfile will make it easier to create your application image on top of the Open Liberty Docker
+image.
+
+1) Once you download the starter project, unpackage the .zip file on your machine.
+2) Open a command line session, navigate to the installation directory, and run `./mvnw liberty:dev` (Linux/Mac) or `mvnw liberty:dev` (Windows).
+ This will install all required dependencies and start the default server. When complete, you will
+ see the necessary features installed and the message "server is ready to run a smarter planet."
+
+For information on developing your application in dev mode using Maven, see the
+dev mode documentation (https://openliberty.io/docs/latest/development-mode.html).
+
+For further help on getting started actually developing your application, see some of our
+MicroProfile guides (https://openliberty.io/guides/?search=microprofile&key=tag) and Jakarta EE
+guides (https://openliberty.io/guides/?search=jakarta%20ee&key=tag).
+
+If you have problems building the starter project, make sure the Java SE version on your
+machine matches the Java SE version you picked from the Open Liberty starter on the downloads
+page (https://openliberty.io/downloads/). You can test this with the command `java -version`.
+
+Open Liberty performs at its best when running using Open J9 which can be obtained via IBM Semeru
+(https://developer.ibm.com/languages/java/semeru-runtimes/downloads/). For a full list of supported
+Java SE versions and where to obtain them, reference the Java SE support page
+(https://openliberty.io/docs/latest/java-se.html).
+
+If you find any issues with the starter project or have recommendations to improve it, open an
+issue in the starter GitHub repo (https://github.com/OpenLiberty/start.openliberty.io).
diff --git a/microprofile-liberty-redis-sentinel/docker-compose.yaml b/microprofile-liberty-redis-sentinel/docker-compose.yaml
new file mode 100644
index 0000000..9ba8002
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/docker-compose.yaml
@@ -0,0 +1,94 @@
+version: '3'
+services:
+ redis-master:
+ container_name: "redis-master"
+ image: redis
+ command: redis-server
+ ports:
+ - "6379:6379"
+ volumes:
+ - redis-master:/data
+
+ redis-slave1:
+ container_name: "redis-slave1"
+ image: redis
+ ports:
+ - "6380:6379"
+ command: redis-server --slaveof redis-master 6379
+ depends_on:
+ - redis-master
+ volumes:
+ - redis-slave1:/data
+
+ redis-slave2:
+ container_name: "redis-slave2"
+ image: redis
+ ports:
+ - "6381:6379"
+ command: redis-server --slaveof redis-master 6379
+ depends_on:
+ - redis-master
+ volumes:
+ - redis-slave2:/data
+
+ redis-sentinel1:
+ container_name: 'redis-sentinel1'
+ image: redis
+ ports:
+ - "26379:26379"
+ command: >
+ sh -c 'echo "bind 0.0.0.0" > /etc/sentinel.conf &&
+ echo "sentinel monitor mymaster redis-master 6379 2" >> /etc/sentinel.conf &&
+ echo "sentinel resolve-hostnames yes" >> /etc/sentinel.conf &&
+ echo "sentinel down-after-milliseconds mymaster 10000" >> /etc/sentinel.conf &&
+ echo "sentinel failover-timeout mymaster 10000" >> /etc/sentinel.conf &&
+ echo "sentinel parallel-syncs mymaster 1" >> /etc/sentinel.conf &&
+ redis-sentinel /etc/sentinel.conf'
+ depends_on:
+ - redis-master
+ - redis-slave1
+ - redis-slave2
+
+ redis-sentinel2:
+ container_name: 'redis-sentinel2'
+ image: redis
+ ports:
+ - "26380:26379"
+ command: >
+ sh -c 'echo "bind 0.0.0.0" > /etc/sentinel.conf &&
+ echo "sentinel monitor mymaster redis-master 6379 2" >> /etc/sentinel.conf &&
+ echo "sentinel resolve-hostnames yes" >> /etc/sentinel.conf &&
+ echo "sentinel down-after-milliseconds mymaster 10000" >> /etc/sentinel.conf &&
+ echo "sentinel failover-timeout mymaster 10000" >> /etc/sentinel.conf &&
+ echo "sentinel parallel-syncs mymaster 1" >> /etc/sentinel.conf &&
+ redis-sentinel /etc/sentinel.conf'
+ depends_on:
+ - redis-master
+ - redis-slave1
+ - redis-slave2
+
+ redis-sentinel3:
+ container_name: 'redis-sentinel3'
+ image: redis
+ ports:
+ - "26381:26379"
+ command: >
+ sh -c 'echo "bind 0.0.0.0" > /etc/sentinel.conf &&
+ echo "sentinel monitor mymaster redis-master 6379 2" >> /etc/sentinel.conf &&
+ echo "sentinel resolve-hostnames yes" >> /etc/sentinel.conf &&
+ echo "sentinel down-after-milliseconds mymaster 10000" >> /etc/sentinel.conf &&
+ echo "sentinel failover-timeout mymaster 10000" >> /etc/sentinel.conf &&
+ echo "sentinel parallel-syncs mymaster 1" >> /etc/sentinel.conf &&
+ redis-sentinel /etc/sentinel.conf'
+ depends_on:
+ - redis-master
+ - redis-slave1
+ - redis-slave2
+
+volumes:
+ redis-master:
+ driver: local
+ redis-slave1:
+ driver: local
+ redis-slave2:
+ driver: local
diff --git a/microprofile-liberty-redis-sentinel/mvnw b/microprofile-liberty-redis-sentinel/mvnw
new file mode 100755
index 0000000..b7f0646
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/mvnw
@@ -0,0 +1,287 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.1.1
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /usr/local/etc/mavenrc ] ; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME
+ else
+ JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ 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
+ else
+ JAVACMD="`\\unset -f command; \\command -v java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ printf '%s' "$(cd "$basedir"; pwd)"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=$(find_maven_basedir "$(dirname $0)")
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ else
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $wrapperUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ QUIET="--quiet"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ QUIET=""
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
+ else
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
+ fi
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
+ elif command -v curl > /dev/null; then
+ QUIET="--silent"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ QUIET=""
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
+ else
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
+ fi
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaSource=`cygpath --path --windows "$javaSource"`
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaSource" ]; then
+ if [ ! -e "$javaClass" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaSource")
+ fi
+ if [ -e "$javaClass" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microprofile-liberty-redis-sentinel/mvnw.cmd b/microprofile-liberty-redis-sentinel/mvnw.cmd
new file mode 100644
index 0000000..474c9d6
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/mvnw.cmd
@@ -0,0 +1,187 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.1.1
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %WRAPPER_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/microprofile-liberty-redis-sentinel/pom.xml b/microprofile-liberty-redis-sentinel/pom.xml
new file mode 100644
index 0000000..09acb4b
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/pom.xml
@@ -0,0 +1,68 @@
+
+
+ 4.0.0
+
+ org.jnosql
+ demo-ee
+ 1.0.1
+
+ org.jnosql.demoee
+ microprofile-liberty-redis-sentinel
+ MicroProfile app using OpenLiberty and Redis Sentinel
+ war
+
+
+ 17
+ 17
+
+ 1.1.1
+ UTF-8
+
+
+
+
+ jakarta.platform
+ jakarta.jakartaee-api
+ 10.0.0
+ provided
+
+
+ org.eclipse.microprofile
+ microprofile
+ 6.1
+ pom
+ provided
+
+
+ org.eclipse.jnosql.databases
+ jnosql-redis
+ ${jnosql.version}
+
+
+
+
+ microprofile-liberty-redis
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.3.2
+
+
+ io.openliberty.tools
+ liberty-maven-plugin
+ 3.11.1
+
+
+
+
+
+ io.openliberty.tools
+ liberty-maven-plugin
+
+
+
+
diff --git a/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/RestApplication.java b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/RestApplication.java
new file mode 100644
index 0000000..f5305dd
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/RestApplication.java
@@ -0,0 +1,9 @@
+package org.jnosql.demoee;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class RestApplication extends Application {
+
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/Hero.java b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/Hero.java
new file mode 100644
index 0000000..32d1724
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/Hero.java
@@ -0,0 +1,60 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.nosql.Column;
+import jakarta.nosql.Entity;
+import jakarta.nosql.Id;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+
+import java.util.Objects;
+import java.util.Set;
+
+@Entity
+@Schema
+public record Hero(
+ @Id
+ @Schema(required = true)
+ Integer id,
+ @Column
+ @Schema
+ String name,
+ @Column
+ @Schema
+ String secretIdentity,
+ @Column
+ @Schema
+ String impactPhrase
+) {
+
+ public static Hero newHero(String name, String secretIdentity, String impactPhrase) {
+ return new Hero(Objects.hash(name, secretIdentity, impactPhrase), name, secretIdentity, impactPhrase);
+ }
+
+ public boolean nameMatchesWith(String name) {
+ return fuzzySearch(name, this.name());
+ }
+
+ public boolean secretIdentityMatchesWith(String pattern) {
+ return fuzzySearch(pattern, this.secretIdentity());
+ }
+
+ public boolean impactPhraseMatchesWith(String pattern) {
+ return fuzzySearch(pattern, this.impactPhrase());
+ }
+
+ private boolean isNotSearchable(String value) {
+ return value == null || value.isBlank();
+ }
+
+ public Set splitPhrase(String phrase) {
+ return Set.of(phrase.split("[.,\\s]"));
+ }
+
+ public boolean fuzzySearch(String source, String target) {
+ if (isNotSearchable(source) || isNotSearchable(target)) {
+ return false;
+ }
+ Set words = splitPhrase(source.toLowerCase());
+ return words.stream().anyMatch(target.toLowerCase()::contains);
+ }
+
+}
diff --git a/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/Heroes.java b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/Heroes.java
new file mode 100644
index 0000000..28fa45a
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/Heroes.java
@@ -0,0 +1,74 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.eclipse.jnosql.mapping.keyvalue.KeyValueDatabase;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+@ApplicationScoped
+public class Heroes {
+
+ @Inject
+ @KeyValueDatabase("heroes")
+ Map heroes;
+
+ public Iterable findHeroesBy(HeroesQuery heroesQuery) {
+
+ var nameMatches = Optional
+ .ofNullable(heroesQuery.name())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.nameMatchesWith(m))
+ .orElse(null);
+
+ var secretIdentityMatches = Optional
+ .ofNullable(heroesQuery.secretIdentity())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.secretIdentityMatchesWith(m))
+ .orElse(null);
+
+ var impactPhraseMatches = Optional
+ .ofNullable(heroesQuery.impactPhrase())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.impactPhraseMatchesWith(m))
+ .orElse(null);
+
+ var matcherFilters = Arrays.stream(new Predicate[]{
+ nameMatches,
+ secretIdentityMatches,
+ impactPhraseMatches})
+ .filter(Objects::nonNull)
+ .reduce((a, b) -> a.or(b));
+
+
+ if (matcherFilters.isPresent()) {
+
+ return heroes.values()
+ .stream()
+ .filter(matcherFilters.orElse(h -> false)).toList();
+ }
+
+ return heroes.values().stream().toList();
+ }
+
+ public Optional getById(Integer id) {
+ return Optional.ofNullable(heroes.get(id));
+ }
+
+ public Hero add(Hero hero) {
+ Objects.requireNonNull(hero, "hero is required");
+ heroes.put(hero.id(), hero);
+ return hero;
+ }
+
+ public Optional remove(Integer id) {
+ return Optional.ofNullable(id)
+ .flatMap(existentId -> Optional.ofNullable(heroes.remove(existentId)));
+ }
+
+
+}
diff --git a/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java
new file mode 100644
index 0000000..5742cdf
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java
@@ -0,0 +1,36 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.Initialized;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
+import org.eclipse.jnosql.mapping.keyvalue.KeyValueDatabase;
+
+import java.util.Map;
+
+import static java.util.Set.of;
+import static org.jnosql.demoee.heroes.Hero.newHero;
+
+@ApplicationScoped
+public class HeroesApplicationInitializer {
+
+ @Inject
+ @KeyValueDatabase("heroes")
+ Map heroes;
+
+ public void onInitialized(@Observes @Initialized(ApplicationScoped.class) Object event) {
+ of(
+ newHero("Superman", "Clark Kent", "Up, up and away!"),
+ newHero("Batman", "Bruce Wayne", "I am vengeance, I am the night!"),
+ newHero("Wonder", "Diana Prince", "I will fight for those who cannot fight for themselves!"),
+ newHero("Flash", "Barry Allen", "Life doesn't give us purpose. We give life purpose!"),
+ newHero("Green Lantern", "Hal Jordan", "In brightest day, in blackest night, no evil shall escape my sight!"),
+ newHero("Aquaman", "Arthur Curry", "I don't belong to the land or the sea!"),
+ newHero("Cyborg", "Victor Stone", "I'm not broken, and I'm not alone!"),
+ newHero("Shazam", "Billy Batson", "Shazam!")
+ )
+ .stream()
+ .filter(hero -> !heroes.containsKey(hero.id()))
+ .forEach(hero -> heroes.put(hero.id(), hero));
+ }
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java
new file mode 100644
index 0000000..b227c84
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java
@@ -0,0 +1,35 @@
+package org.jnosql.demoee.heroes;
+
+public record HeroesQuery(String name, String secretIdentity, String impactPhrase) {
+
+ static QueryBuilder queryBuilder() {
+ return new QueryBuilder();
+ }
+
+ public static class QueryBuilder {
+
+ private String name;
+ private String secretIdentity;
+ private String impactPhrase;
+
+ public QueryBuilder byName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public QueryBuilder bySecretIdentity(String secretIdentity) {
+ this.secretIdentity = secretIdentity;
+ return this;
+ }
+
+ public QueryBuilder byImpactPhrase(String impactPhrase) {
+ this.impactPhrase = impactPhrase;
+ return this;
+ }
+
+ public HeroesQuery build() {
+ return new HeroesQuery(name, secretIdentity, impactPhrase);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java
new file mode 100644
index 0000000..442d628
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java
@@ -0,0 +1,79 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.inject.Inject;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+
+import static org.jnosql.demoee.heroes.HeroesQuery.queryBuilder;
+
+@Path("/heroes")
+@Produces({MediaType.APPLICATION_JSON})
+@Consumes({MediaType.APPLICATION_JSON})
+public class HeroesResource {
+
+ @Inject
+ Heroes heroes;
+
+ @GET
+ public Iterable heroes(
+ @QueryParam("name") String name,
+ @QueryParam("secretIdentity") String secretIdentity,
+ @QueryParam("impactPhrase") String impactPhrase
+ ) {
+
+ return heroes.findHeroesBy(queryBuilder()
+ .byName(name)
+ .bySecretIdentity(secretIdentity)
+ .byImpactPhrase(impactPhrase).build());
+
+ }
+
+ @GET
+ @Path("/{id}")
+ public Hero getHeroById(
+ @PathParam("id")
+ @Schema(required = true) final Integer id) {
+ return heroes.getById(id)
+ .orElseThrow(() -> new NotFoundException("Hero not found"));
+ }
+
+ @Schema
+ public record NewHero(
+ @NotBlank
+ @Schema
+ String name,
+ @Schema
+ String secretIdentity,
+ @Schema
+ String impactPhrase) {
+ Hero toEntity() {
+ return Hero.newHero(name(), secretIdentity(), impactPhrase());
+ }
+ }
+
+ @POST
+ public Hero add(@Valid NewHero request) {
+ var newHero = request.toEntity();
+ return heroes.add(newHero);
+ }
+
+ @DELETE
+ @Path("/{id}")
+ public Hero delete(@PathParam("id")
+ @Schema(required = true) final Integer id) {
+ return this.heroes.remove(id).orElseThrow(() -> new NotFoundException("Hero not found"));
+ }
+
+
+}
diff --git a/microprofile-liberty-redis-sentinel/src/main/liberty/config/server.xml b/microprofile-liberty-redis-sentinel/src/main/liberty/config/server.xml
new file mode 100644
index 0000000..4153670
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/liberty/config/server.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ jakartaee-10.0
+ microProfile-6.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/microprofile-liberty-redis-sentinel/src/main/resources/META-INF/microprofile-config.properties b/microprofile-liberty-redis-sentinel/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..fe41989
--- /dev/null
+++ b/microprofile-liberty-redis-sentinel/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,20 @@
+jnosql.keyvalue.provider=org.eclipse.jnosql.databases.redis.communication.RedisConfiguration
+jnosql.keyvalue.database=heroes
+
+# Sentinel Configuration
+
+jnosql.redis.sentinel.hosts=localhost:26379,localhost:26380,localhost:26381
+jnosql.redis.sentinel.master.name=mymaster
+
+#jnosql.redis.sentinel.master.user=masterUser
+#jnosql.redis.sentinel.master.password=masterPassword
+#jnosql.redis.sentinel.master.ssl=false
+#jnosql.redis.sentinel.master.timeout=2000
+#jnosql.redis.sentinel.master.connection.timeout=2000
+#jnosql.redis.sentinel.master.socket.timeout=2000
+#jnosql.redis.sentinel.slave.user=slaveUser
+#jnosql.redis.sentinel.slave.password=slavePassword
+#jnosql.redis.sentinel.slave.ssl=false
+#jnosql.redis.sentinel.slave.timeout=2000
+#jnosql.redis.sentinel.slave.connection.timeout=2000
+#jnosql.redis.sentinel.slave.socket.timeout=2000
\ No newline at end of file
diff --git a/microprofile-liberty-redis-single-node/.dockerignore b/microprofile-liberty-redis-single-node/.dockerignore
new file mode 100644
index 0000000..326c2bc
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/.dockerignore
@@ -0,0 +1,3 @@
+target/
+!target/*.war
+!target/liberty/wlp/usr/shared/resources/*
diff --git a/microprofile-liberty-redis-single-node/.gitignore b/microprofile-liberty-redis-single-node/.gitignore
new file mode 100644
index 0000000..fef207d
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/.gitignore
@@ -0,0 +1,11 @@
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+# https://github.com/takari/maven-wrapper#usage-without-binary-jar
+.mvn/wrapper/maven-wrapper.jar
\ No newline at end of file
diff --git a/microprofile-liberty-redis-single-node/.mvn/wrapper/maven-wrapper.properties b/microprofile-liberty-redis-single-node/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..207aa43
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.1/apache-maven-3.9.1-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/microprofile-liberty-redis-single-node/Dockerfile b/microprofile-liberty-redis-single-node/Dockerfile
new file mode 100644
index 0000000..5f7ac52
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/Dockerfile
@@ -0,0 +1,10 @@
+
+FROM icr.io/appcafe/open-liberty:kernel-slim-java21-openj9-ubi-minimal
+
+COPY --chown=1001:0 /src/main/liberty/config /config
+
+RUN features.sh
+
+COPY --chown=1001:0 target/*.war /config/apps
+
+RUN configure.sh
diff --git a/microprofile-liberty-redis-single-node/README.adoc b/microprofile-liberty-redis-single-node/README.adoc
new file mode 100644
index 0000000..59f3570
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/README.adoc
@@ -0,0 +1,96 @@
+= MicroProfile Open Liberty with Redis sample
+
+This project is intent to be a sample for MicroProfile with Redis single node integration by using Jakarta NoSQL implementation.
+
+== Setup Redis
+
+image::https://jnosql.github.io/img/logos/redis.png[Redis Project,align="center" width=25%,height=25%]
+
+https://redis.com/[Redis] is a software project that implements data structure servers.
+It is open-source, networked, in-memory, and stores keys with optional durability.
+
+The project is configured to reach out a Redis instance with the following configuration defined on the file `src/main/resources/META-INF/microprofile-config.properties`. More info about it, check the following link: https://github.com/eclipse/jnosql-databases?tab=readme-ov-file#configuration-14
+
+[source,properties]
+----
+include::src/main/resources/META-INF/microprofile-config.properties[]
+----
+*PS:warning:* Pay attention to that when you try to set up your own Redis instance.
+
+== Using Docker Compose
+
+The easier way to execute this project is to use the provided docker-compose.yaml file in the root directory.
+You can run it by performing the following command:
+
+[source, bash]
+----
+docker-compose up -d
+----
+
+== Local installation
+
+Follow the instructions in: https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/
+
+== Using Docker
+
+1. Install docker: https://www.docker.com/
+2. https://hub.docker.com/_/redis
+3. Run docker command
+
+[source, bash]
+----
+docker run -d --name redis-instance -p 6379:6379 redis
+----
+
+== Run the code
+
+The generation of the executable jar file can be performed by issuing the following command
+[source, bash]
+----
+mvn clean package
+----
+
+This will create an executable jar file **microprofile-liberty-redis.jar** within the _target_ maven folder. This can be started by executing the following command
+
+[source, bash]
+----
+java -jar target/microprofile-liberty-redis.jar
+----
+
+=== Liberty Dev Mode
+
+During development, you can use Liberty's development mode (dev mode) to code while observing and testing your changes on the fly.
+With the dev mode, you can code along and watch the change reflected in the running server right away;
+unit and integration tests are run on pressing Enter in the command terminal; you can attach a debugger to the running server at any time to step through your code.
+
+[source, bash]
+----
+mvn liberty:dev
+----
+
+
+
+
+To launch the test page, open your browser at the following URL
+
+[source, text]
+----
+http://localhost:9080/index.html
+----
+
+
+=== Specification examples
+
+By default, there is always the creation of a JAX-RS application class to define the path on which the JAX-RS endpoints are available.
+
+Also, a simple Hello world endpoint is created, have a look at the class **HelloController**.
+
+More information on MicroProfile can be found [here](https://microprofile.io/)
+
+
+=== Config
+
+Configuration of your application parameters. Specification [here](https://microprofile.io/project/eclipse/microprofile-config)
+
+The example class **ConfigTestController** shows you how to inject a configuration parameter and how you can retrieve it programmatically.
+
diff --git a/microprofile-liberty-redis-single-node/README.txt b/microprofile-liberty-redis-single-node/README.txt
new file mode 100644
index 0000000..0e4c219
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/README.txt
@@ -0,0 +1,35 @@
+After you generate a starter project, these instructions will help you with what to do next.
+
+The Open Liberty starter gives you a simple, quick way to get the necessary files to start building
+an application on Open Liberty. There is no need to search how to find out what to add to your
+Maven build files. A simple RestApplication.java file is generated for you to start
+creating a REST based application. A server.xml configuration file is provided with the necessary
+features for the MicroProfile and Jakarta EE versions that you previously selected.
+
+If you plan on developing and/or deploying your app in a containerized environment, the included
+Dockerfile will make it easier to create your application image on top of the Open Liberty Docker
+image.
+
+1) Once you download the starter project, unpackage the .zip file on your machine.
+2) Open a command line session, navigate to the installation directory, and run `./mvnw liberty:dev` (Linux/Mac) or `mvnw liberty:dev` (Windows).
+ This will install all required dependencies and start the default server. When complete, you will
+ see the necessary features installed and the message "server is ready to run a smarter planet."
+
+For information on developing your application in dev mode using Maven, see the
+dev mode documentation (https://openliberty.io/docs/latest/development-mode.html).
+
+For further help on getting started actually developing your application, see some of our
+MicroProfile guides (https://openliberty.io/guides/?search=microprofile&key=tag) and Jakarta EE
+guides (https://openliberty.io/guides/?search=jakarta%20ee&key=tag).
+
+If you have problems building the starter project, make sure the Java SE version on your
+machine matches the Java SE version you picked from the Open Liberty starter on the downloads
+page (https://openliberty.io/downloads/). You can test this with the command `java -version`.
+
+Open Liberty performs at its best when running using Open J9 which can be obtained via IBM Semeru
+(https://developer.ibm.com/languages/java/semeru-runtimes/downloads/). For a full list of supported
+Java SE versions and where to obtain them, reference the Java SE support page
+(https://openliberty.io/docs/latest/java-se.html).
+
+If you find any issues with the starter project or have recommendations to improve it, open an
+issue in the starter GitHub repo (https://github.com/OpenLiberty/start.openliberty.io).
diff --git a/microprofile-liberty-redis-single-node/docker-compose.yaml b/microprofile-liberty-redis-single-node/docker-compose.yaml
new file mode 100644
index 0000000..962e04c
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/docker-compose.yaml
@@ -0,0 +1,15 @@
+version: "3"
+
+services:
+ redis-single-node:
+ container_name: "redis-single-node"
+ image: redis
+ command: redis-server
+ ports:
+ - "6379:6379"
+ volumes:
+ - redis-single-node-data:/data
+
+volumes:
+ redis-single-node-data:
+ driver: local
\ No newline at end of file
diff --git a/microprofile-liberty-redis-single-node/mvnw b/microprofile-liberty-redis-single-node/mvnw
new file mode 100755
index 0000000..b7f0646
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/mvnw
@@ -0,0 +1,287 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.1.1
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /usr/local/etc/mavenrc ] ; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME
+ else
+ JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ 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
+ else
+ JAVACMD="`\\unset -f command; \\command -v java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ printf '%s' "$(cd "$basedir"; pwd)"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=$(find_maven_basedir "$(dirname $0)")
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ else
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $wrapperUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ QUIET="--quiet"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ QUIET=""
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
+ else
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
+ fi
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
+ elif command -v curl > /dev/null; then
+ QUIET="--silent"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ QUIET=""
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
+ else
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
+ fi
+ [ $? -eq 0 ] || rm -f "$wrapperJarPath"
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaSource=`cygpath --path --windows "$javaSource"`
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaSource" ]; then
+ if [ ! -e "$javaClass" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaSource")
+ fi
+ if [ -e "$javaClass" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microprofile-liberty-redis-single-node/mvnw.cmd b/microprofile-liberty-redis-single-node/mvnw.cmd
new file mode 100644
index 0000000..474c9d6
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/mvnw.cmd
@@ -0,0 +1,187 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.1.1
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %WRAPPER_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/microprofile-liberty-redis-single-node/pom.xml b/microprofile-liberty-redis-single-node/pom.xml
new file mode 100644
index 0000000..fa1afa3
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+
+ org.jnosql
+ demo-ee
+ 1.0.1
+
+ org.jnosql.demoee
+ microprofile-liberty-redis-single-node
+ MicroProfile app using OpenLiberty and Redis Single Node
+ war
+
+
+ 17
+ 17
+ 1.1.3-SNAPSHOT
+
+ 1.1.1
+ UTF-8
+
+
+
+
+ jakarta.platform
+ jakarta.jakartaee-api
+ 10.0.0
+ provided
+
+
+ org.eclipse.microprofile
+ microprofile
+ 6.1
+ pom
+ provided
+
+
+ org.eclipse.jnosql.databases
+ jnosql-redis
+ ${jnosql.version}
+
+
+
+
+ microprofile-liberty-redis
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.3.2
+
+
+ io.openliberty.tools
+ liberty-maven-plugin
+ 3.11.1
+
+
+
+
+
+ io.openliberty.tools
+ liberty-maven-plugin
+
+
+
+
diff --git a/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/RestApplication.java b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/RestApplication.java
new file mode 100644
index 0000000..f5305dd
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/RestApplication.java
@@ -0,0 +1,9 @@
+package org.jnosql.demoee;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class RestApplication extends Application {
+
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/Hero.java b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/Hero.java
new file mode 100644
index 0000000..32d1724
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/Hero.java
@@ -0,0 +1,60 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.nosql.Column;
+import jakarta.nosql.Entity;
+import jakarta.nosql.Id;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+
+import java.util.Objects;
+import java.util.Set;
+
+@Entity
+@Schema
+public record Hero(
+ @Id
+ @Schema(required = true)
+ Integer id,
+ @Column
+ @Schema
+ String name,
+ @Column
+ @Schema
+ String secretIdentity,
+ @Column
+ @Schema
+ String impactPhrase
+) {
+
+ public static Hero newHero(String name, String secretIdentity, String impactPhrase) {
+ return new Hero(Objects.hash(name, secretIdentity, impactPhrase), name, secretIdentity, impactPhrase);
+ }
+
+ public boolean nameMatchesWith(String name) {
+ return fuzzySearch(name, this.name());
+ }
+
+ public boolean secretIdentityMatchesWith(String pattern) {
+ return fuzzySearch(pattern, this.secretIdentity());
+ }
+
+ public boolean impactPhraseMatchesWith(String pattern) {
+ return fuzzySearch(pattern, this.impactPhrase());
+ }
+
+ private boolean isNotSearchable(String value) {
+ return value == null || value.isBlank();
+ }
+
+ public Set splitPhrase(String phrase) {
+ return Set.of(phrase.split("[.,\\s]"));
+ }
+
+ public boolean fuzzySearch(String source, String target) {
+ if (isNotSearchable(source) || isNotSearchable(target)) {
+ return false;
+ }
+ Set words = splitPhrase(source.toLowerCase());
+ return words.stream().anyMatch(target.toLowerCase()::contains);
+ }
+
+}
diff --git a/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/Heroes.java b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/Heroes.java
new file mode 100644
index 0000000..28fa45a
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/Heroes.java
@@ -0,0 +1,74 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.eclipse.jnosql.mapping.keyvalue.KeyValueDatabase;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+@ApplicationScoped
+public class Heroes {
+
+ @Inject
+ @KeyValueDatabase("heroes")
+ Map heroes;
+
+ public Iterable findHeroesBy(HeroesQuery heroesQuery) {
+
+ var nameMatches = Optional
+ .ofNullable(heroesQuery.name())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.nameMatchesWith(m))
+ .orElse(null);
+
+ var secretIdentityMatches = Optional
+ .ofNullable(heroesQuery.secretIdentity())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.secretIdentityMatchesWith(m))
+ .orElse(null);
+
+ var impactPhraseMatches = Optional
+ .ofNullable(heroesQuery.impactPhrase())
+ .filter(Predicate.not(String::isBlank))
+ .map(m -> (Predicate) h -> h.impactPhraseMatchesWith(m))
+ .orElse(null);
+
+ var matcherFilters = Arrays.stream(new Predicate[]{
+ nameMatches,
+ secretIdentityMatches,
+ impactPhraseMatches})
+ .filter(Objects::nonNull)
+ .reduce((a, b) -> a.or(b));
+
+
+ if (matcherFilters.isPresent()) {
+
+ return heroes.values()
+ .stream()
+ .filter(matcherFilters.orElse(h -> false)).toList();
+ }
+
+ return heroes.values().stream().toList();
+ }
+
+ public Optional getById(Integer id) {
+ return Optional.ofNullable(heroes.get(id));
+ }
+
+ public Hero add(Hero hero) {
+ Objects.requireNonNull(hero, "hero is required");
+ heroes.put(hero.id(), hero);
+ return hero;
+ }
+
+ public Optional remove(Integer id) {
+ return Optional.ofNullable(id)
+ .flatMap(existentId -> Optional.ofNullable(heroes.remove(existentId)));
+ }
+
+
+}
diff --git a/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java
new file mode 100644
index 0000000..5742cdf
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesApplicationInitializer.java
@@ -0,0 +1,36 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.Initialized;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
+import org.eclipse.jnosql.mapping.keyvalue.KeyValueDatabase;
+
+import java.util.Map;
+
+import static java.util.Set.of;
+import static org.jnosql.demoee.heroes.Hero.newHero;
+
+@ApplicationScoped
+public class HeroesApplicationInitializer {
+
+ @Inject
+ @KeyValueDatabase("heroes")
+ Map heroes;
+
+ public void onInitialized(@Observes @Initialized(ApplicationScoped.class) Object event) {
+ of(
+ newHero("Superman", "Clark Kent", "Up, up and away!"),
+ newHero("Batman", "Bruce Wayne", "I am vengeance, I am the night!"),
+ newHero("Wonder", "Diana Prince", "I will fight for those who cannot fight for themselves!"),
+ newHero("Flash", "Barry Allen", "Life doesn't give us purpose. We give life purpose!"),
+ newHero("Green Lantern", "Hal Jordan", "In brightest day, in blackest night, no evil shall escape my sight!"),
+ newHero("Aquaman", "Arthur Curry", "I don't belong to the land or the sea!"),
+ newHero("Cyborg", "Victor Stone", "I'm not broken, and I'm not alone!"),
+ newHero("Shazam", "Billy Batson", "Shazam!")
+ )
+ .stream()
+ .filter(hero -> !heroes.containsKey(hero.id()))
+ .forEach(hero -> heroes.put(hero.id(), hero));
+ }
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java
new file mode 100644
index 0000000..b227c84
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesQuery.java
@@ -0,0 +1,35 @@
+package org.jnosql.demoee.heroes;
+
+public record HeroesQuery(String name, String secretIdentity, String impactPhrase) {
+
+ static QueryBuilder queryBuilder() {
+ return new QueryBuilder();
+ }
+
+ public static class QueryBuilder {
+
+ private String name;
+ private String secretIdentity;
+ private String impactPhrase;
+
+ public QueryBuilder byName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public QueryBuilder bySecretIdentity(String secretIdentity) {
+ this.secretIdentity = secretIdentity;
+ return this;
+ }
+
+ public QueryBuilder byImpactPhrase(String impactPhrase) {
+ this.impactPhrase = impactPhrase;
+ return this;
+ }
+
+ public HeroesQuery build() {
+ return new HeroesQuery(name, secretIdentity, impactPhrase);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java
new file mode 100644
index 0000000..442d628
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/java/org/jnosql/demoee/heroes/HeroesResource.java
@@ -0,0 +1,79 @@
+package org.jnosql.demoee.heroes;
+
+import jakarta.inject.Inject;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+
+import static org.jnosql.demoee.heroes.HeroesQuery.queryBuilder;
+
+@Path("/heroes")
+@Produces({MediaType.APPLICATION_JSON})
+@Consumes({MediaType.APPLICATION_JSON})
+public class HeroesResource {
+
+ @Inject
+ Heroes heroes;
+
+ @GET
+ public Iterable heroes(
+ @QueryParam("name") String name,
+ @QueryParam("secretIdentity") String secretIdentity,
+ @QueryParam("impactPhrase") String impactPhrase
+ ) {
+
+ return heroes.findHeroesBy(queryBuilder()
+ .byName(name)
+ .bySecretIdentity(secretIdentity)
+ .byImpactPhrase(impactPhrase).build());
+
+ }
+
+ @GET
+ @Path("/{id}")
+ public Hero getHeroById(
+ @PathParam("id")
+ @Schema(required = true) final Integer id) {
+ return heroes.getById(id)
+ .orElseThrow(() -> new NotFoundException("Hero not found"));
+ }
+
+ @Schema
+ public record NewHero(
+ @NotBlank
+ @Schema
+ String name,
+ @Schema
+ String secretIdentity,
+ @Schema
+ String impactPhrase) {
+ Hero toEntity() {
+ return Hero.newHero(name(), secretIdentity(), impactPhrase());
+ }
+ }
+
+ @POST
+ public Hero add(@Valid NewHero request) {
+ var newHero = request.toEntity();
+ return heroes.add(newHero);
+ }
+
+ @DELETE
+ @Path("/{id}")
+ public Hero delete(@PathParam("id")
+ @Schema(required = true) final Integer id) {
+ return this.heroes.remove(id).orElseThrow(() -> new NotFoundException("Hero not found"));
+ }
+
+
+}
diff --git a/microprofile-liberty-redis-single-node/src/main/liberty/config/server.xml b/microprofile-liberty-redis-single-node/src/main/liberty/config/server.xml
new file mode 100644
index 0000000..4153670
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/liberty/config/server.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ jakartaee-10.0
+ microProfile-6.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/microprofile-liberty-redis-single-node/src/main/resources/META-INF/microprofile-config.properties b/microprofile-liberty-redis-single-node/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..35d1cd9
--- /dev/null
+++ b/microprofile-liberty-redis-single-node/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,10 @@
+jnosql.keyvalue.provider=org.eclipse.jnosql.databases.redis.communication.RedisConfiguration
+jnosql.keyvalue.database=heroes
+
+# Single Node Configuration
+jnosql.redis.host=localhost
+jnosql.redis.port=6379
+# if you have user
+# jnosql.redis.user=youruser
+# if you have password
+# jnosql.redis.password=yourpassword
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index fcb67ee..3c074f0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,9 @@
quarkus-jnosql-oracle-nosql
quarkus-jnosql-lite
quarkus-pagination
+ microprofile-liberty-redis-single-node
+ microprofile-liberty-redis-sentinel
+ microprofile-liberty-redis-cluster
diff --git a/quarkus-pagination/pom.xml b/quarkus-pagination/pom.xml
index 174d0fe..1e51eda 100644
--- a/quarkus-pagination/pom.xml
+++ b/quarkus-pagination/pom.xml
@@ -7,7 +7,7 @@
3.12.1
- 21
+ 17
UTF-8
UTF-8
quarkus-bom