diff --git a/java/jdbc/SpringSharding/JDBCTemplate/.gitignore b/java/jdbc/SpringSharding/JDBCTemplate/.gitignore
new file mode 100644
index 00000000..7ed0d6b6
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/.gitignore
@@ -0,0 +1,32 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/LICENSE.txt b/java/jdbc/SpringSharding/JDBCTemplate/LICENSE.txt
new file mode 100644
index 00000000..fe1109d4
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/LICENSE.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2023 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/README.md b/java/jdbc/SpringSharding/JDBCTemplate/README.md
new file mode 100644
index 00000000..e8ff07bc
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/README.md
@@ -0,0 +1,101 @@
+## Overview
+
+This project demonstrates the use of the latest sharding [feature](https://github.com/spring-projects/spring-framework/pull/31506) in Spring Framework with the Oracle Database.
+The feature is about supporting direct routing to sharded databases.
+
+This version uses Spring Data JDBC (JdbcTemplate), for data access.
+
+You can use the datasource configurations provided in this project as a template for setting up the sharding feature in your own projects.
+
+## Configuration
+
+### Database
+
+You can refer to the [Oracle Docs](https://docs.oracle.com/en/database/oracle/oracle-database/21/shard/sharding-deployment.html#GUID-F99B8742-4089-4E77-87D4-4691EA932207)
+to learn how to set up and deploy an Oracle sharded database.
+You can also refer to [Oracle Database Operator](https://github.com/oracle/oracle-database-operator) that makes deploying a sharded database on a Kubernetes Cluster an easy process.
+
+After your sharded database is set, connect to the shard catalog as sysdba and create the demo application schema user.
+
+~~~SQL
+ALTER SESSION ENABLE SHARD DDL;
+
+-- Create demo schema user
+CREATE USER demo_user IDENTIFIED BY demo_user;
+GRANT CONNECT, RESOURCE TO demo_user;
+GRANT CREATE TABLE TO demo_user;
+GRANT UNLIMITED TABLESPACE TO demo_user;
+
+-- Create tablespace
+CREATE TABLESPACE SET TS1 USING TEMPLATE (
+ DATAFILE SIZE 10M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED
+ EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO);
+~~~
+
+On the shard catalog connect as demo_user and run the following SQL script to create your tables.
+
+~~~SQL
+ALTER SESSION ENABLE SHARD DDL;
+
+CREATE SHARDED TABLE users (
+ user_id NUMBER PRIMARY KEY,
+ name VARCHAR2(100),
+ password VARCHAR2(255),
+ role VARCHAR2(5),
+CONSTRAINT roleCheck CHECK (role IN ('USER', 'ADMIN')))
+TABLESPACE SET TS1 PARTITION BY CONSISTENT HASH (user_id);
+
+CREATE SHARDED TABLE notes (
+ note_id NUMBER NOT NULL,
+ user_id NUMBER NOT NULL,
+ title VARCHAR2(255),
+ content CLOB,
+CONSTRAINT notePK PRIMARY KEY (note_id, user_id),
+CONSTRAINT userFK FOREIGN KEY (user_id) REFERENCES users(user_id))
+PARTITION BY REFERENCE (UserFK);
+
+CREATE SEQUENCE note_sequence INCREMENT BY 1 START WITH 1 MAXVALUE 2E9 SHARD;
+~~~
+
+Make sure to insert a user or two in the database before testing the application.
+
+~~~SQL
+INSERT INTO users VALUES (0, 'user1', LOWER(STANDARD_HASH('user1', 'SHA256')), 'USER');
+INSERT INTO users VALUES (1, 'admin', LOWER(STANDARD_HASH('admin', 'SHA256')), 'ADMIN');
+COMMIT;
+~~~
+
+To uninstall and clean up the preceding setup, you can connect as sysdba and run the following SQL script.
+
+~~~SQL
+ALTER SESSION ENABLE SHARD DDL;
+
+DROP USER demo_user CASCADE;
+DROP TABLESPACE SET TS1;
+~~~
+
+## Building the application
+To build the application run:
+
+~~~
+mvn install
+~~~
+
+## Running the application
+
+Before running the application set the following environment variables or update [application.properties](src/main/resources/application.properties). These configure the URL and credentials for the catalog database and shard director (GSM) used by the application.
+
+~~~shell
+export CATALOG_URL="the catalog url"
+export CATALOG_USER="demo_user"
+export CATALOG_PASS="demo_user"
+export SHARD_DIRECTOR_URL="the shard director url"
+export SHARD_DIRECTOR_USER="demo_user"
+export SHARD_DIRECTOR_PASS="demo_user"
+~~~
+
+Then you can run the application using:
+
+~~~shell
+mvn spring-boot:run
+~~~
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/api.yaml b/java/jdbc/SpringSharding/JDBCTemplate/api.yaml
new file mode 100644
index 00000000..69f06acd
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/api.yaml
@@ -0,0 +1,256 @@
+openapi: 3.0.3
+info:
+ title: Notes
+ description: This API keeps track of user notes.
+ license:
+ name: The Universal Permissive License (UPL), version 1.0
+ url: https://www.oracle.com/downloads/licenses/upl-license.html
+ version: 0.0.1
+paths:
+ /users:
+ get:
+ description: Lists all users if authenticated user is admin, otherwise gets current authenticated user
+ operationId: getUsers
+ responses:
+ "200":
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/UserDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ /users/{userId}/notes:
+ post:
+ description: Adds a note to a user
+ operationId: addNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ responses:
+ "201":
+ description: user added successfully
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ResponseNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user not found
+
+ get:
+ description: Lists all notes for a given user
+ operationId: getNotesForUser
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ responses:
+ "200":
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user not found
+
+ /users/{userId}/notes/{noteId}:
+ get:
+ description: Gets a note for a user
+ operationId: getNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ - name: noteId
+ in: path
+ description: the note identifier
+ required: true
+ schema:
+ type: integer
+ responses:
+ "200":
+ description: user added successfully
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ResponseNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user or note not found
+
+ put:
+ description: Updates a note for a user
+ operationId: updateNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ - name: noteId
+ in: path
+ description: the note identifier
+ required: true
+ schema:
+ type: integer
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ responses:
+ "200":
+ description: user added successfully
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ResponseNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user or note not found
+
+ delete:
+ description: deletes a note for a user
+ operationId: deleteNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ - name: noteId
+ in: path
+ description: the note identifier
+ required: true
+ schema:
+ type: integer
+ responses:
+ "200":
+ description: user added successfully
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user or note not found
+
+ /users/all/notes:
+ get:
+ description: Lists all notes for all users (admin only)
+ operationId: getAllNotes
+ security:
+ - basicAuth: [ ]
+ - cookieAuth: [ ]
+ responses:
+ "200":
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+
+components:
+ schemas:
+ RequestNoteDTO:
+ type: object
+ properties:
+ title:
+ type: string
+ description: title of the note
+ example: Title of my first note
+ content:
+ type: string
+ description: content of the note
+ example: Contents of my first note
+ ResponseNoteDTO:
+ type: object
+ properties:
+ userId:
+ type: integer
+ description: user identifier
+ example: 3
+ noteId:
+ type: integer
+ description: note identifier
+ example: 108
+ title:
+ type: string
+ description: title of the note
+ example: Title of my first note
+ content:
+ type: string
+ description: content of the note
+ example: Contents of my first note
+ UserDTO:
+ type: object
+ properties:
+ id:
+ type: integer
+ description: User identifier
+ example: 99
+ username:
+ type: string
+ description: Username
+ example: user1
+ role:
+ type: string
+ description: role of the user can be USER or ADMIN
+ example: USER
+
+ securitySchemes:
+ cookieAuth:
+ type: apiKey
+ in: cookie
+ name: JSESSIONID
+ basicAuth:
+ type: http
+ scheme: basic
+
+security:
+ - basicAuth: [ ]
+ - cookieAuth: [ ]
+
+servers:
+ - url: http://localhost:8080
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/mvnw b/java/jdbc/SpringSharding/JDBCTemplate/mvnw
new file mode 100755
index 00000000..66df2854
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/mvnw
@@ -0,0 +1,308 @@
+#!/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
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.2.0
+#
+# 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" ] && [ -d "$JAVA_HOME" ] &&
+ JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); 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 2>/dev/null; \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/.." || exit 1; pwd)
+ fi
+ # end of workaround
+ done
+ printf '%s' "$(cd "$basedir" || exit 1; pwd)"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ # Remove \r in case we run on Windows within Git Bash
+ # and check out the repository with auto CRLF management
+ # enabled. Otherwise, we may read lines that are delimited with
+ # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
+ # splitting rules.
+ tr -s '\r\n' ' ' < "$1"
+ fi
+}
+
+log() {
+ if [ "$MVNW_VERBOSE" = true ]; then
+ printf '%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
+log "$MAVEN_PROJECTBASEDIR"
+
+##########################################################################################
+# 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.
+##########################################################################################
+wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
+if [ -r "$wrapperJarPath" ]; then
+ log "Found $wrapperJarPath"
+else
+ log "Couldn't find $wrapperJarPath, downloading it ..."
+
+ if [ -n "$MVNW_REPOURL" ]; then
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+ else
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+ fi
+ while IFS="=" read -r key value; do
+ # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
+ safeValue=$(echo "$value" | tr -d '\r')
+ case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
+ esac
+ done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+ log "Downloading from: $wrapperUrl"
+
+ if $cygwin; then
+ wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
+ fi
+
+ if command -v wget > /dev/null; then
+ log "Found wget ... using wget"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ log "Found curl ... using curl"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+ else
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+ fi
+ else
+ log "Falling back to using Java to download"
+ javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$MAVEN_PROJECTBASEDIR/.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
+ log " - Compiling MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/javac" "$javaSource")
+ fi
+ if [ -e "$javaClass" ]; then
+ log " - Running MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+# If specified, validate the SHA-256 sum of the Maven wrapper jar file
+wrapperSha256Sum=""
+while IFS="=" read -r key value; do
+ case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
+ esac
+done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+if [ -n "$wrapperSha256Sum" ]; then
+ wrapperSha256Result=false
+ if command -v sha256sum > /dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ elif command -v shasum > /dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
+ echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
+ exit 1
+ fi
+ if [ $wrapperSha256Result = false ]; then
+ echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
+ echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
+ echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
+ exit 1
+ fi
+fi
+
+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
+
+# shellcheck disable=SC2086 # safe args
+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/java/jdbc/SpringSharding/JDBCTemplate/mvnw.cmd b/java/jdbc/SpringSharding/JDBCTemplate/mvnw.cmd
new file mode 100644
index 00000000..95ba6f54
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/mvnw.cmd
@@ -0,0 +1,205 @@
+@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 https://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.2.0
+@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.2.0/maven-wrapper-3.2.0.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.2.0/maven-wrapper-3.2.0.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 If specified, validate the SHA-256 sum of the Maven wrapper jar file
+SET WRAPPER_SHA_256_SUM=""
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
+)
+IF NOT %WRAPPER_SHA_256_SUM%=="" (
+ powershell -Command "&{"^
+ "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
+ "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
+ " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
+ " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
+ " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
+ " exit 1;"^
+ "}"^
+ "}"
+ if ERRORLEVEL 1 goto error
+)
+
+@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/java/jdbc/SpringSharding/JDBCTemplate/pom.xml b/java/jdbc/SpringSharding/JDBCTemplate/pom.xml
new file mode 100644
index 00000000..8d24bc27
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.2
+
+
+ com.oracle.jdbc.sample
+ shardingwithspring
+ 0.0.1-SNAPSHOT
+ ShardingWithSpring
+ Demo application for using sharding with spring
+
+ 17
+ 23.3.0.23.09
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jdbc
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ com.oracle.database.jdbc
+ ojdbc11
+ ${ojdbc.version}
+
+
+
+ com.oracle.database.jdbc
+ ucp11
+ ${ojdbc.version}
+
+
+
+ com.oracle.database.ha
+ ons
+ ${ojdbc.version}
+
+
+
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/ShardingApplication.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/ShardingApplication.java
new file mode 100644
index 00000000..c8529550
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/ShardingApplication.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ShardingApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(ShardingApplication.class, args);
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/CatalogDataSourceConfig.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/CatalogDataSourceConfig.java
new file mode 100644
index 00000000..6ac81a67
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/CatalogDataSourceConfig.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.configuration;
+
+import oracle.ucp.jdbc.PoolDataSource;
+import oracle.ucp.jdbc.PoolDataSourceFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.support.JdbcTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+/**
+ * A catalog datasource is used to execute cross-shard queries, or in all cases where we can not build a sharding key.
+ */
+@Configuration
+@EnableTransactionManagement
+public class CatalogDataSourceConfig {
+ @Value("${oracle.database.catalog.url}")
+ String url;
+ @Value("${oracle.database.catalog.username}")
+ String user;
+ @Value("${oracle.database.catalog.password}")
+ String password;
+
+ /**
+ * Bean definition of the catalog database connection pool.
+ *
+ * @return A DataSource representing the catalog database connection pool.
+ */
+ @Bean
+ @Primary
+ DataSource dataSource() throws SQLException {
+ // This is a UCP DataSource
+ PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
+
+ dataSource.setURL(url);
+ dataSource.setUser(user);
+ dataSource.setPassword(password);
+ dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
+ dataSource.setInitialPoolSize(1);
+ dataSource.setMinPoolSize(1);
+ dataSource.setMaxPoolSize(20);
+
+
+ return dataSource;
+ }
+
+ /**
+ * JdbcTemplate bean definition that uses the catalog connection pool.
+ *
+ * @return A JdbcTemplate instance associated with the catalog connection pool
+ */
+ @Bean
+ @Primary
+ public JdbcTemplate jdbcTemplate(
+ @Qualifier("dataSource") DataSource dataSource) {
+ return new JdbcTemplate(dataSource);
+ }
+
+ /**
+ * TransactionManager bean definition that is associated with the catalog connection pool
+ *
+ * @return A PlatformTransactionManager instance associated with the catalog connection pool
+ */
+ @Bean
+ @Primary
+ public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
+ return new JdbcTransactionManager(dataSource);
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/DirectShardDataSourceConfig.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/DirectShardDataSourceConfig.java
new file mode 100644
index 00000000..3484682b
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/DirectShardDataSourceConfig.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.configuration;
+
+import jakarta.servlet.http.HttpServletRequest;
+import oracle.jdbc.OracleType;
+import oracle.jdbc.pool.OracleShardingKeyBuilderImpl;
+import oracle.ucp.jdbc.PoolDataSource;
+import oracle.ucp.jdbc.PoolDataSourceFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.ShardingKeyProvider;
+import org.springframework.jdbc.datasource.ShardingKeyDataSourceAdapter;
+import org.springframework.jdbc.support.JdbcTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.servlet.HandlerMapping;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.sql.ShardingKey;
+import java.util.Map;
+
+/**
+ * A Direct Shard Datasource is used to establish connections to the shard directors, it should be used in cases where
+ * we only need to connect to a single shard which is identified by providing a sharding key.
+ */
+@Configuration
+@EnableTransactionManagement
+public class DirectShardDataSourceConfig {
+ @Value("${oracle.database.directshard.url}")
+ private String url;
+ @Value("${oracle.database.directshard.username}")
+ private String user;
+ @Value("${oracle.database.directshard.password}")
+ private String password;
+
+ private final HttpServletRequest httpRequest;
+
+ public DirectShardDataSourceConfig(HttpServletRequest httpRequest) {
+ this.httpRequest = httpRequest;
+ }
+
+ /**
+ * Bean definition of the ShardingKeyProvider. The sharding key is extracted from the http request path variables.
+ *
+ * @return A ShardingKeyProvider that gets the sharding key from the http request path variables.
+ */
+ @Bean
+ ShardingKeyProvider shardingKeyProvider() {
+ return new ShardingKeyProvider() {
+ public ShardingKey getShardingKey() throws SQLException {
+ // On start up hibernates opens a connection to the database to do some initial setup, not setting
+ // a sharding key causes UCP to throw an exception, to avoid this problem we initialize the sharding key
+ // with -1
+ Long shardingKey = -1L;
+
+ // Get the sharding key (userId) from the request path variables
+ if (RequestContextHolder.getRequestAttributes() != null) {
+ Object httpAttributes = httpRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
+ Map pathVariables = (Map) httpAttributes;
+
+ if (pathVariables.containsKey("userId")) {
+ shardingKey = Long.parseLong(pathVariables.get("userId"));
+ }
+ }
+
+ return new OracleShardingKeyBuilderImpl().subkey(shardingKey, OracleType.NUMBER).build();
+ }
+ // We don't have a super sharding key
+ public ShardingKey getSuperShardingKey() {
+ return null;
+ }
+ };
+ }
+
+ /**
+ * Bean definition of the Direct Shard connection pool.
+ * The created Datasource is an instance of the ShardingKeyDataSourceAdapter, it allows setting direct
+ * connections to specific shards identified by a shardingKey.
+ * The shardingKey, used to identify the shards, is extracted using the {@link #shardingKeyProvider}.
+ *
+ * @return A DataSource representing the Direct Shard connection pool.
+ */
+ @Bean
+ public DataSource directShardDataSource(ShardingKeyProvider shardingKeyProvider) throws SQLException {
+ // This is a UCP DataSource
+ PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
+
+ dataSource.setURL(url);
+ dataSource.setUser(user);
+ dataSource.setPassword(password);
+ dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
+ // We are setting the initial pool size to 0 because if we create a connection without setting a sharding key
+ // they would all point to a single shard, because we initialize the sharding key with -1.
+ dataSource.setInitialPoolSize(0);
+ dataSource.setMinPoolSize(0);
+ dataSource.setMaxPoolSize(20);
+
+ return new ShardingKeyDataSourceAdapter(dataSource, shardingKeyProvider);
+ }
+
+ /**
+ * JdbcTemplate bean definition that uses the Direct Shard Connection Pool.
+ *
+ * @return A JdbcTemplate instance associated with the Direct Shard Connection Pool
+ */
+ @Bean
+ public JdbcTemplate directShardJdbcTemplate(@Qualifier("directShardDataSource") DataSource dataSource) {
+ return new JdbcTemplate(dataSource);
+ }
+
+ /**
+ * TransactionManager bean definition that is associated with the Direct Shard Connection Pool.
+ *
+ * @return A PlatformTransactionManager instance associated with the Direct Shard Connection Pool
+ */
+ @Bean
+ public PlatformTransactionManager directShardTransactionManager(@Qualifier("directShardDataSource") DataSource dataSource) {
+ return new JdbcTransactionManager(dataSource);
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/SecurityConfig.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/SecurityConfig.java
new file mode 100644
index 00000000..4e2be541
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/SecurityConfig.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.configuration;
+
+import com.oracle.jdbc.samples.springsharding.model.User;
+import com.oracle.jdbc.samples.springsharding.service.UserService;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.access.expression.DefaultHttpSecurityExpressionHandler;
+import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig {
+ private final UserService userService;
+ private final ApplicationContext applicationContext;
+
+ public SecurityConfig(UserService userService, ApplicationContext applicationContext) {
+ this.userService = userService;
+ this.applicationContext = applicationContext;
+ }
+
+ /**
+ * Checks that the authenticated user matches the user passed as argument, or is an admin.
+ *
+ * @param authentication The authentication object
+ * @param userId The ID of the user to verify
+ * @return true if authenticated user is same as userId or is an ADMIN, false otherwise
+ */
+ public boolean check(Authentication authentication, Long userId) {
+ if (authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ADMIN")))
+ return true;
+
+ if (authentication.getPrincipal() instanceof User)
+ return ((User) authentication.getPrincipal()).getId().equals(userId);
+ return false;
+ }
+
+ private WebExpressionAuthorizationManager getWebExpressionAuthorizationManager(final String expression) {
+ final var expressionHandler = new DefaultHttpSecurityExpressionHandler();
+ expressionHandler.setApplicationContext(applicationContext);
+ final var authorizationManager = new WebExpressionAuthorizationManager(expression);
+ authorizationManager.setExpressionHandler(expressionHandler);
+
+ return authorizationManager;
+ }
+
+ @Bean
+ SecurityFilterChain SecurityFilterChain(HttpSecurity http) throws Exception {
+ http.csrf(AbstractHttpConfigurer::disable)
+ .authorizeHttpRequests((requests) -> requests
+ .requestMatchers("/users/all/notes").hasAuthority("ADMIN")
+ .requestMatchers("/users/{userId}/**")
+ .access(getWebExpressionAuthorizationManager("@securityConfig.check(authentication,#userId)"))
+ .anyRequest().authenticated());
+
+ // This enables cookie authentication
+ http.sessionManagement((sm) -> sm.sessionCreationPolicy(SessionCreationPolicy.ALWAYS));
+
+ http.httpBasic(Customizer.withDefaults());
+
+ return http.build();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new MessageDigestPasswordEncoder("SHA-256");
+ }
+
+ @Bean
+ public AuthenticationProvider daoAuthenticationProvider() {
+ DaoAuthenticationProvider daoAuthProvider = new DaoAuthenticationProvider();
+
+ daoAuthProvider.setPasswordEncoder(passwordEncoder());
+ daoAuthProvider.setUserDetailsService(userService);
+
+ return daoAuthProvider;
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/controller/Controller.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/controller/Controller.java
new file mode 100644
index 00000000..587f0d96
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/controller/Controller.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.controller;
+
+import com.oracle.jdbc.samples.springsharding.dto.RequestNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.ResponseNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.UserDTO;
+import com.oracle.jdbc.samples.springsharding.mapper.DTOMappers;
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import com.oracle.jdbc.samples.springsharding.service.NoteService;
+import com.oracle.jdbc.samples.springsharding.service.UserService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+// We allow CORS to make it easy to test the API
+@CrossOrigin(originPatterns = "http://localhost:**")
+@org.springframework.stereotype.Controller
+@RequestMapping("/users")
+public class Controller {
+ private final NoteService noteService;
+ private final UserService userService;
+ private final DTOMappers dtoMappers;
+
+ public Controller(NoteService noteService, UserService userService, DTOMappers dtoMappers) {
+ this.noteService = noteService;
+ this.userService = userService;
+ this.dtoMappers = dtoMappers;
+ }
+
+ /**
+ * Get all users if authenticated user is admin, authenticated user otherwise.
+ */
+ @GetMapping
+ public ResponseEntity> getUsers() {
+ String role = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getRole();
+
+ List response = null;
+
+ if (role.equals("ADMIN")) {
+ response = userService.getAllUsers()
+ .stream()
+ .map(dtoMappers::userToUserDTO)
+ .collect(Collectors.toList());
+ } else {
+ response = List.of(dtoMappers.userToUserDTO(userService.getAuthenticatedUser()));
+ }
+
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ /**
+ * Add a note
+ */
+ @PostMapping(value = {"/{userId}/notes"})
+ public ResponseEntity addNote(@PathVariable Long userId,
+ @RequestBody RequestNoteDTO noteBodyDTO) {
+ Note note = dtoMappers.requestNoteDTOToNote(noteBodyDTO, null, userId);
+
+ ResponseNoteDTO response = dtoMappers.noteToResponseNoteDTO(noteService.addNote(note));
+
+ return new ResponseEntity<>(response, HttpStatus.CREATED);
+ }
+
+ /**
+ * Get all notes for all users
+ */
+ @GetMapping("/all/notes")
+ public ResponseEntity> getAllNotes() {
+ List response = noteService.getAllNotes()
+ .stream()
+ .map(dtoMappers::noteToResponseNoteDTO)
+ .collect(Collectors.toList());
+
+ return ResponseEntity.ofNullable(response);
+ }
+
+ /**
+ * Get all notes for a user
+ */
+ @GetMapping(value = {"/{userId}/notes"})
+ public ResponseEntity> getNotesForUser(@PathVariable Long userId) {
+ List notes = noteService.getNotesForUser(userId)
+ .stream()
+ .map(dtoMappers::noteToResponseNoteDTO)
+ .collect(Collectors.toList());
+
+ return ResponseEntity.ofNullable(notes);
+ }
+
+ /**
+ * Get a single note identified by userId and noteId
+ */
+ @GetMapping(value = {"/{userId}/notes/{noteId}"})
+ public ResponseEntity getNote(@PathVariable Long userId, @PathVariable Long noteId) {
+ ResponseNoteDTO response = dtoMappers.noteToResponseNoteDTO(noteService.getNote(noteId, userId));
+
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ /**
+ * Update a note
+ */
+ @PutMapping("/{userId}/notes/{noteId}")
+ public ResponseEntity updateNote(@PathVariable Long userId,
+ @PathVariable Long noteId,
+ @RequestBody RequestNoteDTO noteBodyDTO) {
+ noteService.updateNote(dtoMappers.requestNoteDTOToNote(noteBodyDTO, noteId, userId));
+
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ /**
+ * Delete a note
+ */
+ @DeleteMapping("/{userId}/notes/{noteId}")
+ public ResponseEntity deleteNote(@PathVariable Long userId, @PathVariable Long noteId) {
+ noteService.removeNote(noteId, userId);
+
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/controller/ControllerAdvice.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/controller/ControllerAdvice.java
new file mode 100644
index 00000000..05d20c28
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/controller/ControllerAdvice.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.controller;
+
+import oracle.jdbc.OracleDatabaseException;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestController;
+
+@org.springframework.web.bind.annotation.ControllerAdvice
+@RestController
+public class ControllerAdvice {
+ @ExceptionHandler({OracleDatabaseException.class, EmptyResultDataAccessException.class})
+ public ResponseEntity handleOracleDatabaseException() {
+ return ResponseEntity.status(404).build();
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/RequestNoteDTO.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/RequestNoteDTO.java
new file mode 100644
index 00000000..667a2371
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/RequestNoteDTO.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dto;
+
+public record RequestNoteDTO(
+ String title,
+ String content
+) {}
\ No newline at end of file
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/ResponseNoteDTO.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/ResponseNoteDTO.java
new file mode 100644
index 00000000..1bbfdf97
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/ResponseNoteDTO.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dto;
+
+public record ResponseNoteDTO(
+ Long id,
+ Long userId,
+ String title,
+ String content
+) {}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/UserDTO.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/UserDTO.java
new file mode 100644
index 00000000..b22a5725
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/dto/UserDTO.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dto;
+
+public record UserDTO(
+ Long id,
+ String username,
+ String role
+) {}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/DTOMappers.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/DTOMappers.java
new file mode 100644
index 00000000..73e9ead5
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/DTOMappers.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.mapper;
+
+import com.oracle.jdbc.samples.springsharding.dto.RequestNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.ResponseNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.UserDTO;
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DTOMappers {
+ public ResponseNoteDTO noteToResponseNoteDTO(Note note) {
+ return new ResponseNoteDTO(
+ note.getId(),
+ note.getUserId(),
+ note.getTitle(),
+ note.getContent());
+ }
+
+ public Note requestNoteDTOToNote(RequestNoteDTO requestNoteDTO, Long noteId, Long userId) {
+ return new Note(
+ noteId,
+ userId,
+ requestNoteDTO.title(),
+ requestNoteDTO.content()
+ );
+ }
+
+ public UserDTO userToUserDTO(User user) {
+ return new UserDTO(user.getId(), user.getUsername(), user.getRole());
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/RowMappers.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/RowMappers.java
new file mode 100644
index 00000000..401f4729
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/RowMappers.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.mapper;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.RowMapper;
+
+@Configuration
+public class RowMappers {
+ @Bean
+ public RowMapper NoteRowMapper() {
+ return (rst, rowNum) -> new Note(rst.getLong(1),
+ rst.getLong(2),
+ rst.getString(3),
+ rst.getString(4));
+ }
+
+ @Bean
+ public RowMapper UserRowMapper() {
+ return (rst, rowNum) -> new User(rst.getLong(1),
+ rst.getString(2),
+ rst.getString(3),
+ rst.getString(4));
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/model/Note.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/model/Note.java
new file mode 100644
index 00000000..9851e835
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/model/Note.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.model;
+
+public class Note {
+ private Long id;
+ private Long userId;
+ private String title;
+ private String content;
+
+ public Note(Long id, Long userId, String title, String content) {
+ this.id = id;
+ this.userId = userId;
+ this.title = title;
+ this.content = content;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/model/User.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/model/User.java
new file mode 100644
index 00000000..f24fcc43
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/model/User.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.model;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.List;
+
+public class User implements UserDetails {
+ private Long id;
+ private String userName;
+ private String password;
+ private String role;
+
+ public User(Long id, String userName, String password, String role) {
+ this.id = id;
+ this.userName = userName;
+ this.password = password;
+ this.role = role;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role);
+
+ return List.of(grantedAuthority);
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String getUsername() {
+ return userName;
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteService.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteService.java
new file mode 100644
index 00000000..b1107ce8
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+
+import java.util.List;
+
+public interface NoteService {
+ List getNotesForUser(Long userId);
+ List getAllNotes();
+ Note addNote(Note note);
+ void removeNote(Long noteId, Long userId);
+ Note getNote(Long noteId, Long userId);
+ void updateNote(Note note);
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteServiceImplementation.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteServiceImplementation.java
new file mode 100644
index 00000000..f45827ce
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteServiceImplementation.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Primary;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@Primary
+public class NoteServiceImplementation implements NoteService {
+ private final JdbcTemplate catalogJdbcTemplate;
+ private final JdbcTemplate directShardJdbcTemplate;
+ private final RowMapper noteRowMapper;
+
+ public NoteServiceImplementation(JdbcTemplate catalogJdbcTemplate,
+ @Qualifier("directShardJdbcTemplate") JdbcTemplate directShardJdbcTemplate,
+ RowMapper noteRowMapper) {
+ this.catalogJdbcTemplate = catalogJdbcTemplate;
+ this.directShardJdbcTemplate = directShardJdbcTemplate;
+ this.noteRowMapper = noteRowMapper;
+ }
+
+
+ @Override
+ public Note addNote(Note note) {
+ note.setId(nextSequenceValue(directShardJdbcTemplate));
+
+ directShardJdbcTemplate.update("INSERT INTO notes VALUES (?, ?, ?, ?)",
+ note.getId(),
+ note.getUserId(),
+ note.getTitle(),
+ note.getContent());
+
+ return note;
+ }
+
+ @Override
+ public void removeNote(Long noteId, Long userId) {
+ directShardJdbcTemplate.update("DELETE FROM notes WHERE note_id = ? and user_id = ?", noteId, userId);
+ }
+
+ @Override
+ public Note getNote(Long noteId, Long userId) {
+ String query = "SELECT * FROM notes n WHERE n.user_id = ? AND n.note_id = ?";
+
+ return directShardJdbcTemplate.queryForObject(query, noteRowMapper, userId, noteId);
+ }
+
+ @Override
+ public void updateNote(Note note) {
+ String updateQuery = "UPDATE notes " +
+ "SET title = ?, content = ? " +
+ "WHERE note_id = ? and user_id = ?";
+
+ int affectedRows = directShardJdbcTemplate.update(updateQuery,
+ note.getTitle(),
+ note.getContent(),
+ note.getId(),
+ note.getUserId());
+
+ if (affectedRows == 0) {
+ throw new EmptyResultDataAccessException(1);
+ }
+ }
+
+ @Override
+ public List getNotesForUser(Long userId) {
+ String query = "SELECT * FROM notes n WHERE n.user_id = ?";
+
+ return directShardJdbcTemplate.query(query, noteRowMapper, userId);
+ }
+
+ @Override
+ public List getAllNotes() {
+ return catalogJdbcTemplate.query("SELECT * FROM notes n", noteRowMapper);
+ }
+
+ private Long nextSequenceValue(JdbcTemplate jdbcTemplate) {
+ return jdbcTemplate.queryForObject("SELECT note_sequence.nextval FROM DUAL", Long.class);
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserService.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserService.java
new file mode 100644
index 00000000..73527e5c
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserService.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+
+import java.util.List;
+
+public interface UserService extends UserDetailsService {
+ List getAllUsers();
+ User getAuthenticatedUser();
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserServiceImplementation.java b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserServiceImplementation.java
new file mode 100644
index 00000000..fca76ce5
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserServiceImplementation.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class UserServiceImplementation implements UserService {
+ private final JdbcTemplate catalogJdbcTemplate;
+ private final RowMapper userRowMapper;
+
+ public UserServiceImplementation(JdbcTemplate catalogJdbcTemplate, RowMapper userRowMapper) {
+ this.catalogJdbcTemplate = catalogJdbcTemplate;
+ this.userRowMapper = userRowMapper;
+ }
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ return catalogJdbcTemplate.queryForObject("SELECT * FROM users WHERE name = ?", userRowMapper, username);
+ }
+
+ @Override
+ public List getAllUsers() {
+ return catalogJdbcTemplate.query("SELECT * FROM users", userRowMapper);
+ }
+
+ @Override
+ public User getAuthenticatedUser() {
+ return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ }
+}
diff --git a/java/jdbc/SpringSharding/JDBCTemplate/src/main/resources/application.properties b/java/jdbc/SpringSharding/JDBCTemplate/src/main/resources/application.properties
new file mode 100644
index 00000000..3cc12f83
--- /dev/null
+++ b/java/jdbc/SpringSharding/JDBCTemplate/src/main/resources/application.properties
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2024 Oracle and/or its affiliates.
+#
+# The Universal Permissive License (UPL), Version 1.0
+#
+# Subject to the condition set forth below, permission is hereby granted to any
+# person obtaining a copy of this software, associated documentation and/or data
+# (collectively the "Software"), free of charge and under any and all copyright
+# rights in the Software, and any and all patent rights owned or freely
+# licensable by each licensor hereunder covering either (i) the unmodified
+# Software as contributed to or provided by such licensor, or (ii) the Larger
+# Works (as defined below), to deal in both
+#
+# (a) the Software, and
+# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+# one is included with the Software (each a "Larger Work" to which the Software
+# is contributed by such licensors),
+#
+# without restriction, including without limitation the rights to copy, create
+# derivative works of, display, perform, and distribute the Software and make,
+# use, sell, offer for sale, import, export, have made, and have sold the
+# Software and the Larger Work(s), and to sublicense the foregoing rights on
+# either these or other terms.
+#
+# This license is subject to the following condition:
+# The above copyright notice and either this complete permission notice or at
+# a minimum a reference to the UPL must be included in all copies or
+# substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+# Catalog database
+oracle.database.catalog.url=${CATALOG_URL}
+oracle.database.catalog.username=${CATALOG_USER}
+oracle.database.catalog.password=${CATALOG_PASS}
+
+# Gsm Database
+oracle.database.directshard.url=${SHARD_DIRECTOR_URL}
+oracle.database.directshard.username=${SHARD_DIRECTOR_USER}
+oracle.database.directshard.password=${SHARD_DIRECTOR_PASS}
diff --git a/java/jdbc/SpringSharding/JPA/.gitignore b/java/jdbc/SpringSharding/JPA/.gitignore
new file mode 100644
index 00000000..7ed0d6b6
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/.gitignore
@@ -0,0 +1,32 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/java/jdbc/SpringSharding/JPA/LICENSE.txt b/java/jdbc/SpringSharding/JPA/LICENSE.txt
new file mode 100644
index 00000000..9b47cfba
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/LICENSE.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/java/jdbc/SpringSharding/JPA/README.md b/java/jdbc/SpringSharding/JPA/README.md
new file mode 100644
index 00000000..0cfce567
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/README.md
@@ -0,0 +1,101 @@
+## Overview
+
+This project demonstrates the use of the latest sharding [feature](https://github.com/spring-projects/spring-framework/pull/31506) in Spring Framework with the Oracle Database.
+The feature is about supporting direct routing to sharded databases.
+
+This version uses Spring Data JPA (Hibernates), for data access.
+
+You can use the datasource configurations provided in this project as a template for setting up the sharding feature in your own projects.
+
+## Configuration
+
+### Database
+
+You can refer to the [Oracle Docs](https://docs.oracle.com/en/database/oracle/oracle-database/21/shard/sharding-deployment.html#GUID-F99B8742-4089-4E77-87D4-4691EA932207)
+to learn how to set up and deploy an Oracle sharded database.
+You can also refer to [Oracle Database Operator](https://github.com/oracle/oracle-database-operator) that makes deploying a sharded database on a Kubernetes Cluster an easy process.
+
+After your sharded database is set, connect to the shard catalog as sysdba and create the demo application schema user.
+
+~~~SQL
+ALTER SESSION ENABLE SHARD DDL;
+
+-- Create demo schema user
+CREATE USER demo_user IDENTIFIED BY demo_user;
+GRANT CONNECT, RESOURCE TO demo_user;
+GRANT CREATE TABLE TO demo_user;
+GRANT UNLIMITED TABLESPACE TO demo_user;
+
+-- Create tablespace
+CREATE TABLESPACE SET TS1 USING TEMPLATE (
+ DATAFILE SIZE 10M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED
+ EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO);
+~~~
+
+On the shard catalog connect as demo_user and run the following SQL script to create your tables.
+
+~~~SQL
+ALTER SESSION ENABLE SHARD DDL;
+
+CREATE SHARDED TABLE users (
+ user_id NUMBER PRIMARY KEY,
+ name VARCHAR2(100),
+ password VARCHAR2(255),
+ role VARCHAR2(5),
+CONSTRAINT roleCheck CHECK (role IN ('USER', 'ADMIN')))
+TABLESPACE SET TS1 PARTITION BY CONSISTENT HASH (user_id);
+
+CREATE SHARDED TABLE notes (
+ note_id NUMBER NOT NULL,
+ user_id NUMBER NOT NULL,
+ title VARCHAR2(255),
+ content CLOB,
+CONSTRAINT notePK PRIMARY KEY (note_id, user_id),
+CONSTRAINT userFK FOREIGN KEY (user_id) REFERENCES users(user_id))
+PARTITION BY REFERENCE (UserFK);
+
+CREATE SEQUENCE note_sequence INCREMENT BY 1 START WITH 1 MAXVALUE 2E9 SHARD;
+~~~
+
+Make sure to insert a user or two in the database before testing the application.
+
+~~~SQL
+INSERT INTO users VALUES (0, 'user1', LOWER(STANDARD_HASH('user1', 'SHA256')), 'USER');
+INSERT INTO users VALUES (1, 'admin', LOWER(STANDARD_HASH('admin', 'SHA256')), 'ADMIN');
+COMMIT;
+~~~
+
+To uninstall and clean up the preceding setup, you can connect as sysdba and run the following SQL script.
+
+~~~SQL
+ALTER SESSION ENABLE SHARD DDL;
+
+DROP USER demo_user CASCADE;
+DROP TABLESPACE SET TS1;
+~~~
+
+## Building the application
+To build the application run:
+
+~~~
+mvn install
+~~~
+
+## Running the application
+
+Before running the application set the following environment variables or update [application.properties](src/main/resources/application.properties). These configure the URL and credentials for the catalog database and shard director (GSM) used by the application.
+
+~~~shell
+export CATALOG_URL="the catalog url"
+export CATALOG_USER="demo_user"
+export CATALOG_PASS="demo_user"
+export SHARD_DIRECTOR_URL="the shard director url"
+export SHARD_DIRECTOR_USER="demo_user"
+export SHARD_DIRECTOR_PASS="demo_user"
+~~~
+
+Then you can run the application using:
+
+~~~shell
+mvn spring-boot:run
+~~~
diff --git a/java/jdbc/SpringSharding/JPA/api.yaml b/java/jdbc/SpringSharding/JPA/api.yaml
new file mode 100644
index 00000000..69f06acd
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/api.yaml
@@ -0,0 +1,256 @@
+openapi: 3.0.3
+info:
+ title: Notes
+ description: This API keeps track of user notes.
+ license:
+ name: The Universal Permissive License (UPL), version 1.0
+ url: https://www.oracle.com/downloads/licenses/upl-license.html
+ version: 0.0.1
+paths:
+ /users:
+ get:
+ description: Lists all users if authenticated user is admin, otherwise gets current authenticated user
+ operationId: getUsers
+ responses:
+ "200":
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/UserDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ /users/{userId}/notes:
+ post:
+ description: Adds a note to a user
+ operationId: addNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ responses:
+ "201":
+ description: user added successfully
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ResponseNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user not found
+
+ get:
+ description: Lists all notes for a given user
+ operationId: getNotesForUser
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ responses:
+ "200":
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user not found
+
+ /users/{userId}/notes/{noteId}:
+ get:
+ description: Gets a note for a user
+ operationId: getNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ - name: noteId
+ in: path
+ description: the note identifier
+ required: true
+ schema:
+ type: integer
+ responses:
+ "200":
+ description: user added successfully
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ResponseNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user or note not found
+
+ put:
+ description: Updates a note for a user
+ operationId: updateNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ - name: noteId
+ in: path
+ description: the note identifier
+ required: true
+ schema:
+ type: integer
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ responses:
+ "200":
+ description: user added successfully
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ResponseNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user or note not found
+
+ delete:
+ description: deletes a note for a user
+ operationId: deleteNote
+ parameters:
+ - name: userId
+ in: path
+ description: the user identifier
+ required: true
+ schema:
+ type: integer
+ - name: noteId
+ in: path
+ description: the note identifier
+ required: true
+ schema:
+ type: integer
+ responses:
+ "200":
+ description: user added successfully
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+ "404":
+ description: user or note not found
+
+ /users/all/notes:
+ get:
+ description: Lists all notes for all users (admin only)
+ operationId: getAllNotes
+ security:
+ - basicAuth: [ ]
+ - cookieAuth: [ ]
+ responses:
+ "200":
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: "#/components/schemas/RequestNoteDTO"
+ "401":
+ description: unauthorized, invalid authentication credentials
+ "403":
+ description: access forbidden
+
+components:
+ schemas:
+ RequestNoteDTO:
+ type: object
+ properties:
+ title:
+ type: string
+ description: title of the note
+ example: Title of my first note
+ content:
+ type: string
+ description: content of the note
+ example: Contents of my first note
+ ResponseNoteDTO:
+ type: object
+ properties:
+ userId:
+ type: integer
+ description: user identifier
+ example: 3
+ noteId:
+ type: integer
+ description: note identifier
+ example: 108
+ title:
+ type: string
+ description: title of the note
+ example: Title of my first note
+ content:
+ type: string
+ description: content of the note
+ example: Contents of my first note
+ UserDTO:
+ type: object
+ properties:
+ id:
+ type: integer
+ description: User identifier
+ example: 99
+ username:
+ type: string
+ description: Username
+ example: user1
+ role:
+ type: string
+ description: role of the user can be USER or ADMIN
+ example: USER
+
+ securitySchemes:
+ cookieAuth:
+ type: apiKey
+ in: cookie
+ name: JSESSIONID
+ basicAuth:
+ type: http
+ scheme: basic
+
+security:
+ - basicAuth: [ ]
+ - cookieAuth: [ ]
+
+servers:
+ - url: http://localhost:8080
diff --git a/java/jdbc/SpringSharding/JPA/mvnw b/java/jdbc/SpringSharding/JPA/mvnw
new file mode 100755
index 00000000..66df2854
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/mvnw
@@ -0,0 +1,308 @@
+#!/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
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.2.0
+#
+# 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" ] && [ -d "$JAVA_HOME" ] &&
+ JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); 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 2>/dev/null; \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/.." || exit 1; pwd)
+ fi
+ # end of workaround
+ done
+ printf '%s' "$(cd "$basedir" || exit 1; pwd)"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ # Remove \r in case we run on Windows within Git Bash
+ # and check out the repository with auto CRLF management
+ # enabled. Otherwise, we may read lines that are delimited with
+ # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
+ # splitting rules.
+ tr -s '\r\n' ' ' < "$1"
+ fi
+}
+
+log() {
+ if [ "$MVNW_VERBOSE" = true ]; then
+ printf '%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
+log "$MAVEN_PROJECTBASEDIR"
+
+##########################################################################################
+# 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.
+##########################################################################################
+wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
+if [ -r "$wrapperJarPath" ]; then
+ log "Found $wrapperJarPath"
+else
+ log "Couldn't find $wrapperJarPath, downloading it ..."
+
+ if [ -n "$MVNW_REPOURL" ]; then
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+ else
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+ fi
+ while IFS="=" read -r key value; do
+ # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
+ safeValue=$(echo "$value" | tr -d '\r')
+ case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
+ esac
+ done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+ log "Downloading from: $wrapperUrl"
+
+ if $cygwin; then
+ wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
+ fi
+
+ if command -v wget > /dev/null; then
+ log "Found wget ... using wget"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ log "Found curl ... using curl"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+ else
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+ fi
+ else
+ log "Falling back to using Java to download"
+ javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$MAVEN_PROJECTBASEDIR/.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
+ log " - Compiling MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/javac" "$javaSource")
+ fi
+ if [ -e "$javaClass" ]; then
+ log " - Running MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+# If specified, validate the SHA-256 sum of the Maven wrapper jar file
+wrapperSha256Sum=""
+while IFS="=" read -r key value; do
+ case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
+ esac
+done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+if [ -n "$wrapperSha256Sum" ]; then
+ wrapperSha256Result=false
+ if command -v sha256sum > /dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ elif command -v shasum > /dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
+ echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
+ exit 1
+ fi
+ if [ $wrapperSha256Result = false ]; then
+ echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
+ echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
+ echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
+ exit 1
+ fi
+fi
+
+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
+
+# shellcheck disable=SC2086 # safe args
+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/java/jdbc/SpringSharding/JPA/mvnw.cmd b/java/jdbc/SpringSharding/JPA/mvnw.cmd
new file mode 100644
index 00000000..95ba6f54
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/mvnw.cmd
@@ -0,0 +1,205 @@
+@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 https://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.2.0
+@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.2.0/maven-wrapper-3.2.0.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.2.0/maven-wrapper-3.2.0.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 If specified, validate the SHA-256 sum of the Maven wrapper jar file
+SET WRAPPER_SHA_256_SUM=""
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
+)
+IF NOT %WRAPPER_SHA_256_SUM%=="" (
+ powershell -Command "&{"^
+ "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
+ "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
+ " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
+ " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
+ " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
+ " exit 1;"^
+ "}"^
+ "}"
+ if ERRORLEVEL 1 goto error
+)
+
+@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/java/jdbc/SpringSharding/JPA/pom.xml b/java/jdbc/SpringSharding/JPA/pom.xml
new file mode 100644
index 00000000..8ae30e12
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.2
+
+
+ com.oracle.jdbc.sample
+ shardingwithspring
+ 0.0.1-SNAPSHOT
+ ShardingWithSpring
+ Demo application for using sharding with spring
+
+ 17
+ 23.3.0.23.09
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ com.oracle.database.jdbc
+ ojdbc11
+ ${ojdbc.version}
+
+
+
+ com.oracle.database.jdbc
+ ucp11
+ ${ojdbc.version}
+
+
+
+ com.oracle.database.ha
+ ons
+ ${ojdbc.version}
+
+
+
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/ShardingApplication.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/ShardingApplication.java
new file mode 100644
index 00000000..c8529550
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/ShardingApplication.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ShardingApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(ShardingApplication.class, args);
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/CatalogDataSourceConfig.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/CatalogDataSourceConfig.java
new file mode 100644
index 00000000..edc75e5d
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/CatalogDataSourceConfig.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.configuration;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import oracle.ucp.jdbc.PoolDataSource;
+import oracle.ucp.jdbc.PoolDataSourceFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.util.Objects;
+
+/**
+ * A catalog datasource is used to execute cross-shard queries, or in all cases where we can not build a sharding key.
+ */
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+ // This tells spring to use this configuration for all the repositories under the below package
+ basePackages = "com.oracle.jdbc.samples.springsharding.dataaccess.catalog",
+ entityManagerFactoryRef = "entityManagerFactory",
+ transactionManagerRef = "transactionManager"
+)
+public class CatalogDataSourceConfig {
+ @Value("${oracle.database.catalog.url}")
+ String url;
+ @Value("${oracle.database.catalog.username}")
+ String user;
+ @Value("${oracle.database.catalog.password}")
+ String password;
+
+ /**
+ * Bean definition of the catalog database connection pool.
+ *
+ * @return A DataSource representing the catalog database connection pool.
+ */
+ @Bean
+ @Primary
+ DataSource dataSource() throws SQLException {
+ // This is a UCP DataSource
+ PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
+
+ dataSource.setURL(url);
+ dataSource.setUser(user);
+ dataSource.setPassword(password);
+ dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
+ dataSource.setInitialPoolSize(1);
+ dataSource.setMinPoolSize(1);
+ dataSource.setMaxPoolSize(20);
+
+ return dataSource;
+ }
+
+ /**
+ * EntityManagerFactory bean definition that is associated with the catalog connection pool.
+ *
+ * @return An EntityManagerFactory instance associated with the catalog connection pool
+ */
+ @Bean
+ @Primary
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory(
+ @Qualifier("dataSource") DataSource dataSource,
+ EntityManagerFactoryBuilder builder) {
+ return builder
+ .dataSource(dataSource)
+ .packages(User.class, Note.class)
+ .build();
+ }
+
+ /**
+ * TransactionManager bean definition that is associated with the catalog connection pool
+ *
+ * @return A PlatformTransactionManager instance associated with the catalog connection pool
+ */
+ @Bean
+ @Primary
+ public PlatformTransactionManager transactionManager(
+ @Qualifier("entityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) {
+ return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory.getObject()));
+ }
+
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/DirectShardDataSourceConfig.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/DirectShardDataSourceConfig.java
new file mode 100644
index 00000000..9de38897
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/DirectShardDataSourceConfig.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.configuration;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import jakarta.servlet.http.HttpServletRequest;
+import oracle.jdbc.OracleType;
+import oracle.jdbc.pool.OracleShardingKeyBuilderImpl;
+import oracle.ucp.jdbc.PoolDataSource;
+import oracle.ucp.jdbc.PoolDataSourceFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.jdbc.datasource.ShardingKeyProvider;
+import org.springframework.jdbc.datasource.ShardingKeyDataSourceAdapter;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.servlet.HandlerMapping;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.sql.ShardingKey;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A Direct Shard Datasource is used to establish connections to the shard directors, it should be used in cases where
+ * we only need to connect to a single shard which is identified by providing a sharding key.
+ */
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+ // This tells spring to use this configuration for all the repositories under the below package
+ basePackages = "com.oracle.jdbc.samples.springsharding.dataaccess.directshard",
+ entityManagerFactoryRef = "directShardEntityManagerFactory",
+ transactionManagerRef = "directShardTransactionManager"
+)
+public class DirectShardDataSourceConfig {
+ @Value("${oracle.database.directshard.url}")
+ private String url;
+ @Value("${oracle.database.directshard.username}")
+ private String user;
+ @Value("${oracle.database.directshard.password}")
+ private String password;
+
+ private final HttpServletRequest httpRequest;
+
+ public DirectShardDataSourceConfig(HttpServletRequest httpRequest) {
+ this.httpRequest = httpRequest;
+ }
+
+ /**
+ * Bean definition of the ShardingKeyProvider. The sharding key is extracted from the http request path variables.
+ *
+ * @return A ShardingKeyProvider that gets the sharding key from the http request path variables.
+ */
+ @Bean
+ ShardingKeyProvider shardingKeyProvider() {
+ return new ShardingKeyProvider() {
+ public ShardingKey getShardingKey() throws SQLException {
+ // On start up hibernates opens a connection to the database to do some initial setup, not setting
+ // a sharding key causes UCP to throw an exception, to avoid this problem we initialize the sharding key
+ // with -1
+ Long shardingKey = -1L;
+
+ // Get the sharding key (userId) from the request path variables
+ if (RequestContextHolder.getRequestAttributes() != null) {
+ Object httpAttributes = httpRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
+ Map pathVariables = (Map) httpAttributes;
+
+ if (pathVariables.containsKey("userId")) {
+ shardingKey = Long.parseLong(pathVariables.get("userId"));
+ }
+ }
+
+ return new OracleShardingKeyBuilderImpl().subkey(shardingKey, OracleType.NUMBER).build();
+ }
+ // We don't have a super sharding key
+ public ShardingKey getSuperShardingKey() {
+ return null;
+ }
+ };
+ }
+
+ /**
+ * Bean definition of the Direct Shard connection pool.
+ * The created Datasource is an instance of the ShardingKeyDataSourceAdapter, it allows setting direct
+ * connections to specific shards identified by a shardingKey.
+ * The shardingKey, used to identify the shards, is extracted using the {@link #shardingKeyProvider}.
+ *
+ * @return A DataSource representing the Direct Shard connection pool.
+ */
+ @Bean
+ public DataSource directShardDataSource(ShardingKeyProvider shardingKeyProvider) throws SQLException {
+ // This is a UCP DataSource
+ PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
+
+ dataSource.setURL(url);
+ dataSource.setUser(user);
+ dataSource.setPassword(password);
+ dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
+ // We are setting the initial pool size to 0 because if we create a connection without setting a sharding key
+ // they would all point to a single shard, because we initialize the sharding key with -1.
+ dataSource.setInitialPoolSize(0);
+ dataSource.setMinPoolSize(0);
+ dataSource.setMaxPoolSize(20);
+
+ return new ShardingKeyDataSourceAdapter(dataSource, shardingKeyProvider);
+ }
+
+ /**
+ * EntityManagerFactory bean definition that is associated with the Direct Shard connection pool.
+ *
+ * @return An EntityManagerFactory instance associated with the Direct Shard connection pool
+ */
+ @Bean
+ public LocalContainerEntityManagerFactoryBean directShardEntityManagerFactory(
+ @Qualifier("directShardDataSource") DataSource dataSource,
+ EntityManagerFactoryBuilder builder) {
+ return builder
+ .dataSource(dataSource)
+ .packages(User.class, Note.class)
+ .build();
+ }
+
+ /**
+ * TransactionManager bean definition that is associated with the Direct Shard connection pool
+ *
+ * @return A PlatformTransactionManager instance associated with the Direct Shard connection pool
+ */
+ @Bean
+ public PlatformTransactionManager directShardTransactionManager(
+ @Qualifier("directShardEntityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) {
+ return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory.getObject()));
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/SecurityConfig.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/SecurityConfig.java
new file mode 100644
index 00000000..917e612c
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/configuration/SecurityConfig.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.configuration;
+
+import com.oracle.jdbc.samples.springsharding.model.User;
+import com.oracle.jdbc.samples.springsharding.service.UserService;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.access.expression.DefaultHttpSecurityExpressionHandler;
+import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig {
+ private final UserService userService;
+ private final ApplicationContext applicationContext;
+
+ public SecurityConfig(UserService userService, ApplicationContext applicationContext) {
+ this.userService = userService;
+ this.applicationContext = applicationContext;
+ }
+
+ /**
+ * Checks that the authenticated user matches the user passed as argument, or is an admin.
+ *
+ * @param authentication The authentication object
+ * @param userId The ID of the user to verify
+ * @return true if authenticated user is same as userId or is an ADMIN, false otherwise
+ */
+ public boolean check(Authentication authentication, Long userId) {
+ if (authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ADMIN")))
+ return true;
+
+ if (authentication.getPrincipal() instanceof User)
+ return ((User) authentication.getPrincipal()).getId().equals(userId);
+ return false;
+ }
+
+ private WebExpressionAuthorizationManager getWebExpressionAuthorizationManager(final String expression) {
+ final var expressionHandler = new DefaultHttpSecurityExpressionHandler();
+ expressionHandler.setApplicationContext(applicationContext);
+ final var authorizationManager = new WebExpressionAuthorizationManager(expression);
+ authorizationManager.setExpressionHandler(expressionHandler);
+
+ return authorizationManager;
+ }
+
+ @Bean
+ SecurityFilterChain SecurityFilterChain(HttpSecurity http) throws Exception {
+ http.csrf(AbstractHttpConfigurer::disable)
+ .authorizeHttpRequests((requests) -> requests
+ .requestMatchers("/users/all/notes").hasAuthority("ADMIN")
+ .requestMatchers("/users/{userId}/**")
+ .access(getWebExpressionAuthorizationManager("@securityConfig.check(authentication,#userId)"))
+ .anyRequest().authenticated());
+
+ // This enables cookie authentication
+ http.sessionManagement((sm) -> sm.sessionCreationPolicy(SessionCreationPolicy.ALWAYS));
+ http.httpBasic(Customizer.withDefaults());
+
+ return http.build();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new MessageDigestPasswordEncoder("SHA-256");
+ }
+
+ @Bean
+ public AuthenticationProvider daoAuthenticationProvider() {
+ DaoAuthenticationProvider daoAuthProvider = new DaoAuthenticationProvider();
+
+ daoAuthProvider.setPasswordEncoder(passwordEncoder());
+ daoAuthProvider.setUserDetailsService(userService);
+
+ return daoAuthProvider;
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/controller/Controller.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/controller/Controller.java
new file mode 100644
index 00000000..587f0d96
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/controller/Controller.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.controller;
+
+import com.oracle.jdbc.samples.springsharding.dto.RequestNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.ResponseNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.UserDTO;
+import com.oracle.jdbc.samples.springsharding.mapper.DTOMappers;
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import com.oracle.jdbc.samples.springsharding.service.NoteService;
+import com.oracle.jdbc.samples.springsharding.service.UserService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+// We allow CORS to make it easy to test the API
+@CrossOrigin(originPatterns = "http://localhost:**")
+@org.springframework.stereotype.Controller
+@RequestMapping("/users")
+public class Controller {
+ private final NoteService noteService;
+ private final UserService userService;
+ private final DTOMappers dtoMappers;
+
+ public Controller(NoteService noteService, UserService userService, DTOMappers dtoMappers) {
+ this.noteService = noteService;
+ this.userService = userService;
+ this.dtoMappers = dtoMappers;
+ }
+
+ /**
+ * Get all users if authenticated user is admin, authenticated user otherwise.
+ */
+ @GetMapping
+ public ResponseEntity> getUsers() {
+ String role = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getRole();
+
+ List response = null;
+
+ if (role.equals("ADMIN")) {
+ response = userService.getAllUsers()
+ .stream()
+ .map(dtoMappers::userToUserDTO)
+ .collect(Collectors.toList());
+ } else {
+ response = List.of(dtoMappers.userToUserDTO(userService.getAuthenticatedUser()));
+ }
+
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ /**
+ * Add a note
+ */
+ @PostMapping(value = {"/{userId}/notes"})
+ public ResponseEntity addNote(@PathVariable Long userId,
+ @RequestBody RequestNoteDTO noteBodyDTO) {
+ Note note = dtoMappers.requestNoteDTOToNote(noteBodyDTO, null, userId);
+
+ ResponseNoteDTO response = dtoMappers.noteToResponseNoteDTO(noteService.addNote(note));
+
+ return new ResponseEntity<>(response, HttpStatus.CREATED);
+ }
+
+ /**
+ * Get all notes for all users
+ */
+ @GetMapping("/all/notes")
+ public ResponseEntity> getAllNotes() {
+ List response = noteService.getAllNotes()
+ .stream()
+ .map(dtoMappers::noteToResponseNoteDTO)
+ .collect(Collectors.toList());
+
+ return ResponseEntity.ofNullable(response);
+ }
+
+ /**
+ * Get all notes for a user
+ */
+ @GetMapping(value = {"/{userId}/notes"})
+ public ResponseEntity> getNotesForUser(@PathVariable Long userId) {
+ List notes = noteService.getNotesForUser(userId)
+ .stream()
+ .map(dtoMappers::noteToResponseNoteDTO)
+ .collect(Collectors.toList());
+
+ return ResponseEntity.ofNullable(notes);
+ }
+
+ /**
+ * Get a single note identified by userId and noteId
+ */
+ @GetMapping(value = {"/{userId}/notes/{noteId}"})
+ public ResponseEntity getNote(@PathVariable Long userId, @PathVariable Long noteId) {
+ ResponseNoteDTO response = dtoMappers.noteToResponseNoteDTO(noteService.getNote(noteId, userId));
+
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ /**
+ * Update a note
+ */
+ @PutMapping("/{userId}/notes/{noteId}")
+ public ResponseEntity updateNote(@PathVariable Long userId,
+ @PathVariable Long noteId,
+ @RequestBody RequestNoteDTO noteBodyDTO) {
+ noteService.updateNote(dtoMappers.requestNoteDTOToNote(noteBodyDTO, noteId, userId));
+
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ /**
+ * Delete a note
+ */
+ @DeleteMapping("/{userId}/notes/{noteId}")
+ public ResponseEntity deleteNote(@PathVariable Long userId, @PathVariable Long noteId) {
+ noteService.removeNote(noteId, userId);
+
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/controller/ControllerAdvice.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/controller/ControllerAdvice.java
new file mode 100644
index 00000000..4bc862f5
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/controller/ControllerAdvice.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.controller;
+
+import jakarta.persistence.EntityNotFoundException;
+import oracle.jdbc.OracleDatabaseException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestController;
+
+@org.springframework.web.bind.annotation.ControllerAdvice
+@RestController
+public class ControllerAdvice {
+ @ExceptionHandler({OracleDatabaseException.class, EntityNotFoundException.class})
+ public ResponseEntity handleOracleDatabaseException() {
+ return ResponseEntity.status(404).build();
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/NoteRepository.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/NoteRepository.java
new file mode 100644
index 00000000..f0100a7d
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/NoteRepository.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dataaccess;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+/**
+ * A Note Repository interface that will be inherited by two repositories, providing users with the flexibility
+ * to select between performing database operations on either the Catalog Database or Shard Directors (Direct Shard).
+ */
+public interface NoteRepository extends JpaRepository {
+ List findByUserId(Long userId);
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/UserRepository.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/UserRepository.java
new file mode 100644
index 00000000..fd4481e3
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/UserRepository.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dataaccess;
+
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+/**
+ * A User Repository interface that will be inherited by two repositories, providing users with the flexibility
+ * to select between performing database operations on either the Catalog Database or Shard Directors (Direct Shard).
+ */
+public interface UserRepository extends JpaRepository {
+ Optional findByUserName(String username);
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/catalog/CatalogNoteRepository.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/catalog/CatalogNoteRepository.java
new file mode 100644
index 00000000..0a44896c
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/catalog/CatalogNoteRepository.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dataaccess.catalog;
+
+import com.oracle.jdbc.samples.springsharding.dataaccess.NoteRepository;
+import com.oracle.jdbc.samples.springsharding.configuration.CatalogDataSourceConfig;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Repository;
+
+/**
+ * This Note Repository is configured to utilize the Catalog Database Connections,
+ * as specified in {@link CatalogDataSourceConfig}.
+ */
+@Repository
+@Primary
+public interface CatalogNoteRepository extends NoteRepository {}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/catalog/CatalogUserRepository.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/catalog/CatalogUserRepository.java
new file mode 100644
index 00000000..06a900b0
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/catalog/CatalogUserRepository.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dataaccess.catalog;
+
+import com.oracle.jdbc.samples.springsharding.dataaccess.UserRepository;
+import com.oracle.jdbc.samples.springsharding.configuration.CatalogDataSourceConfig;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Repository;
+
+/**
+ * This User Repository is configured to utilize the Catalog Database Connections,
+ * as specified in {@link CatalogDataSourceConfig}.
+ */
+@Repository
+@Primary
+public interface CatalogUserRepository extends UserRepository {}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/directshard/DirectShardNoteRepository.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/directshard/DirectShardNoteRepository.java
new file mode 100644
index 00000000..bc84abde
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/directshard/DirectShardNoteRepository.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dataaccess.directshard;
+
+import com.oracle.jdbc.samples.springsharding.dataaccess.NoteRepository;
+import com.oracle.jdbc.samples.springsharding.configuration.DirectShardDataSourceConfig;
+import org.springframework.stereotype.Repository;
+
+/**
+ * This NoteRepository is configured to utilize Direct Shard Connections,
+ * as specified in {@link DirectShardDataSourceConfig}.
+ */
+@Repository
+public interface DirectShardNoteRepository extends NoteRepository {}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/directshard/DirectShardUserRepository.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/directshard/DirectShardUserRepository.java
new file mode 100644
index 00000000..413e726d
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dataaccess/directshard/DirectShardUserRepository.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dataaccess.directshard;
+
+import com.oracle.jdbc.samples.springsharding.dataaccess.UserRepository;
+import com.oracle.jdbc.samples.springsharding.configuration.DirectShardDataSourceConfig;
+import org.springframework.stereotype.Repository;
+
+/**
+ * This User Repository is configured to utilize Direct Shard Connections,
+ * as specified in {@link DirectShardDataSourceConfig}.
+ */
+@Repository
+public interface DirectShardUserRepository extends UserRepository {}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/RequestNoteDTO.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/RequestNoteDTO.java
new file mode 100644
index 00000000..667a2371
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/RequestNoteDTO.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dto;
+
+public record RequestNoteDTO(
+ String title,
+ String content
+) {}
\ No newline at end of file
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/ResponseNoteDTO.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/ResponseNoteDTO.java
new file mode 100644
index 00000000..1bbfdf97
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/ResponseNoteDTO.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dto;
+
+public record ResponseNoteDTO(
+ Long id,
+ Long userId,
+ String title,
+ String content
+) {}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/UserDTO.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/UserDTO.java
new file mode 100644
index 00000000..b22a5725
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/dto/UserDTO.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.dto;
+
+public record UserDTO(
+ Long id,
+ String username,
+ String role
+) {}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/DTOMappers.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/DTOMappers.java
new file mode 100644
index 00000000..73e9ead5
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/mapper/DTOMappers.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.mapper;
+
+import com.oracle.jdbc.samples.springsharding.dto.RequestNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.ResponseNoteDTO;
+import com.oracle.jdbc.samples.springsharding.dto.UserDTO;
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DTOMappers {
+ public ResponseNoteDTO noteToResponseNoteDTO(Note note) {
+ return new ResponseNoteDTO(
+ note.getId(),
+ note.getUserId(),
+ note.getTitle(),
+ note.getContent());
+ }
+
+ public Note requestNoteDTOToNote(RequestNoteDTO requestNoteDTO, Long noteId, Long userId) {
+ return new Note(
+ noteId,
+ userId,
+ requestNoteDTO.title(),
+ requestNoteDTO.content()
+ );
+ }
+
+ public UserDTO userToUserDTO(User user) {
+ return new UserDTO(user.getId(), user.getUsername(), user.getRole());
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/model/Note.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/model/Note.java
new file mode 100644
index 00000000..38a689b8
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/model/Note.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.IdClass;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
+
+import java.io.Serializable;
+
+@Entity
+@Table(name = "notes")
+@SequenceGenerator(name="NOTE_SEQUENCE_GENERATOR", sequenceName="NOTE_SEQUENCE", initialValue=1, allocationSize=1)
+@IdClass(Note.CompositeNoteId.class)
+public class Note {
+ @Id
+ @Column(name = "note_id")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="NOTE_SEQUENCE_GENERATOR")
+ private Long id;
+
+ @Id
+ @Column(name = "user_id")
+ private Long userId;
+
+ @Column(name = "title")
+ private String title;
+
+ @Column(name = "content")
+ private String content;
+
+ public Note() {}
+
+ public Note(Long id, Long userId, String title, String content) {
+ this.id = id;
+ this.userId = userId;
+ this.title = title;
+ this.content = content;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public static class CompositeNoteId implements Serializable {
+ private Long id;
+ private Long userId;
+
+ public CompositeNoteId() {};
+
+ public CompositeNoteId(Long id, Long userId) {
+ this.id = id;
+ this.userId = userId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof CompositeNoteId noteId))
+ return false;
+
+ return (noteId.id.equals(this.id)) && (noteId.userId.equals(this.userId));
+ }
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/model/User.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/model/User.java
new file mode 100644
index 00000000..8e3eaf67
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/model/User.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.List;
+
+@Entity
+@Table(name = "users")
+public class User implements UserDetails {
+ @Id
+ @Column(name = "user_id")
+ private Long id;
+
+ @Column(name = "name")
+ private String userName;
+
+ private String password;
+
+ private String role = "USER";
+
+ public User() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role);
+
+ return List.of(grantedAuthority);
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String getUsername() {
+ return userName;
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteService.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteService.java
new file mode 100644
index 00000000..3217f8f2
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteService.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+
+import java.util.List;
+
+public interface NoteService {
+ List getNotesForUser(Long userId);
+
+ List getAllNotes();
+
+ Note addNote(Note note);
+
+ void removeNote(Long noteId, Long userId);
+
+ Note getNote(Long noteId, Long userId);
+
+ void updateNote(Note note);
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteServiceImplementation.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteServiceImplementation.java
new file mode 100644
index 00000000..071622cb
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/NoteServiceImplementation.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.model.Note;
+import com.oracle.jdbc.samples.springsharding.dataaccess.NoteRepository;
+import jakarta.persistence.EntityNotFoundException;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class NoteServiceImplementation implements NoteService {
+ private final NoteRepository directShardNoteRepository;
+ private final NoteRepository catalogNoteRepository;
+
+ public NoteServiceImplementation(NoteRepository directShardNoteRepository,
+ @Qualifier("catalogNoteRepository") NoteRepository catalogNoteRepository) {
+ this.directShardNoteRepository = directShardNoteRepository;
+ this.catalogNoteRepository = catalogNoteRepository;
+ }
+
+ @Override
+ public Note addNote(Note note) {
+ return directShardNoteRepository.save(note);
+ }
+
+ @Override
+ public void removeNote(Long noteId, Long userId) {
+ directShardNoteRepository.deleteById(new Note.CompositeNoteId(noteId, userId));
+ }
+
+ @Override
+ public Note getNote(Long noteId, Long userId) {
+ Optional note = directShardNoteRepository.findById(new Note.CompositeNoteId(noteId, userId));
+
+ if (note.isPresent())
+ return note.get();
+ throw new EntityNotFoundException();
+ }
+
+ @Override
+ public void updateNote(Note note) {
+ if (!directShardNoteRepository.existsById(new Note.CompositeNoteId(note.getId(), note.getUserId())))
+ throw new EntityNotFoundException();
+ directShardNoteRepository.save(note);
+ }
+
+ @Override
+ public List getNotesForUser(Long userId) {
+ return directShardNoteRepository.findByUserId(userId);
+ }
+
+ @Override
+ public List getAllNotes() {
+ return catalogNoteRepository.findAll();
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserService.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserService.java
new file mode 100644
index 00000000..73527e5c
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserService.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+
+import java.util.List;
+
+public interface UserService extends UserDetailsService {
+ List getAllUsers();
+ User getAuthenticatedUser();
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserServiceImplementation.java b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserServiceImplementation.java
new file mode 100644
index 00000000..942b7355
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/java/com/oracle/jdbc/samples/springsharding/service/UserServiceImplementation.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * The Universal Permissive License (UPL), Version 1.0
+ *
+ * Subject to the condition set forth below, permission is hereby granted to any
+ * person obtaining a copy of this software, associated documentation and/or data
+ * (collectively the "Software"), free of charge and under any and all copyright
+ * rights in the Software, and any and all patent rights owned or freely
+ * licensable by each licensor hereunder covering either (i) the unmodified
+ * Software as contributed to or provided by such licensor, or (ii) the Larger
+ * Works (as defined below), to deal in both
+ *
+ * (a) the Software, and
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+ * one is included with the Software (each a "Larger Work" to which the Software
+ * is contributed by such licensors),
+ *
+ * without restriction, including without limitation the rights to copy, create
+ * derivative works of, display, perform, and distribute the Software and make,
+ * use, sell, offer for sale, import, export, have made, and have sold the
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
+ * either these or other terms.
+ *
+ * This license is subject to the following condition:
+ * The above copyright notice and either this complete permission notice or at
+ * a minimum a reference to the UPL must be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.oracle.jdbc.samples.springsharding.service;
+
+import com.oracle.jdbc.samples.springsharding.dataaccess.UserRepository;
+import com.oracle.jdbc.samples.springsharding.model.User;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class UserServiceImplementation implements UserService {
+ private final UserRepository catalogUserRepository;
+
+ public UserServiceImplementation(UserRepository userRepository) {
+ this.catalogUserRepository = userRepository;
+ }
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ var optional = catalogUserRepository.findByUserName(username);
+
+ if (optional.isEmpty())
+ throw new UsernameNotFoundException(username + " not found!");
+
+ return optional.get();
+ }
+
+ @Override
+ public List getAllUsers() {
+ return catalogUserRepository.findAll();
+ }
+
+ @Override
+ public User getAuthenticatedUser() {
+ return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ }
+}
diff --git a/java/jdbc/SpringSharding/JPA/src/main/resources/application.properties b/java/jdbc/SpringSharding/JPA/src/main/resources/application.properties
new file mode 100644
index 00000000..cfe4597c
--- /dev/null
+++ b/java/jdbc/SpringSharding/JPA/src/main/resources/application.properties
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2024 Oracle and/or its affiliates.
+#
+# The Universal Permissive License (UPL), Version 1.0
+#
+# Subject to the condition set forth below, permission is hereby granted to any
+# person obtaining a copy of this software, associated documentation and/or data
+# (collectively the "Software"), free of charge and under any and all copyright
+# rights in the Software, and any and all patent rights owned or freely
+# licensable by each licensor hereunder covering either (i) the unmodified
+# Software as contributed to or provided by such licensor, or (ii) the Larger
+# Works (as defined below), to deal in both
+#
+# (a) the Software, and
+# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+# one is included with the Software (each a "Larger Work" to which the Software
+# is contributed by such licensors),
+#
+# without restriction, including without limitation the rights to copy, create
+# derivative works of, display, perform, and distribute the Software and make,
+# use, sell, offer for sale, import, export, have made, and have sold the
+# Software and the Larger Work(s), and to sublicense the foregoing rights on
+# either these or other terms.
+#
+# This license is subject to the following condition:
+# The above copyright notice and either this complete permission notice or at
+# a minimum a reference to the UPL must be included in all copies or
+# substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+# Catalog database
+oracle.database.catalog.url=${CATALOG_URL}
+oracle.database.catalog.username=${CATALOG_USER}
+oracle.database.catalog.password=${CATALOG_PASS}
+
+# Gsm Database
+oracle.database.directshard.url=${SHARD_DIRECTOR_URL}
+oracle.database.directshard.username=${SHARD_DIRECTOR_USER}
+oracle.database.directshard.password=${SHARD_DIRECTOR_PASS}
+
+# dialect
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.OracleDialect