mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-22 15:55:49 +00:00
Merge branch 'spring-projects:main' into main
This commit is contained in:
commit
bf12157061
41 changed files with 2814 additions and 1568 deletions
|
@ -8,6 +8,6 @@ ARG USER=vscode
|
||||||
VOLUME /home/$USER/.m2
|
VOLUME /home/$USER/.m2
|
||||||
VOLUME /home/$USER/.gradle
|
VOLUME /home/$USER/.gradle
|
||||||
|
|
||||||
ARG JAVA_VERSION=17.0.4.1-ms
|
ARG JAVA_VERSION=17.0.7-ms
|
||||||
RUN sudo mkdir /home/$USER/.m2 /home/$USER/.gradle && sudo chown $USER:$USER /home/$USER/.m2 /home/$USER/.gradle
|
RUN sudo mkdir /home/$USER/.m2 /home/$USER/.gradle && sudo chown $USER:$USER /home/$USER/.m2 /home/$USER/.gradle
|
||||||
RUN bash -lc '. /usr/local/sdkman/bin/sdkman-init.sh && sdk install java $JAVA_VERSION && sdk use java $JAVA_VERSION'
|
RUN bash -lc '. /usr/local/sdkman/bin/sdkman-init.sh && sdk install java $JAVA_VERSION && sdk use java $JAVA_VERSION'
|
||||||
|
|
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Binary file not shown.
4
.mvn/wrapper/maven-wrapper.properties
vendored
4
.mvn/wrapper/maven-wrapper.properties
vendored
|
@ -14,5 +14,5 @@
|
||||||
# KIND, either express or implied. See the License for the
|
# KIND, either express or implied. See the License for the
|
||||||
# specific language governing permissions and limitations
|
# specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.1/apache-maven-3.9.1-bin.zip
|
||||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
|
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
java-baseline=8
|
|
10
build.gradle
10
build.gradle
|
@ -1,14 +1,14 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.springframework.boot' version '3.0.4'
|
id 'org.springframework.boot' version '3.1.1'
|
||||||
id 'io.spring.dependency-management' version '1.1.0'
|
id 'io.spring.dependency-management' version '1.1.0'
|
||||||
id 'org.graalvm.buildtools.native' version '0.9.20'
|
id 'org.graalvm.buildtools.native' version '0.9.23'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
|
|
||||||
group = 'org.springframework.samples'
|
group = 'org.springframework.samples'
|
||||||
version = '3.0.0'
|
version = '3.1.0'
|
||||||
sourceCompatibility = '17'
|
sourceCompatibility = '17'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -35,6 +35,10 @@ dependencies {
|
||||||
runtimeOnly 'org.postgresql:postgresql'
|
runtimeOnly 'org.postgresql:postgresql'
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
|
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
|
||||||
|
testImplementation 'org.springframework.boot:spring-boot-docker-compose'
|
||||||
|
testImplementation 'org.testcontainers:junit-jupiter'
|
||||||
|
testImplementation 'org.testcontainers:mysql'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|
|
@ -13,11 +13,15 @@ services:
|
||||||
- MYSQL_DATABASE=petclinic
|
- MYSQL_DATABASE=petclinic
|
||||||
volumes:
|
volumes:
|
||||||
- "./conf.d:/etc/mysql/conf.d:ro"
|
- "./conf.d:/etc/mysql/conf.d:ro"
|
||||||
|
profiles:
|
||||||
|
- mysql
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:15.2
|
image: postgres:15.3
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "5432:5432"
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_PASSWORD=petclinic
|
- POSTGRES_PASSWORD=petclinic
|
||||||
- POSTGRES_USER=petclinic
|
- POSTGRES_USER=petclinic
|
||||||
- POSTGRES_DB=petclinic
|
- POSTGRES_DB=petclinic
|
||||||
|
profiles:
|
||||||
|
- postgres
|
||||||
|
|
218
mvnw
vendored
218
mvnw
vendored
|
@ -19,7 +19,7 @@
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Maven Start Up Batch script
|
# Apache Maven Wrapper startup batch script, version 3.2.0
|
||||||
#
|
#
|
||||||
# Required ENV vars:
|
# Required ENV vars:
|
||||||
# ------------------
|
# ------------------
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
#
|
#
|
||||||
# Optional ENV vars
|
# Optional ENV vars
|
||||||
# -----------------
|
# -----------------
|
||||||
# M2_HOME - location of maven2's installed home dir
|
|
||||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
# e.g. to debug Maven itself, use
|
# e.g. to debug Maven itself, use
|
||||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
@ -54,7 +53,7 @@ fi
|
||||||
cygwin=false;
|
cygwin=false;
|
||||||
darwin=false;
|
darwin=false;
|
||||||
mingw=false
|
mingw=false
|
||||||
case "`uname`" in
|
case "$(uname)" in
|
||||||
CYGWIN*) cygwin=true ;;
|
CYGWIN*) cygwin=true ;;
|
||||||
MINGW*) mingw=true;;
|
MINGW*) mingw=true;;
|
||||||
Darwin*) darwin=true
|
Darwin*) darwin=true
|
||||||
|
@ -62,9 +61,9 @@ case "`uname`" in
|
||||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||||
if [ -z "$JAVA_HOME" ]; then
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
if [ -x "/usr/libexec/java_home" ]; then
|
if [ -x "/usr/libexec/java_home" ]; then
|
||||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
|
||||||
else
|
else
|
||||||
export JAVA_HOME="/Library/Java/Home"
|
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
@ -72,68 +71,38 @@ esac
|
||||||
|
|
||||||
if [ -z "$JAVA_HOME" ] ; then
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
if [ -r /etc/gentoo-release ] ; then
|
if [ -r /etc/gentoo-release ] ; then
|
||||||
JAVA_HOME=`java-config --jre-home`
|
JAVA_HOME=$(java-config --jre-home)
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$M2_HOME" ] ; then
|
|
||||||
## resolve links - $0 may be a link to maven's home
|
|
||||||
PRG="$0"
|
|
||||||
|
|
||||||
# need this for relative symlinks
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG="`dirname "$PRG"`/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
saveddir=`pwd`
|
|
||||||
|
|
||||||
M2_HOME=`dirname "$PRG"`/..
|
|
||||||
|
|
||||||
# make it fully qualified
|
|
||||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
|
||||||
|
|
||||||
cd "$saveddir"
|
|
||||||
# echo Using m2 at $M2_HOME
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
if $cygwin ; then
|
if $cygwin ; then
|
||||||
[ -n "$M2_HOME" ] &&
|
|
||||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
|
||||||
[ -n "$JAVA_HOME" ] &&
|
[ -n "$JAVA_HOME" ] &&
|
||||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
|
||||||
[ -n "$CLASSPATH" ] &&
|
[ -n "$CLASSPATH" ] &&
|
||||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||||
if $mingw ; then
|
if $mingw ; then
|
||||||
[ -n "$M2_HOME" ] &&
|
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
|
||||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
|
||||||
[ -n "$JAVA_HOME" ] &&
|
|
||||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$JAVA_HOME" ]; then
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
javaExecutable="`which javac`"
|
javaExecutable="$(which javac)"
|
||||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
|
||||||
# readlink(1) is not available as standard on Solaris 10.
|
# readlink(1) is not available as standard on Solaris 10.
|
||||||
readLink=`which readlink`
|
readLink=$(which readlink)
|
||||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
|
||||||
if $darwin ; then
|
if $darwin ; then
|
||||||
javaHome="`dirname \"$javaExecutable\"`"
|
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
|
||||||
else
|
else
|
||||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
|
||||||
fi
|
fi
|
||||||
javaHome="`dirname \"$javaExecutable\"`"
|
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
|
||||||
JAVA_HOME="$javaHome"
|
JAVA_HOME="$javaHome"
|
||||||
export JAVA_HOME
|
export JAVA_HOME
|
||||||
fi
|
fi
|
||||||
|
@ -149,7 +118,7 @@ if [ -z "$JAVACMD" ] ; then
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="`\\unset -f command; \\command -v java`"
|
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -163,12 +132,9 @@ if [ -z "$JAVA_HOME" ] ; then
|
||||||
echo "Warning: JAVA_HOME environment variable is not set."
|
echo "Warning: JAVA_HOME environment variable is not set."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
|
||||||
|
|
||||||
# traverses directory structure from process work directory to filesystem root
|
# traverses directory structure from process work directory to filesystem root
|
||||||
# first directory with .mvn subdirectory is considered project base directory
|
# first directory with .mvn subdirectory is considered project base directory
|
||||||
find_maven_basedir() {
|
find_maven_basedir() {
|
||||||
|
|
||||||
if [ -z "$1" ]
|
if [ -z "$1" ]
|
||||||
then
|
then
|
||||||
echo "Path not specified to find_maven_basedir"
|
echo "Path not specified to find_maven_basedir"
|
||||||
|
@ -184,96 +150,99 @@ find_maven_basedir() {
|
||||||
fi
|
fi
|
||||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||||
if [ -d "${wdir}" ]; then
|
if [ -d "${wdir}" ]; then
|
||||||
wdir=`cd "$wdir/.."; pwd`
|
wdir=$(cd "$wdir/.." || exit 1; pwd)
|
||||||
fi
|
fi
|
||||||
# end of workaround
|
# end of workaround
|
||||||
done
|
done
|
||||||
echo "${basedir}"
|
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# concatenates all lines of a file
|
# concatenates all lines of a file
|
||||||
concat_lines() {
|
concat_lines() {
|
||||||
if [ -f "$1" ]; then
|
if [ -f "$1" ]; then
|
||||||
echo "$(tr -s '\n' ' ' < "$1")"
|
# 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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
log() {
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
printf '%s\n' "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
|
||||||
if [ -z "$BASE_DIR" ]; then
|
if [ -z "$BASE_DIR" ]; then
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
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
|
# 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.
|
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
if [ -r "$wrapperJarPath" ]; then
|
||||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
log "Found $wrapperJarPath"
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
log "Couldn't find $wrapperJarPath, downloading it ..."
|
||||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
|
||||||
fi
|
|
||||||
if [ -n "$MVNW_REPOURL" ]; then
|
if [ -n "$MVNW_REPOURL" ]; then
|
||||||
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||||
else
|
else
|
||||||
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||||
fi
|
fi
|
||||||
while IFS="=" read key value; do
|
while IFS="=" read -r key value; do
|
||||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
# 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
|
esac
|
||||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
log "Downloading from: $wrapperUrl"
|
||||||
echo "Downloading from: $jarUrl"
|
|
||||||
fi
|
|
||||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
|
||||||
if $cygwin; then
|
if $cygwin; then
|
||||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command -v wget > /dev/null; then
|
if command -v wget > /dev/null; then
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
log "Found wget ... using wget"
|
||||||
echo "Found wget ... using wget"
|
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
|
||||||
fi
|
|
||||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||||
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||||
else
|
else
|
||||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||||
fi
|
fi
|
||||||
elif command -v curl > /dev/null; then
|
elif command -v curl > /dev/null; then
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
log "Found curl ... using curl"
|
||||||
echo "Found curl ... using curl"
|
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
|
||||||
fi
|
|
||||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||||
else
|
else
|
||||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
log "Falling back to using Java to download"
|
||||||
echo "Falling back to using Java to download"
|
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||||
fi
|
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
|
||||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
|
||||||
# For Cygwin, switch paths to Windows format before running javac
|
# For Cygwin, switch paths to Windows format before running javac
|
||||||
if $cygwin; then
|
if $cygwin; then
|
||||||
javaClass=`cygpath --path --windows "$javaClass"`
|
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
|
fi
|
||||||
if [ -e "$javaClass" ]; then
|
if [ -e "$javaClass" ]; then
|
||||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
log " - Running MavenWrapperDownloader.java ..."
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
|
||||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
|
||||||
fi
|
|
||||||
# Compiling the Java class
|
|
||||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
|
||||||
fi
|
|
||||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
|
||||||
# Running the downloader
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo " - Running MavenWrapperDownloader.java ..."
|
|
||||||
fi
|
|
||||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -282,35 +251,58 @@ fi
|
||||||
# End of extension
|
# End of extension
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
|
|
||||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
wrapperSha256Sum=""
|
||||||
echo $MAVEN_PROJECTBASEDIR
|
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
|
fi
|
||||||
|
|
||||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
if $cygwin; then
|
if $cygwin; then
|
||||||
[ -n "$M2_HOME" ] &&
|
|
||||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
|
||||||
[ -n "$JAVA_HOME" ] &&
|
[ -n "$JAVA_HOME" ] &&
|
||||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
|
||||||
[ -n "$CLASSPATH" ] &&
|
[ -n "$CLASSPATH" ] &&
|
||||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
|
||||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Provide a "standardized" way to retrieve the CLI args that will
|
# Provide a "standardized" way to retrieve the CLI args that will
|
||||||
# work with both Windows and non-Windows executions.
|
# work with both Windows and non-Windows executions.
|
||||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
|
||||||
export MAVEN_CMD_LINE_ARGS
|
export MAVEN_CMD_LINE_ARGS
|
||||||
|
|
||||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086 # safe args
|
||||||
exec "$JAVACMD" \
|
exec "$JAVACMD" \
|
||||||
$MAVEN_OPTS \
|
$MAVEN_OPTS \
|
||||||
$MAVEN_DEBUG_OPTS \
|
$MAVEN_DEBUG_OPTS \
|
||||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||||
"-Dmaven.home=${M2_HOME}" \
|
|
||||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||||
|
|
31
mvnw.cmd
vendored
31
mvnw.cmd
vendored
|
@ -18,13 +18,12 @@
|
||||||
@REM ----------------------------------------------------------------------------
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
@REM ----------------------------------------------------------------------------
|
@REM ----------------------------------------------------------------------------
|
||||||
@REM Maven Start Up Batch script
|
@REM Apache Maven Wrapper startup batch script, version 3.2.0
|
||||||
@REM
|
@REM
|
||||||
@REM Required ENV vars:
|
@REM Required ENV vars:
|
||||||
@REM JAVA_HOME - location of a JDK home dir
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
@REM
|
@REM
|
||||||
@REM Optional ENV vars
|
@REM Optional ENV vars
|
||||||
@REM M2_HOME - location of maven2's installed home dir
|
|
||||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
@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_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 MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
@ -120,10 +119,10 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
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 (
|
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
|
||||||
)
|
)
|
||||||
|
|
||||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
@ -134,11 +133,11 @@ if exist %WRAPPER_JAR% (
|
||||||
)
|
)
|
||||||
) else (
|
) else (
|
||||||
if not "%MVNW_REPOURL%" == "" (
|
if not "%MVNW_REPOURL%" == "" (
|
||||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||||
)
|
)
|
||||||
if "%MVNW_VERBOSE%" == "true" (
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||||
echo Downloading from: %DOWNLOAD_URL%
|
echo Downloading from: %WRAPPER_URL%
|
||||||
)
|
)
|
||||||
|
|
||||||
powershell -Command "&{"^
|
powershell -Command "&{"^
|
||||||
|
@ -146,7 +145,7 @@ if exist %WRAPPER_JAR% (
|
||||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||||
"}"^
|
"}"^
|
||||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
|
||||||
"}"
|
"}"
|
||||||
if "%MVNW_VERBOSE%" == "true" (
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
echo Finished downloading %WRAPPER_JAR%
|
echo Finished downloading %WRAPPER_JAR%
|
||||||
|
@ -154,6 +153,24 @@ if exist %WRAPPER_JAR% (
|
||||||
)
|
)
|
||||||
@REM End of extension
|
@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 Provide a "standardized" way to retrieve the CLI args that will
|
||||||
@REM work with both Windows and non-Windows executions.
|
@REM work with both Windows and non-Windows executions.
|
||||||
set MAVEN_CMD_LINE_ARGS=%*
|
set MAVEN_CMD_LINE_ARGS=%*
|
||||||
|
|
87
pom.xml
87
pom.xml
|
@ -3,12 +3,12 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.springframework.samples</groupId>
|
<groupId>org.springframework.samples</groupId>
|
||||||
<artifactId>spring-petclinic</artifactId>
|
<artifactId>spring-petclinic</artifactId>
|
||||||
<version>3.0.0-SNAPSHOT</version>
|
<version>3.1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.0.4</version>
|
<version>3.1.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<name>petclinic</name>
|
<name>petclinic</name>
|
||||||
|
|
||||||
|
@ -18,14 +18,20 @@
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<!-- Important for reproducible builds. Update using e.g. ./mvnw versions:set -DnewVersion=... -->
|
||||||
|
<project.build.outputTimestamp>2023-05-10T07:42:50Z</project.build.outputTimestamp>
|
||||||
|
|
||||||
<!-- Web dependencies -->
|
<!-- Web dependencies -->
|
||||||
<webjars-bootstrap.version>5.2.3</webjars-bootstrap.version>
|
<webjars-bootstrap.version>5.2.3</webjars-bootstrap.version>
|
||||||
<webjars-font-awesome.version>4.7.0</webjars-font-awesome.version>
|
<webjars-font-awesome.version>4.7.0</webjars-font-awesome.version>
|
||||||
|
|
||||||
<jacoco.version>0.8.8</jacoco.version>
|
<checkstyle.version>10.11.0</checkstyle.version>
|
||||||
|
<jacoco.version>0.8.10</jacoco.version>
|
||||||
|
<libsass.version>0.2.29</libsass.version>
|
||||||
|
<lifecycle-mapping>1.0.0</lifecycle-mapping>
|
||||||
|
<maven-checkstyle.version>3.2.2</maven-checkstyle.version>
|
||||||
<nohttp-checkstyle.version>0.0.11</nohttp-checkstyle.version>
|
<nohttp-checkstyle.version>0.0.11</nohttp-checkstyle.version>
|
||||||
<spring-format.version>0.0.38</spring-format.version>
|
<spring-format.version>0.0.39</spring-format.version>
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@ -104,7 +110,27 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
<optional>true</optional>
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-testcontainers</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-docker-compose</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>mysql</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -114,21 +140,20 @@
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>testcontainers-bom</artifactId>
|
||||||
|
<version>${testcontainers.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>io.spring.javaformat</groupId>
|
|
||||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
|
||||||
<version>${spring-format.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>validate</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>validate</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-enforcer-plugin</artifactId>
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
@ -149,15 +174,28 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.spring.javaformat</groupId>
|
||||||
|
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||||
|
<version>${spring-format.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>validate</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>${maven-checkstyle.version}</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.puppycrawl.tools</groupId>
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
<artifactId>checkstyle</artifactId>
|
<artifactId>checkstyle</artifactId>
|
||||||
<version>10.8.1</version>
|
<version>${checkstyle.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.spring.nohttp</groupId>
|
<groupId>io.spring.nohttp</groupId>
|
||||||
|
@ -172,7 +210,6 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<configLocation>src/checkstyle/nohttp-checkstyle.xml</configLocation>
|
<configLocation>src/checkstyle/nohttp-checkstyle.xml</configLocation>
|
||||||
<suppressionsLocation>src/checkstyle/nohttp-checkstyle-suppressions.xml</suppressionsLocation>
|
<suppressionsLocation>src/checkstyle/nohttp-checkstyle-suppressions.xml</suppressionsLocation>
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<sourceDirectories>${basedir}</sourceDirectories>
|
<sourceDirectories>${basedir}</sourceDirectories>
|
||||||
<includes>**/*</includes>
|
<includes>**/*</includes>
|
||||||
<excludes>**/.git/**/*,**/.idea/**/*,**/target/**/,**/.flattened-pom.xml,**/*.class</excludes>
|
<excludes>**/.git/**/*,**/.idea/**/*,**/target/**/,**/.flattened-pom.xml,**/*.class</excludes>
|
||||||
|
@ -201,8 +238,8 @@
|
||||||
<additionalProperties>
|
<additionalProperties>
|
||||||
<encoding.source>${project.build.sourceEncoding}</encoding.source>
|
<encoding.source>${project.build.sourceEncoding}</encoding.source>
|
||||||
<encoding.reporting>${project.reporting.outputEncoding}</encoding.reporting>
|
<encoding.reporting>${project.reporting.outputEncoding}</encoding.reporting>
|
||||||
<java.source>${maven.compiler.source}</java.source>
|
<java.source>${java.version}</java.source>
|
||||||
<java.target>${maven.compiler.target}</java.target>
|
<java.target>${java.version}</java.target>
|
||||||
</additionalProperties>
|
</additionalProperties>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
@ -320,7 +357,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.gitlab.haynes</groupId>
|
<groupId>com.gitlab.haynes</groupId>
|
||||||
<artifactId>libsass-maven-plugin</artifactId>
|
<artifactId>libsass-maven-plugin</artifactId>
|
||||||
<version>0.2.29</version>
|
<version>${libsass.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>generate-resources</phase>
|
<phase>generate-resources</phase>
|
||||||
|
@ -354,7 +391,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.eclipse.m2e</groupId>
|
<groupId>org.eclipse.m2e</groupId>
|
||||||
<artifactId>lifecycle-mapping</artifactId>
|
<artifactId>lifecycle-mapping</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>${lifecycle-mapping}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<lifecycleMappingMetadata>
|
<lifecycleMappingMetadata>
|
||||||
<pluginExecutions>
|
<pluginExecutions>
|
||||||
|
|
18
readme.md
18
readme.md
|
@ -29,8 +29,6 @@ Or you can run it from Maven directly using the Spring Boot Maven plugin. If you
|
||||||
./mvnw spring-boot:run
|
./mvnw spring-boot:run
|
||||||
```
|
```
|
||||||
|
|
||||||
> NOTE: Windows users should set `git config core.autocrlf true` to avoid format assertions failing the build (use `--global` to set that flag globally).
|
|
||||||
|
|
||||||
> NOTE: If you prefer to use Gradle, you can build the app using `./gradlew build` and look for the jar file in `build/libs`.
|
> NOTE: If you prefer to use Gradle, you can build the app using `./gradlew build` and look for the jar file in `build/libs`.
|
||||||
|
|
||||||
## Building a Container
|
## Building a Container
|
||||||
|
@ -68,6 +66,22 @@ docker run -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES
|
||||||
Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt)
|
Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt)
|
||||||
and for [PostgreSQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt).
|
and for [PostgreSQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt).
|
||||||
|
|
||||||
|
Instead of vanilla `docker` you can also use the provided `docker-compose.yml` file to start the database containers. Each one has a profile just like the Spring profile:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker-compose --profile mysql up
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker-compose --profile postgres up
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Applications
|
||||||
|
|
||||||
|
At development time we recommend you use the test applications set up as `main()` methods in `PetClinicIntegrationTests` (using the default H2 database and also adding Spring Boot devtools), `MySqlTestApplication` and `PostgresIntegrationTests`. These are set up so that you can run the apps in your IDE and get fast feedback, and also run the same classes as integration tests against the respective database. The MySql integration tests use Testcontainers to start the database in a Docker container, and the Postgres tests use Docker Compose to do the same thing.
|
||||||
|
|
||||||
## Compiling the CSS
|
## Compiling the CSS
|
||||||
|
|
||||||
There is a `petclinic.css` in `src/main/resources/static/resources/css`. It was generated from the `petclinic.scss` source, combined with the [Bootstrap](https://getbootstrap.com/) library. If you make changes to the `scss`, or upgrade Bootstrap, you will need to re-compile the CSS resources using the Maven profile "css", i.e. `./mvnw package -P css`. There is no build profile for Gradle to compile the CSS.
|
There is a `petclinic.css` in `src/main/resources/static/resources/css`. It was generated from the `petclinic.scss` source, combined with the [Bootstrap](https://getbootstrap.com/) library. If you make changes to the `scss`, or upgrade Bootstrap, you will need to re-compile the CSS resources using the Maven profile "css", i.e. `./mvnw package -P css`. There is no build profile for Gradle to compile the CSS.
|
||||||
|
|
|
@ -18,6 +18,9 @@ package org.springframework.samples.petclinic;
|
||||||
|
|
||||||
import org.springframework.aot.hint.RuntimeHints;
|
import org.springframework.aot.hint.RuntimeHints;
|
||||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||||
|
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
|
import org.springframework.samples.petclinic.model.Person;
|
||||||
|
import org.springframework.samples.petclinic.vet.Vet;
|
||||||
|
|
||||||
public class PetClinicRuntimeHints implements RuntimeHintsRegistrar {
|
public class PetClinicRuntimeHints implements RuntimeHintsRegistrar {
|
||||||
|
|
||||||
|
@ -26,6 +29,10 @@ public class PetClinicRuntimeHints implements RuntimeHintsRegistrar {
|
||||||
hints.resources().registerPattern("db/*"); // https://github.com/spring-projects/spring-boot/issues/32654
|
hints.resources().registerPattern("db/*"); // https://github.com/spring-projects/spring-boot/issues/32654
|
||||||
hints.resources().registerPattern("messages/*");
|
hints.resources().registerPattern("messages/*");
|
||||||
hints.resources().registerPattern("META-INF/resources/webjars/*");
|
hints.resources().registerPattern("META-INF/resources/webjars/*");
|
||||||
|
hints.resources().registerPattern("mysql-default-conf");
|
||||||
|
hints.serialization().registerType(BaseEntity.class);
|
||||||
|
hints.serialization().registerType(Person.class);
|
||||||
|
hints.serialization().registerType(Vet.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ package org.springframework.samples.petclinic.model;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.MappedSuperclass;
|
import jakarta.persistence.MappedSuperclass;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple JavaBean domain object representing an person.
|
* Simple JavaBean domain object representing an person.
|
||||||
|
@ -28,11 +28,11 @@ import jakarta.validation.constraints.NotEmpty;
|
||||||
public class Person extends BaseEntity {
|
public class Person extends BaseEntity {
|
||||||
|
|
||||||
@Column(name = "first_name")
|
@Column(name = "first_name")
|
||||||
@NotEmpty
|
@NotBlank
|
||||||
private String firstName;
|
private String firstName;
|
||||||
|
|
||||||
@Column(name = "last_name")
|
@Column(name = "last_name")
|
||||||
@NotEmpty
|
@NotBlank
|
||||||
private String lastName;
|
private String lastName;
|
||||||
|
|
||||||
public String getFirstName() {
|
public String getFirstName() {
|
||||||
|
|
|
@ -31,7 +31,7 @@ import jakarta.persistence.OneToMany;
|
||||||
import jakarta.persistence.OrderBy;
|
import jakarta.persistence.OrderBy;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.validation.constraints.Digits;
|
import jakarta.validation.constraints.Digits;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple JavaBean domain object representing an owner.
|
* Simple JavaBean domain object representing an owner.
|
||||||
|
@ -47,15 +47,15 @@ import jakarta.validation.constraints.NotEmpty;
|
||||||
public class Owner extends Person {
|
public class Owner extends Person {
|
||||||
|
|
||||||
@Column(name = "address")
|
@Column(name = "address")
|
||||||
@NotEmpty
|
@NotBlank
|
||||||
private String address;
|
private String address;
|
||||||
|
|
||||||
@Column(name = "city")
|
@Column(name = "city")
|
||||||
@NotEmpty
|
@NotBlank
|
||||||
private String city;
|
private String city;
|
||||||
|
|
||||||
@Column(name = "telephone")
|
@Column(name = "telephone")
|
||||||
@NotEmpty
|
@NotBlank
|
||||||
@Digits(fraction = 0, integer = 10)
|
@Digits(fraction = 0, integer = 10)
|
||||||
private String telephone;
|
private String telephone;
|
||||||
|
|
||||||
|
@ -132,10 +132,9 @@ public class Owner extends Person {
|
||||||
public Pet getPet(String name, boolean ignoreNew) {
|
public Pet getPet(String name, boolean ignoreNew) {
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
for (Pet pet : getPets()) {
|
for (Pet pet : getPets()) {
|
||||||
if (!ignoreNew || !pet.isNew()) {
|
|
||||||
String compName = pet.getName();
|
String compName = pet.getName();
|
||||||
compName = compName == null ? "" : compName.toLowerCase();
|
if (compName != null && compName.equalsIgnoreCase(name)) {
|
||||||
if (compName.equals(name)) {
|
if (!ignoreNew || !pet.isNew()) {
|
||||||
return pet;
|
return pet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,6 @@ class OwnerController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String addPaginationModel(int page, Model model, Page<Owner> paginated) {
|
private String addPaginationModel(int page, Model model, Page<Owner> paginated) {
|
||||||
model.addAttribute("listOwners", paginated);
|
|
||||||
List<Owner> listOwners = paginated.getContent();
|
List<Owner> listOwners = paginated.getContent();
|
||||||
model.addAttribute("currentPage", page);
|
model.addAttribute("currentPage", page);
|
||||||
model.addAttribute("totalPages", paginated.getTotalPages());
|
model.addAttribute("totalPages", paginated.getTotalPages());
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
@ -55,13 +56,23 @@ class PetController {
|
||||||
|
|
||||||
@ModelAttribute("owner")
|
@ModelAttribute("owner")
|
||||||
public Owner findOwner(@PathVariable("ownerId") int ownerId) {
|
public Owner findOwner(@PathVariable("ownerId") int ownerId) {
|
||||||
return this.owners.findById(ownerId);
|
|
||||||
|
Owner owner = this.owners.findById(ownerId);
|
||||||
|
if (owner == null) {
|
||||||
|
throw new IllegalArgumentException("Owner ID not found: " + ownerId);
|
||||||
|
}
|
||||||
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModelAttribute("pet")
|
@ModelAttribute("pet")
|
||||||
public Pet findPet(@PathVariable("ownerId") int ownerId,
|
public Pet findPet(@PathVariable("ownerId") int ownerId,
|
||||||
@PathVariable(name = "petId", required = false) Integer petId) {
|
@PathVariable(name = "petId", required = false) Integer petId) {
|
||||||
return petId == null ? new Pet() : this.owners.findById(ownerId).getPet(petId);
|
|
||||||
|
Owner owner = this.owners.findById(ownerId);
|
||||||
|
if (owner == null) {
|
||||||
|
throw new IllegalArgumentException("Owner ID not found: " + ownerId);
|
||||||
|
}
|
||||||
|
return petId == null ? new Pet() : owner.getPet(petId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitBinder("owner")
|
@InitBinder("owner")
|
||||||
|
@ -84,10 +95,15 @@ class PetController {
|
||||||
|
|
||||||
@PostMapping("/pets/new")
|
@PostMapping("/pets/new")
|
||||||
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
|
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
|
||||||
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
|
if (StringUtils.hasText(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
|
||||||
result.rejectValue("name", "duplicate", "already exists");
|
result.rejectValue("name", "duplicate", "already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalDate currentDate = LocalDate.now();
|
||||||
|
if (pet.getBirthDate() != null && pet.getBirthDate().isAfter(currentDate)) {
|
||||||
|
result.rejectValue("birthDate", "typeMismatch.birthDate");
|
||||||
|
}
|
||||||
|
|
||||||
owner.addPet(pet);
|
owner.addPet(pet);
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
model.put("pet", pet);
|
model.put("pet", pet);
|
||||||
|
@ -107,6 +123,22 @@ class PetController {
|
||||||
|
|
||||||
@PostMapping("/pets/{petId}/edit")
|
@PostMapping("/pets/{petId}/edit")
|
||||||
public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
|
public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
|
||||||
|
|
||||||
|
String petName = pet.getName();
|
||||||
|
|
||||||
|
// checking if the pet name already exist for the owner
|
||||||
|
if (StringUtils.hasText(petName)) {
|
||||||
|
Pet existingPet = owner.getPet(petName.toLowerCase(), false);
|
||||||
|
if (existingPet != null && existingPet.getId() != pet.getId()) {
|
||||||
|
result.rejectValue("name", "duplicate", "already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate currentDate = LocalDate.now();
|
||||||
|
if (pet.getBirthDate() != null && pet.getBirthDate().isAfter(currentDate)) {
|
||||||
|
result.rejectValue("birthDate", "typeMismatch.birthDate");
|
||||||
|
}
|
||||||
|
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
model.put("pet", pet);
|
model.put("pet", pet);
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class PetValidator implements Validator {
|
||||||
Pet pet = (Pet) obj;
|
Pet pet = (Pet) obj;
|
||||||
String name = pet.getName();
|
String name = pet.getName();
|
||||||
// name validation
|
// name validation
|
||||||
if (!StringUtils.hasLength(name)) {
|
if (!StringUtils.hasText(name)) {
|
||||||
errors.rejectValue("name", REQUIRED, REQUIRED);
|
errors.rejectValue("name", REQUIRED, REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple JavaBean domain object representing a visit.
|
* Simple JavaBean domain object representing a visit.
|
||||||
|
@ -39,7 +39,7 @@ public class Visit extends BaseEntity {
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
@NotEmpty
|
@NotBlank
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -49,7 +49,6 @@ class VetController {
|
||||||
Page<Vet> paginated = findPaginated(page);
|
Page<Vet> paginated = findPaginated(page);
|
||||||
vets.getVetList().addAll(paginated.toList());
|
vets.getVetList().addAll(paginated.toList());
|
||||||
return addPaginationModel(page, paginated, model);
|
return addPaginationModel(page, paginated, model);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String addPaginationModel(int page, Page<Vet> paginated, Model model) {
|
private String addPaginationModel(int page, Page<Vet> paginated, Model model) {
|
||||||
|
|
|
@ -4,5 +4,6 @@ notFound=wurde nicht gefunden
|
||||||
duplicate=ist bereits vergeben
|
duplicate=ist bereits vergeben
|
||||||
nonNumeric=darf nur numerisch sein
|
nonNumeric=darf nur numerisch sein
|
||||||
duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt
|
duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt
|
||||||
typeMismatch.date=ungültiges Datum
|
typeMismatch.date=ung<EFBFBD>ltiges Datum
|
||||||
typeMismatch.birthDate=ungültiges Datum
|
typeMismatch.birthDate=ung<EFBFBD>ltiges Datum
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,4 @@ nonNumeric=Sólo debe contener numeros
|
||||||
duplicateFormSubmission=No se permite el envío de formularios duplicados
|
duplicateFormSubmission=No se permite el envío de formularios duplicados
|
||||||
typeMismatch.date=Fecha invalida
|
typeMismatch.date=Fecha invalida
|
||||||
typeMismatch.birthDate=Fecha invalida
|
typeMismatch.birthDate=Fecha invalida
|
||||||
|
|
||||||
|
|
8
src/main/resources/messages/messages_ko.properties
Normal file
8
src/main/resources/messages/messages_ko.properties
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
welcome=환영합니다
|
||||||
|
required=입력이 필요합니다
|
||||||
|
notFound=찾을 수 없습니다
|
||||||
|
duplicate=이미 존재합니다
|
||||||
|
nonNumeric=모두 숫자로 입력해야 합니다
|
||||||
|
duplicateFormSubmission=중복 제출은 허용되지 않습니다
|
||||||
|
typeMismatch.date=잘못된 날짜입니다
|
||||||
|
typeMismatch.birthDate=잘못된 날짜입니다
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB |
66
src/main/resources/static/resources/images/spring-logo.svg
Normal file
66
src/main/resources/static/resources/images/spring-logo.svg
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 2674.9 417">
|
||||||
|
<style>
|
||||||
|
.st0, .st1 {
|
||||||
|
fill: #6db33f;
|
||||||
|
}
|
||||||
|
.st3 {
|
||||||
|
fill: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g>
|
||||||
|
<path class="st0"
|
||||||
|
d="M366.9,29c-5.8,14.1-13.3,26.6-21.6,37.8c-36.6-37.3-87.8-61-144.3-61C90,5.8-0.7,96-0.7,207.4 c0,58.2,24.9,110.6,64.4,147.6l7.5,6.7c34.9,29.5,80.3,47.4,129.7,47.4c106,0,193.3-82.7,200.8-187.1 C407.7,171.3,392.3,106.4,366.9,29z M92.9,356.7c-5.8,7.5-16.6,8.3-24.1,2.5s-8.3-16.6-2.5-24.1s16.6-8.3,24.1-2.5 C97.5,338.4,98.7,349.2,92.9,356.7z M365.7,296.4c-49.5,66.1-155.9,43.7-223.7,47c0,0-12.1,0.8-24.1,2.5c0,0,4.6-2.1,10.4-4.2 c47.8-16.6,70.3-20,99.4-34.9c54.5-27.9,108.9-89,119.8-152.2c-20.8,60.7-84,113.1-141.4,134.3c-39.5,14.6-110.6,28.7-110.6,28.7 l-2.9-1.7c-48.2-23.7-49.9-128.5,38.3-162.2c38.7-15,75.3-6.7,117.3-16.6c44.5-10.4,96.1-43.7,116.8-87.3 C388.1,120.1,416.4,229,365.7,296.4z"></path>
|
||||||
|
<g>
|
||||||
|
<path class="st1"
|
||||||
|
d="M516.2,286.4c-5-2.5-8.3-8.3-8.3-15.4c0-10,7.9-18.3,18.3-18.3c3.7,0,7.1,1.2,9.6,2.5 c18.7,12.5,38.7,18.7,56.1,18.7c19.1,0,30.4-8.3,30.4-21.2v-0.8c0-15.4-20.8-20.4-43.7-27.4c-28.7-8.3-61.1-20-61.1-57.4v-0.8 c0-37,30.8-59.5,69.4-59.5c20.8,0,42.4,5.8,61.5,15.8c6.2,3.3,10.8,9.1,10.8,17c0,10.4-8.3,18.3-18.7,18.3c-3.7,0-5.8-0.8-8.7-2.1 c-15.8-8.3-32-13.3-45.7-13.3c-17.5,0-27.4,8.3-27.4,19.1v0.8c0,14.6,21.2,20.4,44.1,27.9c28.7,8.7,60.7,22,60.7,57v0.8 c0,41.2-32,61.5-72.3,61.5C565.7,309.7,538.6,301.8,516.2,286.4z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M680,129.7c0-12.5,9.6-22.5,22-22.5s22.5,10,22.5,22.5V143c14.6-20.4,34.9-36.6,66.5-36.6 c45.7,0,90.6,36.2,90.6,101.5v0.8c0,64.9-44.5,101.5-90.6,101.5c-32.4,0-52.8-16.2-66.5-34.5v69c0,12.5-10,22.5-22.5,22.5 c-12.1,0-22-9.6-22-22.5V129.7z M836.8,208.7v-0.8c0-37.8-25.4-62.4-55.7-62.4c-30.4,0-57,25.4-57,62.4v0.8 c0,37.4,26.6,62.4,57,62.4C811.4,271.5,836.8,247.3,836.8,208.7z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M899.1,129.7c0-12.5,9.6-22.5,22-22.5s22.5,10,22.5,22.5v10.8c2.1-16.6,29.5-33.3,49.1-33.3 c14.1,0,22,9.1,22,22c0,11.6-7.9,19.5-17.9,21.6c-32,5.4-53.6,33.3-53.6,71.9v64.4c0,12.1-10,22-22.5,22c-12.1,0-22-9.6-22-22 V129.7H899.1z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1032.6,130.1c0-12.5,9.6-22.5,22-22.5s22.5,10,22.5,22.5v157.6c0,12.5-10,22-22.5,22c-12.1,0-22-9.6-22-22 V130.1z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1100,130.1c0-12.5,9.6-22.5,22-22.5s22.5,10,22.5,22.5v9.1c12.5-18.3,30.8-32,61.1-32 c44.1,0,69.4,29.5,69.4,74.8v105.2c0,12.5-9.6,22-22,22s-22.5-9.6-22.5-22v-91.5c0-30.4-15-47.8-42-47.8 c-25.8,0-44.1,18.3-44.1,48.6v91.1c0,12.5-10,22-22.5,22c-12.1,0-22-9.6-22-22L1100,130.1L1100,130.1z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1472.1,106.8c-12.5,0-22.5,10-22.5,22.5v13.3c-14.6-20.4-34.9-36.6-66.5-36.6c-45.7,0-90.6,36.2-90.6,101.5 v0.8c0,64.9,44.5,101.5,90.6,101.5c32.4,0,52.8-16.2,66.5-34.1c-2.1,35.3-23.7,53.6-61.5,53.6c-22.5,0-42-5.4-59.9-15.4 c-2.1-1.2-5-1.7-7.9-1.7c-10.4,0-19.1,8.3-19.1,18.3c0,8.7,5,15,12.5,17.9c23.7,11.6,48.2,17.5,75.7,17.5 c35.3,0,62.8-8.3,80.3-26.2c16.2-16.2,24.9-40.7,24.9-73.6V129.7C1494.6,116.8,1484.6,106.8,1472.1,106.8z M1393.5,271 c-30.8,0-55.7-24.1-55.7-62.8v-0.8c0-37.8,25.4-62.4,55.7-62.4s57,25.4,57,62.4v0.8C1450.9,245.7,1424.3,271,1393.5,271z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1077.5,53.6c0,12.5-10,22.5-22.5,22.5s-22.5-10-22.5-22.5s10-22.5,22.5-22.5 C1067.1,30.7,1077.5,40.7,1077.5,53.6z"></path>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1545.7,153.8c-12.5,0-22.9-10.4-22.9-22.9c0-12.9,10.4-22.9,22.9-22.9c12.9,0,22.9,10.4,22.9,22.9 S1558.6,153.8,1545.7,153.8z M1545.7,111.4c-10.8,0-19.5,8.7-19.5,19.5s8.7,19.5,19.5,19.5s19.5-8.7,19.5-19.5 C1565.2,119.7,1556.5,111.4,1545.7,111.4z M1551.9,143.8l-6.7-10.4h-4.6v10.4h-3.7v-26.2h10.8c4.6,0,8.7,3.3,8.7,7.9 c0,5.8-5.4,7.9-6.7,7.9l7.1,10.4H1551.9L1551.9,143.8z M1547.4,120.9h-6.7v9.1h7.1c2.1,0,4.6-1.7,4.6-4.6 C1552.4,122.6,1549.9,120.9,1547.4,120.9z"></path>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1652.3,260.1c0,20-12.8,34.1-30,34.1c-10.4,0-18.8-5.2-23.7-13.7v12.2h-9.4v-88h9.4v35.1 c4.9-8.6,13.2-13.7,23.7-13.7C1639.4,226.1,1652.3,240.2,1652.3,260.1z M1642.3,260.1c0-15-9.1-25.6-21.8-25.6 c-12.8,0-21.9,10.6-21.9,25.6s9.1,25.7,21.9,25.7C1633.3,285.8,1642.3,275.1,1642.3,260.1z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1668,313.3l2.3-8.1c2.3,1.1,4.9,1.6,7.7,1.6c4.2,0,6.9-1.4,9.4-5.8l3.8-8.1l-28.3-65.3h10.4l22.8,54.1 l21.5-54.1h10.2l-29.7,72.4c-4.5,11.1-10.8,15.2-19.8,15.4C1674.6,315.4,1671,314.6,1668,313.3z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1861.3,206.2l-38.1,86.5h-10.7l-38.1-86.5h10.7l32.9,74.4l32.7-74.4L1861.3,206.2L1861.3,206.2z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1877.1,206.2h9.8l32.1,60.3l32.1-60.3h9.8v86.5h-9.8v-65.3l-32.1,60.3l-32.1-60.3v65.3h-9.8V206.2z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M1977.2,227.6h10.1l16.2,52.5l17.8-52.5h8.2l17.8,52.5l16.2-52.5h10.1l-21.9,65.1h-8.9l-17.2-52l-17.5,52 h-8.9L1977.2,227.6z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2140.1,253.1v39.7h-9.4v-10.2c-4.7,7.7-14.4,11.7-22.9,11.7c-13.7,0-23.8-7.9-23.8-20.8 c0-13,11.6-21.7,25.6-21.7c7,0,14.5,1.5,21.2,3.7v-2.4c0-8.8-3.5-18.9-17.6-18.9c-6.5,0-13.1,2.9-19,5.9l-3.8-7.7 c9.3-4.7,17.1-6.3,23.4-6.3C2131.4,226.1,2140.1,237.3,2140.1,253.1z M2130.7,272.3v-9.9c-5.9-1.6-12.6-2.6-19.6-2.6 c-9.7,0-17.9,5.5-17.9,13.3c0,8.1,7,12.8,16.2,12.8C2118,285.9,2128.2,281.5,2130.7,272.3z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2194.9,226.1v8.4c-14.7,0-25.2,9.1-25.2,21.8v36.4h-9.4v-65.1h9.4v12.7 C2173.6,231.7,2182.9,226.1,2194.9,226.1z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2257.8,278l5.8,6.2c-5.7,6.2-17.1,10.1-26.2,10.1c-17.4,0-33-14.2-33-34.2c0-19.4,14.6-33.9,32.1-33.9 c19.6,0,30.8,14.9,30.8,37.6H2214c1.4,12.7,10.3,22,23.2,22C2245,285.8,2253.8,282.4,2257.8,278z M2214.3,255.3h43.8 c-1.3-11.7-8.2-20.8-21.2-20.8C2225.4,234.6,2216.1,242.7,2214.3,255.3z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2344.6,215.6h-29.1v-9.3h68v9.3h-29.1v77.2h-9.8L2344.6,215.6L2344.6,215.6z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2451.6,253.1v39.7h-9.4v-10.2c-4.7,7.7-14.4,11.7-22.9,11.7c-13.7,0-23.8-7.9-23.8-20.8 c0-13,11.6-21.7,25.6-21.7c7,0,14.5,1.5,21.2,3.7v-2.4c0-8.8-3.5-18.9-17.6-18.9c-6.5,0-13.1,2.9-19,5.9l-3.8-7.7 c9.3-4.7,17.1-6.3,23.4-6.3C2442.9,226.1,2451.6,237.3,2451.6,253.1z M2442.2,272.3v-9.9c-5.9-1.6-12.6-2.6-19.6-2.6 c-9.7,0-17.9,5.5-17.9,13.3c0,8.1,7,12.8,16.2,12.8C2429.4,285.9,2439.6,281.5,2442.2,272.3z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2526.3,251.3v41.4h-9.4v-40.2c0-10.6-6.7-18-16.2-18c-11,0-20.1,7.7-20.1,16.7v41.4h-9.4v-65.1h9.4v10.4 c3.8-6.9,12.2-12,21.4-12C2516.2,226.1,2526.3,236.6,2526.3,251.3z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2542.6,285.3l38.4-48.7h-37.6v-8.9h50.4v7.4l-38.5,48.7h38.8v8.9h-51.4L2542.6,285.3L2542.6,285.3z"></path>
|
||||||
|
<path class="st1"
|
||||||
|
d="M2665.4,227.6v65.1h-9.4v-10.4c-3.8,6.9-12.2,12-21.4,12c-14.4,0-24.4-10.4-24.4-25.2v-41.4h9.4v40.2 c0,10.6,6.7,18,16.2,18c11,0,20.1-7.7,20.1-16.7v-41.4h9.5V227.6z"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<path class="st3"
|
||||||
|
d="M92.9,356.7c-5.8,7.5-16.6,8.3-24.1,2.5s-8.3-16.6-2.5-24.1s16.6-8.3,24.1-2.5 C97.5,338.4,98.7,349.2,92.9,356.7z"></path>
|
||||||
|
<path class="st3"
|
||||||
|
d="M365.7,296.4c-49.5,66.1-155.9,43.7-223.7,47c0,0-12.1,0.8-24.1,2.5c0,0,4.6-2.1,10.4-4.2 c47.8-16.6,70.3-20,99.4-34.9c54.5-27.9,108.9-89,119.8-152.2c-20.8,60.7-84,113.1-141.4,134.3c-39.5,14.6-110.6,28.7-110.6,28.7 l-2.9-1.7c-48.2-23.7-49.9-128.5,38.3-162.2c38.7-15,75.3-6.7,117.3-16.6c44.5-10.4,96.1-43.7,116.8-87.3 C388.1,120.1,416.4,229,365.7,296.4z"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB |
|
@ -80,8 +80,8 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 text-center">
|
<div class="col-12 text-center">
|
||||||
<img src="../static/resources/images/spring-pivotal-logo.png"
|
<img src="../static/images/spring-logo.svg" th:src="@{/resources/images/spring-logo.svg}" alt="VMware Tanzu Logo" class="logo">
|
||||||
th:src="@{/resources/images/spring-pivotal-logo.png}" alt="Sponsored by Pivotal" /></div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -188,6 +188,10 @@ table td.action-column {
|
||||||
color: $spring-brown;
|
color: $spring-brown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
.myspinner {
|
.myspinner {
|
||||||
animation-name: spinner;
|
animation-name: spinner;
|
||||||
animation-duration: 2s;
|
animation-duration: 2s;
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.samples.petclinic;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.DisabledInNativeImage;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
|
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.RequestEntity;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.samples.petclinic.vet.VetRepository;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.testcontainers.containers.MySQLContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||||
|
@ActiveProfiles("mysql")
|
||||||
|
@Testcontainers(disabledWithoutDocker = true)
|
||||||
|
@DisabledInNativeImage
|
||||||
|
class MySqlIntegrationTests {
|
||||||
|
|
||||||
|
@ServiceConnection
|
||||||
|
@Container
|
||||||
|
static MySQLContainer<?> container = new MySQLContainer<>("mysql:5.7");
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
int port;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VetRepository vets;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplateBuilder builder;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFindAll() throws Exception {
|
||||||
|
vets.findAll();
|
||||||
|
vets.findAll(); // served from cache
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOwnerDetails() {
|
||||||
|
RestTemplate template = builder.rootUri("http://localhost:" + port).build();
|
||||||
|
ResponseEntity<String> result = template.exchange(RequestEntity.get("/owners/1").build(), String.class);
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.samples.petclinic;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.testcontainers.containers.MySQLContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PetClinic Spring Boot Application.
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class MysqlTestApplication {
|
||||||
|
|
||||||
|
@ServiceConnection
|
||||||
|
@Profile("mysql")
|
||||||
|
@Bean
|
||||||
|
static MySQLContainer<?> container() {
|
||||||
|
return new MySQLContainer<>("mysql:5.7");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PetClinicApplication.class, "--spring.profiles.active=mysql");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
|
@ -31,7 +32,7 @@ import org.springframework.samples.petclinic.vet.VetRepository;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||||
class PetClinicIntegrationTests {
|
public class PetClinicIntegrationTests {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
int port;
|
int port;
|
||||||
|
@ -55,4 +56,8 @@ class PetClinicIntegrationTests {
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PetClinicApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.samples.petclinic;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.DisabledInNativeImage;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.boot.context.event.ApplicationPreparedEvent;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.env.EnumerablePropertySource;
|
||||||
|
import org.springframework.core.env.PropertySource;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.RequestEntity;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.samples.petclinic.vet.VetRepository;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.testcontainers.DockerClientFactory;
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "spring.docker.compose.skip.in-tests=false", //
|
||||||
|
"spring.docker.compose.profiles.active=postgres" })
|
||||||
|
@ActiveProfiles("postgres")
|
||||||
|
@DisabledInNativeImage
|
||||||
|
public class PostgresIntegrationTests {
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
int port;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VetRepository vets;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplateBuilder builder;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void available() {
|
||||||
|
assumeTrue(DockerClientFactory.instance().isDockerAvailable(), "Docker not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new SpringApplicationBuilder(PetClinicApplication.class) //
|
||||||
|
.profiles("postgres") //
|
||||||
|
.properties( //
|
||||||
|
"spring.docker.compose.profiles.active=postgres" //
|
||||||
|
) //
|
||||||
|
.listeners(new PropertiesLogger()) //
|
||||||
|
.run(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFindAll() throws Exception {
|
||||||
|
vets.findAll();
|
||||||
|
vets.findAll(); // served from cache
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOwnerDetails() {
|
||||||
|
RestTemplate template = builder.rootUri("http://localhost:" + port).build();
|
||||||
|
ResponseEntity<String> result = template.exchange(RequestEntity.get("/owners/1").build(), String.class);
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class PropertiesLogger implements ApplicationListener<ApplicationPreparedEvent> {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(PropertiesLogger.class);
|
||||||
|
|
||||||
|
private ConfigurableEnvironment environment;
|
||||||
|
|
||||||
|
private boolean isFirstRun = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationPreparedEvent event) {
|
||||||
|
if (isFirstRun) {
|
||||||
|
environment = event.getApplicationContext().getEnvironment();
|
||||||
|
printProperties();
|
||||||
|
}
|
||||||
|
isFirstRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printProperties() {
|
||||||
|
for (EnumerablePropertySource<?> source : findPropertiesPropertySources()) {
|
||||||
|
log.info("PropertySource: " + source.getName());
|
||||||
|
String[] names = source.getPropertyNames();
|
||||||
|
Arrays.sort(names);
|
||||||
|
for (String name : names) {
|
||||||
|
String resolved = environment.getProperty(name);
|
||||||
|
String value = source.getProperty(name).toString();
|
||||||
|
if (resolved.equals(value)) {
|
||||||
|
log.info(name + "=" + resolved);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.info(name + "=" + value + " OVERRIDDEN to " + resolved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<EnumerablePropertySource<?>> findPropertiesPropertySources() {
|
||||||
|
List<EnumerablePropertySource<?>> sources = new LinkedList<>();
|
||||||
|
for (PropertySource<?> source : environment.getPropertySources()) {
|
||||||
|
if (source instanceof EnumerablePropertySource enumerable) {
|
||||||
|
sources.add(enumerable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -54,7 +54,7 @@ class ValidatorTests {
|
||||||
assertThat(constraintViolations).hasSize(1);
|
assertThat(constraintViolations).hasSize(1);
|
||||||
ConstraintViolation<Person> violation = constraintViolations.iterator().next();
|
ConstraintViolation<Person> violation = constraintViolations.iterator().next();
|
||||||
assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName");
|
assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName");
|
||||||
assertThat(violation.getMessage()).isEqualTo("must not be empty");
|
assertThat(violation.getMessage()).isEqualTo("must not be blank");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.hamcrest.BaseMatcher;
|
||||||
import org.hamcrest.Description;
|
import org.hamcrest.Description;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.DisabledInNativeImage;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
@ -53,6 +54,7 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||||
* @author Colin But
|
* @author Colin But
|
||||||
*/
|
*/
|
||||||
@WebMvcTest(OwnerController.class)
|
@WebMvcTest(OwnerController.class)
|
||||||
|
@DisabledInNativeImage
|
||||||
class OwnerControllerTests {
|
class OwnerControllerTests {
|
||||||
|
|
||||||
private static final int TEST_OWNER_ID = 1;
|
private static final int TEST_OWNER_ID = 1;
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.samples.petclinic.owner;
|
||||||
import org.assertj.core.util.Lists;
|
import org.assertj.core.util.Lists;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.DisabledInNativeImage;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
@ -29,7 +30,9 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for the {@link PetController}
|
* Test class for the {@link PetController}
|
||||||
|
@ -38,6 +41,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
*/
|
*/
|
||||||
@WebMvcTest(value = PetController.class,
|
@WebMvcTest(value = PetController.class,
|
||||||
includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE))
|
includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE))
|
||||||
|
@DisabledInNativeImage
|
||||||
class PetControllerTests {
|
class PetControllerTests {
|
||||||
|
|
||||||
private static final int TEST_OWNER_ID = 1;
|
private static final int TEST_OWNER_ID = 1;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Locale;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.DisabledInNativeImage;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
@ -38,6 +39,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
* @author Colin But
|
* @author Colin But
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
@DisabledInNativeImage
|
||||||
class PetTypeFormatterTests {
|
class PetTypeFormatterTests {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
|
|
|
@ -25,6 +25,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.DisabledInNativeImage;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
@ -36,6 +37,7 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||||
* @author Colin But
|
* @author Colin But
|
||||||
*/
|
*/
|
||||||
@WebMvcTest(VisitController.class)
|
@WebMvcTest(VisitController.class)
|
||||||
|
@DisabledInNativeImage
|
||||||
class VisitControllerTests {
|
class VisitControllerTests {
|
||||||
|
|
||||||
private static final int TEST_OWNER_ID = 1;
|
private static final int TEST_OWNER_ID = 1;
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.samples.petclinic.system;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.RequestEntity;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration Test for {@link CrashController}.
|
||||||
|
*
|
||||||
|
* @author Alex Lutz
|
||||||
|
*/
|
||||||
|
// NOT Waiting https://github.com/spring-projects/spring-boot/issues/5574
|
||||||
|
@SpringBootTest(webEnvironment = RANDOM_PORT,
|
||||||
|
properties = { "server.error.include-message=ALWAYS", "management.endpoints.enabled-by-default=false" })
|
||||||
|
class CrashControllerIntegrationTests {
|
||||||
|
|
||||||
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
|
||||||
|
DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
|
||||||
|
static class TestConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value(value = "${local.server.port}")
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TestRestTemplate rest;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTriggerExceptionJson() {
|
||||||
|
ResponseEntity<Map<String, Object>> resp = rest.exchange(
|
||||||
|
RequestEntity.get("http://localhost:" + port + "/oups").build(),
|
||||||
|
new ParameterizedTypeReference<Map<String, Object>>() {
|
||||||
|
});
|
||||||
|
assertThat(resp).isNotNull();
|
||||||
|
assertThat(resp.getStatusCode().is5xxServerError());
|
||||||
|
assertThat(resp.getBody().containsKey("timestamp"));
|
||||||
|
assertThat(resp.getBody().containsKey("status"));
|
||||||
|
assertThat(resp.getBody().containsKey("error"));
|
||||||
|
assertThat(resp.getBody()).containsEntry("message",
|
||||||
|
"Expected: controller used to showcase what happens when an exception is thrown");
|
||||||
|
assertThat(resp.getBody()).containsEntry("path", "/oups");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTriggerExceptionHtml() {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setAccept(List.of(MediaType.TEXT_HTML));
|
||||||
|
ResponseEntity<String> resp = rest.exchange("http://localhost:" + port + "/oups", HttpMethod.GET,
|
||||||
|
new HttpEntity<>(headers), String.class);
|
||||||
|
assertThat(resp).isNotNull();
|
||||||
|
assertThat(resp.getStatusCode().is5xxServerError());
|
||||||
|
assertThat(resp.getBody()).isNotNull();
|
||||||
|
// html:
|
||||||
|
assertThat(resp.getBody()).containsSubsequence("<body>", "<h2>", "Something happened...", "</h2>", "<p>",
|
||||||
|
"Expected:", "controller", "used", "to", "showcase", "what", "happens", "when", "an", "exception", "is",
|
||||||
|
"thrown", "</p>", "</body>");
|
||||||
|
// Not the whitelabel error page:
|
||||||
|
assertThat(resp.getBody()).doesNotContain("Whitelabel Error Page",
|
||||||
|
"This application has no explicit mapping for");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,35 +16,31 @@
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.system;
|
package org.springframework.samples.petclinic.system;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import org.junit.jupiter.api.Test;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for {@link CrashController}
|
* Test class for {@link CrashController}
|
||||||
*
|
*
|
||||||
* @author Colin But
|
* @author Colin But
|
||||||
|
* @author Alex Lutz
|
||||||
*/
|
*/
|
||||||
// Waiting https://github.com/spring-projects/spring-boot/issues/5574
|
// Waiting https://github.com/spring-projects/spring-boot/issues/5574 ..good
|
||||||
@Disabled
|
// luck ((plain(st) UNIT test)! :)
|
||||||
@WebMvcTest(controllers = CrashController.class)
|
|
||||||
class CrashControllerTests {
|
class CrashControllerTests {
|
||||||
|
|
||||||
@Autowired
|
CrashController testee = new CrashController();
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testTriggerException() throws Exception {
|
void testTriggerException() throws Exception {
|
||||||
mockMvc.perform(get("/oups"))
|
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
|
||||||
.andExpect(view().name("exception"))
|
testee.triggerException();
|
||||||
.andExpect(model().attributeExists("exception"))
|
});
|
||||||
.andExpect(forwardedUrl("exception"))
|
|
||||||
.andExpect(status().isOk());
|
assertEquals("Expected: controller used to showcase what happens when an exception is thrown",
|
||||||
|
thrown.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.samples.petclinic.vet;
|
||||||
import org.assertj.core.util.Lists;
|
import org.assertj.core.util.Lists;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.DisabledInNativeImage;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
@ -39,6 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@WebMvcTest(VetController.class)
|
@WebMvcTest(VetController.class)
|
||||||
|
@DisabledInNativeImage
|
||||||
class VetControllerTests {
|
class VetControllerTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -31,6 +31,7 @@ class VetTests {
|
||||||
vet.setFirstName("Zaphod");
|
vet.setFirstName("Zaphod");
|
||||||
vet.setLastName("Beeblebrox");
|
vet.setLastName("Beeblebrox");
|
||||||
vet.setId(123);
|
vet.setId(123);
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet));
|
Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet));
|
||||||
assertThat(other.getFirstName()).isEqualTo(vet.getFirstName());
|
assertThat(other.getFirstName()).isEqualTo(vet.getFirstName());
|
||||||
assertThat(other.getLastName()).isEqualTo(vet.getLastName());
|
assertThat(other.getLastName()).isEqualTo(vet.getLastName());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<jmeterTestPlan version="1.2" properties="2.8" jmeter="2.13 r1665067">
|
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.5">
|
||||||
<hashTree>
|
<hashTree>
|
||||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
|
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
|
||||||
<stringProp name="TestPlan.comments"></stringProp>
|
<stringProp name="TestPlan.comments"></stringProp>
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
<hashTree/>
|
<hashTree/>
|
||||||
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="User Count" enabled="true">
|
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="User Count" enabled="true">
|
||||||
<stringProp name="CounterConfig.start">1</stringProp>
|
<stringProp name="CounterConfig.start">1</stringProp>
|
||||||
<stringProp name="CounterConfig.end">10</stringProp>
|
<stringProp name="CounterConfig.end">3</stringProp>
|
||||||
<stringProp name="CounterConfig.incr">1</stringProp>
|
<stringProp name="CounterConfig.incr">1</stringProp>
|
||||||
<stringProp name="CounterConfig.name">count</stringProp>
|
<stringProp name="CounterConfig.name">count</stringProp>
|
||||||
<stringProp name="CounterConfig.format"></stringProp>
|
<stringProp name="CounterConfig.format"></stringProp>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
<hashTree/>
|
<hashTree/>
|
||||||
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="Pet Count" enabled="true">
|
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="Pet Count" enabled="true">
|
||||||
<stringProp name="CounterConfig.start">1</stringProp>
|
<stringProp name="CounterConfig.start">1</stringProp>
|
||||||
<stringProp name="CounterConfig.end">13</stringProp>
|
<stringProp name="CounterConfig.end">3</stringProp>
|
||||||
<stringProp name="CounterConfig.incr">1</stringProp>
|
<stringProp name="CounterConfig.incr">1</stringProp>
|
||||||
<stringProp name="CounterConfig.name">petCount</stringProp>
|
<stringProp name="CounterConfig.name">petCount</stringProp>
|
||||||
<stringProp name="CounterConfig.format"></stringProp>
|
<stringProp name="CounterConfig.format"></stringProp>
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/webjars/jquery/jquery.min.js</stringProp>
|
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/webjars/bootstrap/5.2.3/dist/js/bootstrap.bundle.min.js</stringProp>
|
||||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
@ -246,13 +246,42 @@
|
||||||
</HTTPSamplerProxy>
|
</HTTPSamplerProxy>
|
||||||
<hashTree/>
|
<hashTree/>
|
||||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="POST Edit Owner" enabled="true">
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="POST Edit Owner" enabled="true">
|
||||||
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr<70>-d<>finies" enabled="true">
|
||||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
|
||||||
<collectionProp name="Arguments.arguments">
|
<collectionProp name="Arguments.arguments">
|
||||||
<elementProp name="" elementType="HTTPArgument">
|
<elementProp name="firstName" elementType="HTTPArgument">
|
||||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
<stringProp name="Argument.value">firstName=Test&lastName=${count}&address=1234+Test+St.&city=TestCity&telephone=612345678</stringProp>
|
<stringProp name="Argument.value">Test</stringProp>
|
||||||
<stringProp name="Argument.metadata">=</stringProp>
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">firstName</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="lastName" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">${count}</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">lastName</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="address" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">1234+Test+St.</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">address</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="city" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">TestCity</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">city</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="telephone" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">612345678</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">telephone</stringProp>
|
||||||
</elementProp>
|
</elementProp>
|
||||||
</collectionProp>
|
</collectionProp>
|
||||||
</elementProp>
|
</elementProp>
|
||||||
|
@ -272,7 +301,7 @@
|
||||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
</HTTPSamplerProxy>
|
</HTTPSamplerProxy>
|
||||||
<hashTree/>
|
<hashTree/>
|
||||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="New visit" enabled="true">
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="New Pet" enabled="true">
|
||||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr<70>-d<>finies" enabled="true">
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr<70>-d<>finies" enabled="true">
|
||||||
<collectionProp name="Arguments.arguments"/>
|
<collectionProp name="Arguments.arguments"/>
|
||||||
</elementProp>
|
</elementProp>
|
||||||
|
@ -282,7 +311,7 @@
|
||||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/owners/${count}/pets/${petCount}/visits/new</stringProp>
|
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/owners/${count}/pets/new</stringProp>
|
||||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
@ -292,14 +321,29 @@
|
||||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
</HTTPSamplerProxy>
|
</HTTPSamplerProxy>
|
||||||
<hashTree/>
|
<hashTree/>
|
||||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="POST new visit" enabled="true">
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="POST new pet" enabled="true">
|
||||||
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr<70>-d<>finies" enabled="true">
|
||||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
|
||||||
<collectionProp name="Arguments.arguments">
|
<collectionProp name="Arguments.arguments">
|
||||||
<elementProp name="" elementType="HTTPArgument">
|
<elementProp name="name" elementType="HTTPArgument">
|
||||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
<stringProp name="Argument.value">date=2013%2F02%2F22&description=visit</stringProp>
|
<stringProp name="Argument.value">Test+Fluffy+${petCount}</stringProp>
|
||||||
<stringProp name="Argument.metadata">=</stringProp>
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">name</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="birthDate" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">2020-12-20</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">birthDate</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="type" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">cat</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">type</stringProp>
|
||||||
</elementProp>
|
</elementProp>
|
||||||
</collectionProp>
|
</collectionProp>
|
||||||
</elementProp>
|
</elementProp>
|
||||||
|
@ -309,7 +353,7 @@
|
||||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/owners/${count}/pets/${petCount}/visits/new</stringProp>
|
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/owners/${count}/pets/new</stringProp>
|
||||||
<stringProp name="HTTPSampler.method">POST</stringProp>
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
@ -319,22 +363,54 @@
|
||||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
</HTTPSamplerProxy>
|
</HTTPSamplerProxy>
|
||||||
<hashTree/>
|
<hashTree/>
|
||||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Owner" enabled="true">
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="New visit" enabled="true">
|
||||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr<70>-d<>finies" enabled="true">
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr<70>-d<>finies" enabled="true">
|
||||||
<collectionProp name="Arguments.arguments"/>
|
<collectionProp name="Arguments.arguments"/>
|
||||||
</elementProp>
|
</elementProp>
|
||||||
<stringProp name="HTTPSampler.domain"></stringProp>
|
<stringProp name="HTTPSampler.domain"></stringProp>
|
||||||
<stringProp name="HTTPSampler.port"></stringProp>
|
<stringProp name="HTTPSampler.port"></stringProp>
|
||||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
|
||||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
|
||||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/owners/${count}</stringProp>
|
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/owners/${count}/pets/${petCount}/visits/new</stringProp>
|
||||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree/>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="POST new visit" enabled="true">
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr<70>-d<>finies" enabled="true">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="date" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">2013-02-22</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">date</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="description" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">visit</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||||
|
<stringProp name="Argument.name">description</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="HTTPSampler.domain"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">${CONTEXT_WEB}/owners/${count}/pets/${petCount}/visits/new</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||||
<boolProp name="HTTPSampler.monitor">false</boolProp>
|
<boolProp name="HTTPSampler.monitor">false</boolProp>
|
||||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
</HTTPSamplerProxy>
|
</HTTPSamplerProxy>
|
||||||
|
|
Loading…
Reference in a new issue